Embeds
This commit is contained in:
@@ -12,6 +12,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam blandit dolor nibh,
|
|||||||
|
|
||||||
$[https://krzak.org/krzak-icon.png]
|
$[https://krzak.org/krzak-icon.png]
|
||||||
$(https://krzak.org/krzak-icon.png)
|
$(https://krzak.org/krzak-icon.png)
|
||||||
|
$[https://krzak.org/krzak-icon.png|img]
|
||||||
|
|
||||||
*italic*
|
*italic*
|
||||||
**bold**
|
**bold**
|
||||||
|
|||||||
@@ -2,6 +2,13 @@ package main
|
|||||||
|
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|
||||||
|
is_url :: proc(url: string) -> bool {
|
||||||
|
if strings.contains(url, ":") || strings.contains(url, "/") || strings.contains(url, ".") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
get_ext :: proc(url: string) -> string {
|
get_ext :: proc(url: string) -> string {
|
||||||
clean := url
|
clean := url
|
||||||
if question := strings.index_byte(clean, '?'); question != -1 {
|
if question := strings.index_byte(clean, '?'); question != -1 {
|
||||||
|
|||||||
@@ -278,6 +278,39 @@ print_html :: proc(token: ^Token) {
|
|||||||
fmt.print("</a>")
|
fmt.print("</a>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case TokenType.Image:
|
||||||
|
if url, ok := token.value.(string); ok {
|
||||||
|
b := strings.builder_make(context.temp_allocator)
|
||||||
|
for child in token.children {
|
||||||
|
get_text_content(child, &b)
|
||||||
|
}
|
||||||
|
alt_text := strings.to_string(b)
|
||||||
|
fmt.printf("<img src=\"%s\" alt=\"%s\">", url, alt_text)
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.Audio:
|
||||||
|
if url, ok := token.value.(string); ok {
|
||||||
|
fmt.printf("<audio controls src=\"%s\">", url)
|
||||||
|
for child in token.children {
|
||||||
|
print_html(child)
|
||||||
|
}
|
||||||
|
fmt.print("</audio>")
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.Video:
|
||||||
|
if url, ok := token.value.(string); ok {
|
||||||
|
fmt.printf("<video controls src=\"%s\">", url)
|
||||||
|
for child in token.children {
|
||||||
|
print_html(child)
|
||||||
|
}
|
||||||
|
fmt.print("</video>")
|
||||||
|
}
|
||||||
|
|
||||||
|
case TokenType.Iframe:
|
||||||
|
if url, ok := token.value.(string); ok {
|
||||||
|
fmt.printf("<iframe src=\"%s\"></iframe>", url)
|
||||||
|
}
|
||||||
|
|
||||||
case TokenType.BreakLine:
|
case TokenType.BreakLine:
|
||||||
fmt.print("<br>\n")
|
fmt.print("<br>\n")
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,14 @@ print_token :: proc(token: ^Token, depth: int = 0) {
|
|||||||
type_str = "HeaderLink"
|
type_str = "HeaderLink"
|
||||||
case TokenType.Link:
|
case TokenType.Link:
|
||||||
type_str = "Link"
|
type_str = "Link"
|
||||||
|
case TokenType.Image:
|
||||||
|
type_str = "Image"
|
||||||
|
case TokenType.Audio:
|
||||||
|
type_str = "Audio"
|
||||||
|
case TokenType.Video:
|
||||||
|
type_str = "Video"
|
||||||
|
case TokenType.Iframe:
|
||||||
|
type_str = "Iframe"
|
||||||
}
|
}
|
||||||
|
|
||||||
value_str := ""
|
value_str := ""
|
||||||
|
|||||||
+149
@@ -34,6 +34,10 @@ TokenType :: enum {
|
|||||||
Subscript,
|
Subscript,
|
||||||
HeaderLink,
|
HeaderLink,
|
||||||
Link,
|
Link,
|
||||||
|
Image,
|
||||||
|
Audio,
|
||||||
|
Video,
|
||||||
|
Iframe,
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenValue :: union {
|
TokenValue :: union {
|
||||||
@@ -476,6 +480,150 @@ parse_links :: proc(token: ^Token) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_embed :: proc(
|
||||||
|
str: string,
|
||||||
|
) -> (
|
||||||
|
start_idx, end_idx: int,
|
||||||
|
is_embed: bool,
|
||||||
|
url: string,
|
||||||
|
alt: string,
|
||||||
|
embed_type: string,
|
||||||
|
) {
|
||||||
|
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 {
|
||||||
|
clean_url := url_text
|
||||||
|
type_hint := ""
|
||||||
|
if pipe_idx := strings.index_byte(url_text, '|'); pipe_idx != -1 {
|
||||||
|
clean_url = url_text[:pipe_idx]
|
||||||
|
type_hint = url_text[pipe_idx + 1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_url(clean_url) {
|
||||||
|
e_type := ""
|
||||||
|
if type_hint != "" {
|
||||||
|
e_type = parse_type_hint(type_hint)
|
||||||
|
}
|
||||||
|
if e_type == "" {
|
||||||
|
e_type = detect_embed_type(clean_url)
|
||||||
|
}
|
||||||
|
return i, i + 1 + end, true, clean_url, alt_text, e_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if end, inner, ok := match_single(str[i + 1:], '[', ']'); ok {
|
||||||
|
url_text := inner
|
||||||
|
type_hint := ""
|
||||||
|
if pipe_idx := strings.index_byte(inner, '|'); pipe_idx != -1 {
|
||||||
|
url_text = inner[:pipe_idx]
|
||||||
|
type_hint = inner[pipe_idx + 1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_url(url_text) {
|
||||||
|
e_type := ""
|
||||||
|
if type_hint != "" {
|
||||||
|
e_type = parse_type_hint(type_hint)
|
||||||
|
}
|
||||||
|
if e_type == "" {
|
||||||
|
e_type = detect_embed_type(url_text)
|
||||||
|
}
|
||||||
|
return i, i + 1 + end, true, url_text, url_text, e_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if str[i + 1] == '(' {
|
||||||
|
if end, url_text, alt_text, ok := match_pair(str[i + 1:], '(', ')', '[', ']'); ok {
|
||||||
|
clean_url := url_text
|
||||||
|
type_hint := ""
|
||||||
|
if pipe_idx := strings.index_byte(url_text, '|'); pipe_idx != -1 {
|
||||||
|
clean_url = url_text[:pipe_idx]
|
||||||
|
type_hint = url_text[pipe_idx + 1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_url(clean_url) {
|
||||||
|
e_type := ""
|
||||||
|
if type_hint != "" {
|
||||||
|
e_type = parse_type_hint(type_hint)
|
||||||
|
}
|
||||||
|
if e_type == "" {
|
||||||
|
e_type = detect_embed_type(clean_url)
|
||||||
|
}
|
||||||
|
return i, i + 1 + end, true, clean_url, alt_text, e_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if end, inner, ok := match_single(str[i + 1:], '(', ')'); ok {
|
||||||
|
url_text := inner
|
||||||
|
type_hint := ""
|
||||||
|
if pipe_idx := strings.index_byte(inner, '|'); pipe_idx != -1 {
|
||||||
|
url_text = inner[:pipe_idx]
|
||||||
|
type_hint = inner[pipe_idx + 1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_url(url_text) {
|
||||||
|
e_type := ""
|
||||||
|
if type_hint != "" {
|
||||||
|
e_type = parse_type_hint(type_hint)
|
||||||
|
}
|
||||||
|
if e_type == "" {
|
||||||
|
e_type = detect_embed_type(url_text)
|
||||||
|
}
|
||||||
|
return i, i + 1 + end, true, url_text, url_text, e_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1, -1, false, "", "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_embeds :: 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_embeds(token.children[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if token.type == .Text {
|
||||||
|
str, ok := token.value.(string)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
start_idx, end_idx, is_embed, url, alt, e_type := find_embed(str)
|
||||||
|
if !is_embed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
token.value = nil
|
||||||
|
|
||||||
|
if start_idx > 0 {
|
||||||
|
push_token(token, .Text, str[:start_idx])
|
||||||
|
}
|
||||||
|
|
||||||
|
embed_token_type: TokenType
|
||||||
|
if e_type == "image" {
|
||||||
|
embed_token_type = .Image
|
||||||
|
} else if e_type == "audio" {
|
||||||
|
embed_token_type = .Audio
|
||||||
|
} else if e_type == "video" {
|
||||||
|
embed_token_type = .Video
|
||||||
|
} else {
|
||||||
|
embed_token_type = .Iframe
|
||||||
|
}
|
||||||
|
|
||||||
|
embed_token := push_token(token, embed_token_type, url)
|
||||||
|
push_token(embed_token, .Text, alt)
|
||||||
|
|
||||||
|
if end_idx < len(str) {
|
||||||
|
rem := push_token(token, .Text, str[end_idx:])
|
||||||
|
parse_embeds(rem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add_breaklines :: proc(token: ^Token) {
|
add_breaklines :: proc(token: ^Token) {
|
||||||
if token.type == .CodeBlock {
|
if token.type == .CodeBlock {
|
||||||
return
|
return
|
||||||
@@ -667,6 +815,7 @@ 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)
|
||||||
|
parse_embeds(token)
|
||||||
parse_links(token)
|
parse_links(token)
|
||||||
parse_inline_footnotes(token)
|
parse_inline_footnotes(token)
|
||||||
pass_through_children(token)
|
pass_through_children(token)
|
||||||
|
|||||||
Reference in New Issue
Block a user