Strikethrough parsing
This commit is contained in:
+5
-2
@@ -3,9 +3,12 @@
|
|||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam blandit dolor nibh, vitae tempor enim pretium non. Sed in condimentum turpis. Vivamus placerat molestie ullamcorper. Maecenas nec risus nibh. Nullam vel vestibulum sapien. Integer ante erat, aliquam id tellus in, malesuada finibus nunc. Sed porttitor ante orci, eget molestie nibh posuere nec.
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam blandit dolor nibh, vitae tempor enim pretium non. Sed in condimentum turpis. Vivamus placerat molestie ullamcorper. Maecenas nec risus nibh. Nullam vel vestibulum sapien. Integer ante erat, aliquam id tellus in, malesuada finibus nunc. Sed porttitor ante orci, eget molestie nibh posuere nec.
|
||||||
|
|
||||||
^[Link on the right](http://example.com) >>
|
#[Link on the right](http://example.com) >>
|
||||||
(http://example.com)[Example.com]^ <<
|
(http://example.com)[Example.com]^ <<
|
||||||
^[Link to nekoweb.org in the middle](https://n0va.nekoweb.org) ^^
|
#[Link to nekoweb.org in the middle](https://n0va.nekoweb.org) ^^
|
||||||
|
#[https://krzak.org]
|
||||||
|
#(https://krzak.org)
|
||||||
|
^ Links with no alt text
|
||||||
|
|
||||||
#[https://krzak.org/krzak-icon.png]
|
#[https://krzak.org/krzak-icon.png]
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
input=$(cat -)
|
input=$(cat -)
|
||||||
input="${input#odin run src/}"
|
input="${input#odin run src/}"
|
||||||
style="<style>$(cat styles.css)</style>"
|
style="<style>$(cat styles.css)</style>"
|
||||||
start="<html><head><title>TypoML Preview</title>$style</head><body>"
|
doctype='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
|
||||||
|
meta='<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
|
||||||
|
start="$doctype<html><head><title>TypoML Preview</title>$meta$style</head><body>"
|
||||||
end="</body></html>"
|
end="</body></html>"
|
||||||
output="$start$input$end"
|
output="$start$input$end"
|
||||||
echo "$output" > /tmp/preview.html
|
echo "$output" > /tmp/preview.html
|
||||||
|
|||||||
+54
-26
@@ -52,63 +52,85 @@ parse_header :: proc(line: string) -> (int, string) {
|
|||||||
return lvl, line[lvl + 1:]
|
return lvl, line[lvl + 1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_through_children :: proc(token: ^Token) {
|
StyleToggle :: struct {
|
||||||
|
amount: int,
|
||||||
|
type: TokenType,
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_inline_style :: proc(token: ^Token, symbol: byte, toggles: []StyleToggle) {
|
||||||
if token.children != nil {
|
if token.children != nil {
|
||||||
for child in token.children {
|
for i := 0; i < len(token.children); i += 1 {
|
||||||
pass_through_children(child)
|
parse_inline_style(token.children[i], symbol, toggles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if token.type == TokenType.Text {
|
if token.type == .Text {
|
||||||
str, ok := token.value.(string)
|
str, ok := token.value.(string)
|
||||||
if !ok || !strings.contains(str, "*") {
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
symbol_found := false
|
||||||
|
for i := 0; i < len(str); i += 1 {
|
||||||
|
if str[i] == symbol {
|
||||||
|
symbol_found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !symbol_found {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
token.value = nil
|
token.value = nil
|
||||||
|
|
||||||
is_bold := false
|
active_styles: [256]bool
|
||||||
is_italic := false
|
|
||||||
current_node := token
|
current_node := token
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
start := 0
|
start := 0
|
||||||
|
|
||||||
for i < len(str) {
|
for i < len(str) {
|
||||||
if str[i] == '*' {
|
if str[i] == symbol {
|
||||||
if i > start {
|
if i > start {
|
||||||
push_token(current_node, TokenType.Text, str[start:i])
|
push_token(current_node, TokenType.Text, str[start:i])
|
||||||
}
|
}
|
||||||
|
|
||||||
asterisks := 0
|
count := 0
|
||||||
for i < len(str) && str[i] == '*' {
|
symbol_start := i
|
||||||
asterisks += 1
|
for i < len(str) && str[i] == symbol {
|
||||||
|
count += 1
|
||||||
i += 1
|
i += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
for asterisks >= 3 {
|
for count > 0 {
|
||||||
is_bold = !is_bold
|
matched := false
|
||||||
is_italic = !is_italic
|
for toggle in toggles {
|
||||||
asterisks -= 3
|
if count >= toggle.amount {
|
||||||
|
active_styles[int(toggle.type)] = !active_styles[int(toggle.type)]
|
||||||
|
count -= toggle.amount
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
push_token(
|
||||||
|
current_node,
|
||||||
|
TokenType.Text,
|
||||||
|
str[symbol_start:symbol_start + count],
|
||||||
|
)
|
||||||
|
count = 0
|
||||||
|
break
|
||||||
}
|
}
|
||||||
if asterisks == 2 {
|
|
||||||
is_bold = !is_bold
|
|
||||||
} else if asterisks == 1 {
|
|
||||||
is_italic = !is_italic
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_node = token
|
current_node = token
|
||||||
if is_bold {
|
for toggle in toggles {
|
||||||
|
if active_styles[int(toggle.type)] {
|
||||||
last :=
|
last :=
|
||||||
current_node.children[len(current_node.children) - 1] if len(current_node.children) > 0 else nil
|
current_node.children[len(current_node.children) - 1] if len(current_node.children) > 0 else nil
|
||||||
current_node =
|
current_node =
|
||||||
last if last != nil && last.type == .Bold else push_token(current_node, TokenType.Bold, nil)
|
last if last != nil && last.type == toggle.type else push_token(current_node, toggle.type, nil)
|
||||||
}
|
}
|
||||||
if is_italic {
|
|
||||||
last :=
|
|
||||||
current_node.children[len(current_node.children) - 1] if len(current_node.children) > 0 else nil
|
|
||||||
current_node =
|
|
||||||
last if last != nil && last.type == .Italics else push_token(current_node, TokenType.Italics, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start = i
|
start = i
|
||||||
@@ -123,6 +145,12 @@ pass_through_children :: proc(token: ^Token) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pass_through_children :: proc(token: ^Token) {
|
||||||
|
parse_inline_style(token, '*', []StyleToggle{{2, .Bold}, {1, .Italics}})
|
||||||
|
parse_inline_style(token, '~', []StyleToggle{{2, .Strikethrough}})
|
||||||
|
parse_inline_style(token, '-', []StyleToggle{{2, .Strikethrough}})
|
||||||
|
}
|
||||||
|
|
||||||
add_breaklines :: proc(token: ^Token) {
|
add_breaklines :: proc(token: ^Token) {
|
||||||
if token.children == nil {
|
if token.children == nil {
|
||||||
return
|
return
|
||||||
|
|||||||
+4
-3
@@ -3,7 +3,7 @@ body {
|
|||||||
color: #e0e0e0;
|
color: #e0e0e0;
|
||||||
background: #1a1a1a;
|
background: #1a1a1a;
|
||||||
margin: 2em auto;
|
margin: 2em auto;
|
||||||
max-width: 750px;
|
width: 750px;
|
||||||
padding: 1em 2em;
|
padding: 1em 2em;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
@@ -19,7 +19,8 @@ pre {
|
|||||||
background: #2a2a2a;
|
background: #2a2a2a;
|
||||||
border: 1px solid #444;
|
border: 1px solid #444;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
overflow: auto;
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
code {
|
code {
|
||||||
font-family: "Courier New", Courier, monospace;
|
font-family: "Courier New", Courier, monospace;
|
||||||
@@ -40,7 +41,7 @@ a:hover {
|
|||||||
color: #ff1493;
|
color: #ff1493;
|
||||||
}
|
}
|
||||||
table {
|
table {
|
||||||
border-collapse: collapse;
|
border-spacing: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user