Codeblocks

This commit is contained in:
2026-07-14 19:21:35 +02:00
parent 91671995d3
commit 5c35ce4408
4 changed files with 107 additions and 0 deletions
+6
View File
@@ -41,5 +41,11 @@ Text under a blockquote [#named]
| table | row | with | | table | row | with |
| some | ***content*** | in | | some | ***content*** | in |
```odin
main :: proc() {
fmt.println("Hello, World!")
}
```
[&1] Ordered list item 2 not included [&1] Ordered list item 2 not included
[&named] This is the definition for a named footnote [&named] This is the definition for a named footnote
+23
View File
@@ -187,6 +187,29 @@ print_html :: proc(token: ^Token) {
fmt.print("</div>\n") fmt.print("</div>\n")
} }
case TokenType.CodeBlock:
lang := ""
if v, ok := token.value.(string); ok && v != "" {
lang = v
}
if lang != "" {
fmt.printf("<pre><code class=\"lang-%s\">", lang)
} else {
fmt.print("<pre><code>")
}
for i := 0; i < len(token.children); i += 1 {
print_html(token.children[i])
if i + 1 < len(token.children) {
fmt.print("\n")
}
}
fmt.print("\n</code></pre>\n")
case TokenType.InlineCode:
if code, ok := token.value.(string); ok {
fmt.printf("<code>%s</code>", code)
}
case TokenType.BreakLine: case TokenType.BreakLine:
fmt.print("<br>\n") fmt.print("<br>\n")
+4
View File
@@ -59,6 +59,10 @@ print_token :: proc(token: ^Token, depth: int = 0) {
type_str = "FootnoteDef" type_str = "FootnoteDef"
case TokenType.FootnoteRef: case TokenType.FootnoteRef:
type_str = "FootnoteRef" type_str = "FootnoteRef"
case TokenType.CodeBlock:
type_str = "CodeBlock"
case TokenType.InlineCode:
type_str = "InlineCode"
} }
value_str := "" value_str := ""
+74
View File
@@ -26,6 +26,8 @@ TokenType :: enum {
Middle, Middle,
FootnoteDef, FootnoteDef,
FootnoteRef, FootnoteRef,
CodeBlock,
InlineCode,
} }
TokenValue :: union { TokenValue :: union {
@@ -249,12 +251,61 @@ parse_inline_style :: proc(token: ^Token, symbol: byte, toggles: []StyleToggle)
} }
pass_through_children :: proc(token: ^Token) { pass_through_children :: proc(token: ^Token) {
if token.type == .CodeBlock || token.type == .InlineCode {
return
}
parse_inline_style(token, '*', []StyleToggle{{2, .Bold}, {1, .Italics}}) parse_inline_style(token, '*', []StyleToggle{{2, .Bold}, {1, .Italics}})
parse_inline_style(token, '~', []StyleToggle{{2, .Strikethrough}}) parse_inline_style(token, '~', []StyleToggle{{2, .Strikethrough}})
parse_inline_style(token, '-', []StyleToggle{{2, .Strikethrough}}) parse_inline_style(token, '-', []StyleToggle{{2, .Strikethrough}})
} }
parse_inline_code :: proc(token: ^Token) {
if token.type == .CodeBlock || token.type == .InlineCode {
return
}
if token.children != nil {
for i := 0; i < len(token.children); i += 1 {
parse_inline_code(token.children[i])
}
}
if token.type == .Text {
str, ok := token.value.(string)
if !ok {
return
}
start_idx := strings.index_byte(str, '`')
if start_idx == -1 {
return
}
end_idx := strings.index_byte(str[start_idx + 1:], '`')
if end_idx == -1 {
return
}
end_idx += start_idx + 1
code := str[start_idx + 1:end_idx]
token.value = nil
if start_idx > 0 {
push_token(token, .Text, str[:start_idx])
}
push_token(token, .InlineCode, code)
if end_idx + 1 < len(str) {
rem := push_token(token, .Text, str[end_idx + 1:])
parse_inline_code(rem)
}
}
}
parse_inline_footnotes :: proc(token: ^Token) { parse_inline_footnotes :: proc(token: ^Token) {
if token.type == .CodeBlock || token.type == .InlineCode {
return
}
if token.children != nil { if token.children != nil {
for i := 0; i < len(token.children); i += 1 { for i := 0; i < len(token.children); i += 1 {
parse_inline_footnotes(token.children[i]) parse_inline_footnotes(token.children[i])
@@ -295,6 +346,9 @@ parse_inline_footnotes :: proc(token: ^Token) {
} }
add_breaklines :: proc(token: ^Token) { add_breaklines :: proc(token: ^Token) {
if token.type == .CodeBlock {
return
}
if token.children == nil { if token.children == nil {
return return
} }
@@ -331,9 +385,28 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
// FIRST PASS // FIRST PASS
in_code_block := false
for untrimmed_line, line_index in lines { for untrimmed_line, line_index in lines {
line := strings.trim_space(untrimmed_line) line := strings.trim_space(untrimmed_line)
if in_code_block {
if strings.has_prefix(line, "```") {
in_code_block = false
current_token = &root
} else {
push_token(current_token, TokenType.Text, untrimmed_line)
}
continue
}
if strings.has_prefix(line, "```") {
lang := strings.trim_space(line[3:])
current_token = push_token(&root, TokenType.CodeBlock, lang)
in_code_block = true
continue
}
if len(line) == 0 { if len(line) == 0 {
current_token = &root current_token = &root
continue continue
@@ -441,6 +514,7 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
// THIRD PASS // THIRD PASS
for token in root.children { for token in root.children {
parse_inline_code(token)
pass_through_children(token) pass_through_children(token)
parse_inline_footnotes(token) parse_inline_footnotes(token)
} }