Strikethrough parsing

This commit is contained in:
2026-07-14 18:06:42 +02:00
parent 7737c2d763
commit 5d232786bf
4 changed files with 71 additions and 37 deletions
+5 -2
View File
@@ -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.
^[Link on the right](http://example.com) >>
#[Link on the right](http://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]
+3 -1
View File
@@ -2,7 +2,9 @@
input=$(cat -)
input="${input#odin run src/}"
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>"
output="$start$input$end"
echo "$output" > /tmp/preview.html
+59 -31
View File
@@ -52,63 +52,85 @@ parse_header :: proc(line: string) -> (int, string) {
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 {
for child in token.children {
pass_through_children(child)
for i := 0; i < len(token.children); i += 1 {
parse_inline_style(token.children[i], symbol, toggles)
}
}
if token.type == TokenType.Text {
if token.type == .Text {
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
}
token.value = nil
is_bold := false
is_italic := false
active_styles: [256]bool
current_node := token
i := 0
start := 0
for i < len(str) {
if str[i] == '*' {
if str[i] == symbol {
if i > start {
push_token(current_node, TokenType.Text, str[start:i])
}
asterisks := 0
for i < len(str) && str[i] == '*' {
asterisks += 1
count := 0
symbol_start := i
for i < len(str) && str[i] == symbol {
count += 1
i += 1
}
for asterisks >= 3 {
is_bold = !is_bold
is_italic = !is_italic
asterisks -= 3
}
if asterisks == 2 {
is_bold = !is_bold
} else if asterisks == 1 {
is_italic = !is_italic
for count > 0 {
matched := false
for toggle in toggles {
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
}
}
current_node = token
if is_bold {
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 == .Bold else push_token(current_node, TokenType.Bold, 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)
for toggle in toggles {
if active_styles[int(toggle.type)] {
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 == toggle.type else push_token(current_node, toggle.type, nil)
}
}
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) {
if token.children == nil {
return
+4 -3
View File
@@ -3,7 +3,7 @@ body {
color: #e0e0e0;
background: #1a1a1a;
margin: 2em auto;
max-width: 750px;
width: 750px;
padding: 1em 2em;
line-height: 1.8;
font-size: 18px;
@@ -19,7 +19,8 @@ pre {
background: #2a2a2a;
border: 1px solid #444;
padding: 1em;
overflow: auto;
white-space: pre-wrap;
word-wrap: break-word;
}
code {
font-family: "Courier New", Courier, monospace;
@@ -40,7 +41,7 @@ a:hover {
color: #ff1493;
}
table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
margin-bottom: 1em;
}