Codeblocks
This commit is contained in:
@@ -41,5 +41,11 @@ Text under a blockquote [#named]
|
||||
| table | row | with |
|
||||
| some | ***content*** | in |
|
||||
|
||||
```odin
|
||||
main :: proc() {
|
||||
fmt.println("Hello, World!")
|
||||
}
|
||||
```
|
||||
|
||||
[&1] Ordered list item 2 not included
|
||||
[&named] This is the definition for a named footnote
|
||||
|
||||
@@ -187,6 +187,29 @@ print_html :: proc(token: ^Token) {
|
||||
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:
|
||||
fmt.print("<br>\n")
|
||||
|
||||
|
||||
@@ -59,6 +59,10 @@ print_token :: proc(token: ^Token, depth: int = 0) {
|
||||
type_str = "FootnoteDef"
|
||||
case TokenType.FootnoteRef:
|
||||
type_str = "FootnoteRef"
|
||||
case TokenType.CodeBlock:
|
||||
type_str = "CodeBlock"
|
||||
case TokenType.InlineCode:
|
||||
type_str = "InlineCode"
|
||||
}
|
||||
|
||||
value_str := ""
|
||||
|
||||
@@ -26,6 +26,8 @@ TokenType :: enum {
|
||||
Middle,
|
||||
FootnoteDef,
|
||||
FootnoteRef,
|
||||
CodeBlock,
|
||||
InlineCode,
|
||||
}
|
||||
|
||||
TokenValue :: union {
|
||||
@@ -249,12 +251,61 @@ parse_inline_style :: proc(token: ^Token, symbol: byte, toggles: []StyleToggle)
|
||||
}
|
||||
|
||||
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, .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) {
|
||||
if token.type == .CodeBlock || token.type == .InlineCode {
|
||||
return
|
||||
}
|
||||
if token.children != nil {
|
||||
for i := 0; i < len(token.children); i += 1 {
|
||||
parse_inline_footnotes(token.children[i])
|
||||
@@ -295,6 +346,9 @@ parse_inline_footnotes :: proc(token: ^Token) {
|
||||
}
|
||||
|
||||
add_breaklines :: proc(token: ^Token) {
|
||||
if token.type == .CodeBlock {
|
||||
return
|
||||
}
|
||||
if token.children == nil {
|
||||
return
|
||||
}
|
||||
@@ -331,9 +385,28 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
|
||||
|
||||
// FIRST PASS
|
||||
|
||||
in_code_block := false
|
||||
|
||||
for untrimmed_line, line_index in lines {
|
||||
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 {
|
||||
current_token = &root
|
||||
continue
|
||||
@@ -441,6 +514,7 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
|
||||
// THIRD PASS
|
||||
|
||||
for token in root.children {
|
||||
parse_inline_code(token)
|
||||
pass_through_children(token)
|
||||
parse_inline_footnotes(token)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user