Footnotes
This commit is contained in:
+5
-2
@@ -26,12 +26,12 @@ The **VARIABLE** is $(variable)
|
|||||||
- List item 1
|
- List item 1
|
||||||
. List item 2
|
. List item 2
|
||||||
|
|
||||||
1. Ordered list item
|
1. Ordered list item [#1]
|
||||||
|
|
||||||
> This is a sample blockquote
|
> This is a sample blockquote
|
||||||
> Bon apetit!
|
> Bon apetit!
|
||||||
|
|
||||||
Text under a blockquote
|
Text under a blockquote [#named]
|
||||||
|
|
||||||
**This *is* bold *and* italics *mixed** TOGETHER*
|
**This *is* bold *and* italics *mixed** TOGETHER*
|
||||||
|
|
||||||
@@ -40,3 +40,6 @@ Text under a blockquote
|
|||||||
| This << | is >> | a ^^ |
|
| This << | is >> | a ^^ |
|
||||||
| table | row | with |
|
| table | row | with |
|
||||||
| some | ***content*** | in |
|
| some | ***content*** | in |
|
||||||
|
|
||||||
|
[&1] Ordered list item 2 not included
|
||||||
|
[&named] This is the definition for a named footnote
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ import "core:fmt"
|
|||||||
print_html :: proc(token: ^Token) {
|
print_html :: proc(token: ^Token) {
|
||||||
switch token.type {
|
switch token.type {
|
||||||
case TokenType.Root:
|
case TokenType.Root:
|
||||||
|
has_footnotes := false
|
||||||
for child in token.children {
|
for child in token.children {
|
||||||
|
if child.type == .FootnoteDef && !has_footnotes {
|
||||||
|
fmt.print("<hr class=\"footnotes-sep\">\n")
|
||||||
|
has_footnotes = true
|
||||||
|
}
|
||||||
print_html(child)
|
print_html(child)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +173,20 @@ print_html :: proc(token: ^Token) {
|
|||||||
}
|
}
|
||||||
fmt.print("</div>")
|
fmt.print("</div>")
|
||||||
|
|
||||||
|
case TokenType.FootnoteRef:
|
||||||
|
if id, ok := token.value.(string); ok {
|
||||||
|
fmt.printf("<a href=\"#fn-%s\" id=\"ref-%s\"><sup>%s</sup></a>", id, id, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.FootnoteDef:
|
||||||
|
if id, ok := token.value.(string); ok {
|
||||||
|
fmt.printf("<div class=\"footnote\" id=\"fn-%s\"><a href=\"#ref-%s\">^</a> ", id, id)
|
||||||
|
for child in token.children {
|
||||||
|
print_html(child)
|
||||||
|
}
|
||||||
|
fmt.print("</div>\n")
|
||||||
|
}
|
||||||
|
|
||||||
case TokenType.BreakLine:
|
case TokenType.BreakLine:
|
||||||
fmt.print("<br>\n")
|
fmt.print("<br>\n")
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ print_token :: proc(token: ^Token, depth: int = 0) {
|
|||||||
type_str = "Right"
|
type_str = "Right"
|
||||||
case TokenType.Middle:
|
case TokenType.Middle:
|
||||||
type_str = "Middle"
|
type_str = "Middle"
|
||||||
|
case TokenType.FootnoteDef:
|
||||||
|
type_str = "FootnoteDef"
|
||||||
|
case TokenType.FootnoteRef:
|
||||||
|
type_str = "FootnoteRef"
|
||||||
}
|
}
|
||||||
|
|
||||||
value_str := ""
|
value_str := ""
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ TokenType :: enum {
|
|||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
Middle,
|
Middle,
|
||||||
|
FootnoteDef,
|
||||||
|
FootnoteRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenValue :: union {
|
TokenValue :: union {
|
||||||
@@ -141,6 +143,18 @@ parse_header :: proc(line: string) -> (int, string) {
|
|||||||
return lvl, line[lvl + 1:]
|
return lvl, line[lvl + 1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parse_footnote_def :: proc(line: string) -> (string, string, bool) {
|
||||||
|
if strings.has_prefix(line, "[&") {
|
||||||
|
idx := strings.index_byte(line, ']')
|
||||||
|
if idx != -1 {
|
||||||
|
id := line[2:idx]
|
||||||
|
text := strings.trim_space(line[idx + 1:])
|
||||||
|
return id, text, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
StyleToggle :: struct {
|
StyleToggle :: struct {
|
||||||
amount: int,
|
amount: int,
|
||||||
type: TokenType,
|
type: TokenType,
|
||||||
@@ -240,6 +254,46 @@ pass_through_children :: proc(token: ^Token) {
|
|||||||
parse_inline_style(token, '-', []StyleToggle{{2, .Strikethrough}})
|
parse_inline_style(token, '-', []StyleToggle{{2, .Strikethrough}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parse_inline_footnotes :: proc(token: ^Token) {
|
||||||
|
if token.children != nil {
|
||||||
|
for i := 0; i < len(token.children); i += 1 {
|
||||||
|
parse_inline_footnotes(token.children[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if token.type == .Text {
|
||||||
|
str, ok := token.value.(string)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
start_idx := strings.index(str, "[#")
|
||||||
|
if start_idx == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
end_idx := strings.index_byte(str[start_idx:], ']')
|
||||||
|
if end_idx == -1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
end_idx += start_idx
|
||||||
|
|
||||||
|
id := str[start_idx + 2:end_idx]
|
||||||
|
|
||||||
|
token.value = nil
|
||||||
|
|
||||||
|
if start_idx > 0 {
|
||||||
|
push_token(token, .Text, str[:start_idx])
|
||||||
|
}
|
||||||
|
push_token(token, .FootnoteRef, id)
|
||||||
|
|
||||||
|
if end_idx + 1 < len(str) {
|
||||||
|
rem := push_token(token, .Text, str[end_idx + 1:])
|
||||||
|
parse_inline_footnotes(rem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add_breaklines :: proc(token: ^Token) {
|
add_breaklines :: proc(token: ^Token) {
|
||||||
if token.children == nil {
|
if token.children == nil {
|
||||||
return
|
return
|
||||||
@@ -293,6 +347,13 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if id, ftext, ok := parse_footnote_def(line); ok {
|
||||||
|
current_token = push_token(&root, TokenType.FootnoteDef, id)
|
||||||
|
push_text(current_token, ftext)
|
||||||
|
current_token = &root
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if strings.has_prefix(text, "> ") {
|
if strings.has_prefix(text, "> ") {
|
||||||
if current_token.type != TokenType.Blockquote {
|
if current_token.type != TokenType.Blockquote {
|
||||||
current_token = push_token(&root, TokenType.Blockquote, nil)
|
current_token = push_token(&root, TokenType.Blockquote, nil)
|
||||||
@@ -381,7 +442,24 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
|
|||||||
|
|
||||||
for token in root.children {
|
for token in root.children {
|
||||||
pass_through_children(token)
|
pass_through_children(token)
|
||||||
|
parse_inline_footnotes(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FOURTH PASS
|
||||||
|
|
||||||
|
footnotes: [dynamic]^Token
|
||||||
|
new_root_children: [dynamic]^Token
|
||||||
|
for child in root.children {
|
||||||
|
if child.type == .FootnoteDef {
|
||||||
|
append(&footnotes, child)
|
||||||
|
} else {
|
||||||
|
append(&new_root_children, child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for child in footnotes {
|
||||||
|
append(&new_root_children, child)
|
||||||
|
}
|
||||||
|
root.children = new_root_children
|
||||||
|
|
||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -59,3 +59,16 @@ tr.table-sep td {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
hr.footnotes-sep {
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid #444;
|
||||||
|
margin: 2em 0 1em 0;
|
||||||
|
}
|
||||||
|
.footnote {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #a0a0a0;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.footnote a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user