This has to be the worst-looking code yet
This commit is contained in:
+4
-2
@@ -4,13 +4,13 @@
|
|||||||
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]
|
||||||
#(https://krzak.org)
|
#(https://krzak.org)
|
||||||
^ Links with no alt text
|
^ Links with no alt text
|
||||||
|
|
||||||
#[https://krzak.org/krzak-icon.png]
|
#[https://krzak.org/krzak-icon.png|]
|
||||||
|
|
||||||
*italic*
|
*italic*
|
||||||
**bold**
|
**bold**
|
||||||
@@ -52,5 +52,7 @@ main :: proc() {
|
|||||||
H_2_O_4_U is uranium peroxide
|
H_2_O_4_U is uranium peroxide
|
||||||
Here is some __underlined__ text
|
Here is some __underlined__ text
|
||||||
|
|
||||||
|
[Go to Top](#Heading)
|
||||||
|
|
||||||
[&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
|
||||||
|
|||||||
+45
-1
@@ -1,6 +1,24 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
import "core:strings"
|
||||||
|
|
||||||
|
get_text_content :: proc(token: ^Token, b: ^strings.Builder) {
|
||||||
|
if token.type == .Text {
|
||||||
|
if v, ok := token.value.(string); ok {
|
||||||
|
strings.write_string(b, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for child in token.children {
|
||||||
|
get_text_content(child, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slugifyifyifyify :: proc(text: string) -> string {
|
||||||
|
lower := strings.to_lower(text, context.temp_allocator)
|
||||||
|
res, _ := strings.replace_all(lower, " ", "-", context.temp_allocator)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
print_html :: proc(token: ^Token) {
|
print_html :: proc(token: ^Token) {
|
||||||
switch token.type {
|
switch token.type {
|
||||||
@@ -19,7 +37,14 @@ print_html :: proc(token: ^Token) {
|
|||||||
if v, ok := token.value.(int); ok {
|
if v, ok := token.value.(int); ok {
|
||||||
level = v
|
level = v
|
||||||
}
|
}
|
||||||
fmt.printf("<h%d>", level)
|
|
||||||
|
b := strings.builder_make(context.temp_allocator)
|
||||||
|
for child in token.children {
|
||||||
|
get_text_content(child, &b)
|
||||||
|
}
|
||||||
|
slug := slugifyifyifyify(strings.to_string(b))
|
||||||
|
|
||||||
|
fmt.printf("<h%d id=\"%s\">", level, slug)
|
||||||
for child in token.children {
|
for child in token.children {
|
||||||
print_html(child)
|
print_html(child)
|
||||||
}
|
}
|
||||||
@@ -234,6 +259,25 @@ print_html :: proc(token: ^Token) {
|
|||||||
}
|
}
|
||||||
fmt.print("</sub>")
|
fmt.print("</sub>")
|
||||||
|
|
||||||
|
case TokenType.HeaderLink:
|
||||||
|
if target, ok := token.value.(string); ok {
|
||||||
|
slug := slugifyifyifyify(target)
|
||||||
|
fmt.printf("<a href=\"#%s\">", slug)
|
||||||
|
for child in token.children {
|
||||||
|
print_html(child)
|
||||||
|
}
|
||||||
|
fmt.print("</a>")
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.Link:
|
||||||
|
if url, ok := token.value.(string); ok {
|
||||||
|
fmt.printf("<a href=\"%s\">", url)
|
||||||
|
for child in token.children {
|
||||||
|
print_html(child)
|
||||||
|
}
|
||||||
|
fmt.print("</a>")
|
||||||
|
}
|
||||||
|
|
||||||
case TokenType.BreakLine:
|
case TokenType.BreakLine:
|
||||||
fmt.print("<br>\n")
|
fmt.print("<br>\n")
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ print_token :: proc(token: ^Token, depth: int = 0) {
|
|||||||
type_str = "Superscript"
|
type_str = "Superscript"
|
||||||
case TokenType.Subscript:
|
case TokenType.Subscript:
|
||||||
type_str = "Subscript"
|
type_str = "Subscript"
|
||||||
|
case TokenType.HeaderLink:
|
||||||
|
type_str = "HeaderLink"
|
||||||
|
case TokenType.Link:
|
||||||
|
type_str = "Link"
|
||||||
}
|
}
|
||||||
|
|
||||||
value_str := ""
|
value_str := ""
|
||||||
|
|||||||
+127
-1
@@ -32,6 +32,8 @@ TokenType :: enum {
|
|||||||
Underline,
|
Underline,
|
||||||
Superscript,
|
Superscript,
|
||||||
Subscript,
|
Subscript,
|
||||||
|
HeaderLink,
|
||||||
|
Link,
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenValue :: union {
|
TokenValue :: union {
|
||||||
@@ -351,6 +353,129 @@ parse_inline_footnotes :: proc(token: ^Token) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match_pair :: proc(s: string, open1, close1, open2, close2: byte) -> (int, string, string, bool) {
|
||||||
|
if len(s) == 0 || s[0] != open1 {
|
||||||
|
return 0, "", "", false
|
||||||
|
}
|
||||||
|
close1_idx := strings.index_byte(s, close1)
|
||||||
|
if close1_idx == -1 {
|
||||||
|
return 0, "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
if close1_idx + 1 < len(s) && s[close1_idx + 1] == open2 {
|
||||||
|
close2_idx := strings.index_byte(s[close1_idx + 2:], close2)
|
||||||
|
if close2_idx != -1 {
|
||||||
|
close2_idx += close1_idx + 2
|
||||||
|
return close2_idx + 1, s[1:close1_idx], s[close1_idx + 2:close2_idx], true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
match_single :: proc(s: string, open, close: byte) -> (int, string, bool) {
|
||||||
|
if len(s) == 0 || s[0] != open {
|
||||||
|
return 0, "", false
|
||||||
|
}
|
||||||
|
close_idx := strings.index_byte(s, close)
|
||||||
|
if close_idx == -1 {
|
||||||
|
return 0, "", false
|
||||||
|
}
|
||||||
|
return close_idx + 1, s[1:close_idx], true
|
||||||
|
}
|
||||||
|
|
||||||
|
find_link :: proc(
|
||||||
|
str: string,
|
||||||
|
) -> (
|
||||||
|
start_idx, end_idx: int,
|
||||||
|
is_link: bool,
|
||||||
|
url: string,
|
||||||
|
alt: string,
|
||||||
|
is_header: bool,
|
||||||
|
) {
|
||||||
|
for i := 0; i < len(str); i += 1 {
|
||||||
|
if str[i] == '#' && i + 1 < len(str) {
|
||||||
|
if str[i + 1] == '[' {
|
||||||
|
if end, alt_text, url_text, ok := match_pair(str[i + 1:], '[', ']', '(', ')'); ok {
|
||||||
|
return i, i + 1 + end, true, url_text, alt_text, false
|
||||||
|
}
|
||||||
|
if end, inner, ok := match_single(str[i + 1:], '[', ']'); ok {
|
||||||
|
return i, i + 1 + end, true, inner, inner, false
|
||||||
|
}
|
||||||
|
} else if str[i + 1] == '(' {
|
||||||
|
if end, url_text, alt_text, ok := match_pair(str[i + 1:], '(', ')', '[', ']'); ok {
|
||||||
|
return i, i + 1 + end, true, url_text, alt_text, false
|
||||||
|
}
|
||||||
|
if end, inner, ok := match_single(str[i + 1:], '(', ')'); ok {
|
||||||
|
return i, i + 1 + end, true, inner, inner, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if str[i] == '[' {
|
||||||
|
if end, alt_text, url_text, ok := match_pair(str[i:], '[', ']', '(', ')'); ok {
|
||||||
|
if strings.has_prefix(url_text, "#") {
|
||||||
|
return i, i + end, true, url_text[1:], alt_text, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if end, inner, ok := match_single(str[i:], '[', ']'); ok {
|
||||||
|
if strings.has_prefix(inner, "#") {
|
||||||
|
return i, i + end, true, inner[1:], inner[1:], true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if str[i] == '(' {
|
||||||
|
if end, url_text, alt_text, ok := match_pair(str[i:], '(', ')', '[', ']'); ok {
|
||||||
|
if strings.has_prefix(url_text, "#") {
|
||||||
|
return i, i + end, true, url_text[1:], alt_text, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if end, inner, ok := match_single(str[i:], '(', ')'); ok {
|
||||||
|
if strings.has_prefix(inner, "#") {
|
||||||
|
return i, i + end, true, inner[1:], inner[1:], true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1, -1, false, "", "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_links :: 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_links(token.children[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if token.type == .Text {
|
||||||
|
str, ok := token.value.(string)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
start_idx, end_idx, is_link, url, alt, is_header := find_link(str)
|
||||||
|
if !is_link {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
token.value = nil
|
||||||
|
|
||||||
|
if start_idx > 0 {
|
||||||
|
push_token(token, .Text, str[:start_idx])
|
||||||
|
}
|
||||||
|
|
||||||
|
link_token := push_token(token, .HeaderLink if is_header else .Link, url)
|
||||||
|
push_token(link_token, .Text, alt)
|
||||||
|
|
||||||
|
if end_idx < len(str) {
|
||||||
|
rem := push_token(token, .Text, str[end_idx:])
|
||||||
|
parse_links(rem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add_breaklines :: proc(token: ^Token) {
|
add_breaklines :: proc(token: ^Token) {
|
||||||
if token.type == .CodeBlock {
|
if token.type == .CodeBlock {
|
||||||
return
|
return
|
||||||
@@ -542,8 +667,9 @@ parse :: proc(lines: []string, allocator := context.allocator) -> Token {
|
|||||||
|
|
||||||
for token in root.children {
|
for token in root.children {
|
||||||
parse_inline_code(token)
|
parse_inline_code(token)
|
||||||
pass_through_children(token)
|
parse_links(token)
|
||||||
parse_inline_footnotes(token)
|
parse_inline_footnotes(token)
|
||||||
|
pass_through_children(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FOURTH PASS
|
// FOURTH PASS
|
||||||
|
|||||||
Reference in New Issue
Block a user