Merge branch 'odin-rewrite'
This commit was merged in pull request #1.
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.v]
|
|
||||||
indent_style = tab
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
* text=auto eol=lf
|
|
||||||
*.bat eol=crlf
|
|
||||||
|
|
||||||
*.v linguist-language=V
|
|
||||||
*.vv linguist-language=V
|
|
||||||
*.vsh linguist-language=V
|
|
||||||
v.mod linguist-language=V
|
|
||||||
.vdocignore linguist-language=ignore
|
|
||||||
+1
-26
@@ -1,27 +1,2 @@
|
|||||||
# Binaries for programs and plugins
|
|
||||||
main
|
|
||||||
TypoML
|
TypoML
|
||||||
*.exe
|
src.bin
|
||||||
*.exe~
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
*.dll
|
|
||||||
|
|
||||||
# Ignore binary output folders
|
|
||||||
bin/
|
|
||||||
|
|
||||||
# Ignore common editor/system specific metadata
|
|
||||||
.DS_Store
|
|
||||||
.idea/
|
|
||||||
.vscode/
|
|
||||||
*.iml
|
|
||||||
|
|
||||||
# ENV
|
|
||||||
.env
|
|
||||||
|
|
||||||
# Web assets and local databases
|
|
||||||
*.db
|
|
||||||
*.js
|
|
||||||
|
|
||||||
# Ignore installed modules through `v install --local`:
|
|
||||||
modules/
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
all: build
|
all: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
v src/
|
odin build src/ -out:TypoML
|
||||||
|
|
||||||
run:
|
run:
|
||||||
v run src/
|
odin run src/
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f TypoML
|
rm -f TypoML
|
||||||
|
|
||||||
format:
|
format:
|
||||||
v fmt -w src/
|
odinfmt -w src/
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
input=$(cat -)
|
input=$(cat -)
|
||||||
input="${input#v run src/}"
|
input="${input#odin run src/}"
|
||||||
style="<style>$(cat styles.css)</style>"
|
style="<style>$(cat styles.css)</style>"
|
||||||
start="<html><head><title>TypoML Preview</title>$style</head><body>"
|
start="<html><head><title>TypoML Preview</title>$style</head><body>"
|
||||||
end="</body></html>"
|
end="</body></html>"
|
||||||
output="$start$input$end"
|
output="$start$input$end"
|
||||||
echo "$output" > /tmp/preview.html
|
echo "$output" > /tmp/preview.html
|
||||||
xdg-open /tmp/preview.html
|
xdg-open /tmp/preview.html
|
||||||
|
|
||||||
|
|||||||
+374
@@ -0,0 +1,374 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:strings"
|
||||||
|
|
||||||
|
get_ext :: proc(url: string) -> string {
|
||||||
|
clean := url
|
||||||
|
if question := strings.index_byte(clean, '?'); question != -1 {
|
||||||
|
clean = clean[:question]
|
||||||
|
}
|
||||||
|
if hash := strings.index_byte(clean, '#'); hash != -1 {
|
||||||
|
clean = clean[:hash]
|
||||||
|
}
|
||||||
|
if dot := strings.last_index_byte(clean, '.'); dot != -1 {
|
||||||
|
return strings.to_lower(clean[dot:], context.temp_allocator)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_type :: proc(url: string) -> string {
|
||||||
|
ext := get_ext(url)
|
||||||
|
switch ext {
|
||||||
|
case ".jpg",
|
||||||
|
".jpeg",
|
||||||
|
".jpe",
|
||||||
|
".jfif",
|
||||||
|
".jif",
|
||||||
|
".pjpeg",
|
||||||
|
".pjp",
|
||||||
|
".png",
|
||||||
|
".apng",
|
||||||
|
".gif",
|
||||||
|
".webp",
|
||||||
|
".avif",
|
||||||
|
".heic",
|
||||||
|
".heif",
|
||||||
|
".hif",
|
||||||
|
".bmp",
|
||||||
|
".dib",
|
||||||
|
".tif",
|
||||||
|
".tiff",
|
||||||
|
".ico",
|
||||||
|
".cur",
|
||||||
|
".svg",
|
||||||
|
".svgz",
|
||||||
|
".raw",
|
||||||
|
".cr2",
|
||||||
|
".cr3",
|
||||||
|
".nef",
|
||||||
|
".nrw",
|
||||||
|
".orf",
|
||||||
|
".sr2",
|
||||||
|
".arw",
|
||||||
|
".srf",
|
||||||
|
".rw2",
|
||||||
|
".pef",
|
||||||
|
".raf",
|
||||||
|
".dng",
|
||||||
|
".3fr",
|
||||||
|
".ari",
|
||||||
|
".bay",
|
||||||
|
".cap",
|
||||||
|
".dcr",
|
||||||
|
".erf",
|
||||||
|
".fff",
|
||||||
|
".iiq",
|
||||||
|
".k25",
|
||||||
|
".kdc",
|
||||||
|
".mdc",
|
||||||
|
".mos",
|
||||||
|
".mrw",
|
||||||
|
".obm",
|
||||||
|
".ptx",
|
||||||
|
".pxn",
|
||||||
|
".r3d",
|
||||||
|
".rwl",
|
||||||
|
".rwz",
|
||||||
|
".srw",
|
||||||
|
".x3f",
|
||||||
|
".gpr",
|
||||||
|
".pgm",
|
||||||
|
".ppm",
|
||||||
|
".pbm",
|
||||||
|
".pnm",
|
||||||
|
".pam",
|
||||||
|
".pfm",
|
||||||
|
".tga",
|
||||||
|
".icb",
|
||||||
|
".vda",
|
||||||
|
".vst",
|
||||||
|
".pcx",
|
||||||
|
".xbm",
|
||||||
|
".xpm",
|
||||||
|
".xwd",
|
||||||
|
".sgi",
|
||||||
|
".rgb",
|
||||||
|
".rgba",
|
||||||
|
".bw",
|
||||||
|
".jp2",
|
||||||
|
".j2k",
|
||||||
|
".j2c",
|
||||||
|
".jpf",
|
||||||
|
".jpx",
|
||||||
|
".jpm",
|
||||||
|
".mj2",
|
||||||
|
".wbmp",
|
||||||
|
".emf",
|
||||||
|
".wmf",
|
||||||
|
".eps",
|
||||||
|
".epsi",
|
||||||
|
".epsf",
|
||||||
|
".psd",
|
||||||
|
".psb",
|
||||||
|
".ai",
|
||||||
|
".cdr",
|
||||||
|
".xcf",
|
||||||
|
".gbr",
|
||||||
|
".gih",
|
||||||
|
".pat",
|
||||||
|
".art",
|
||||||
|
".jxl",
|
||||||
|
".jxr",
|
||||||
|
".wdp",
|
||||||
|
".hdp",
|
||||||
|
".exr",
|
||||||
|
".hdr",
|
||||||
|
".dpx",
|
||||||
|
".cin",
|
||||||
|
".fits",
|
||||||
|
".fit",
|
||||||
|
".fts",
|
||||||
|
".icns",
|
||||||
|
".flif",
|
||||||
|
".dds",
|
||||||
|
".ktx",
|
||||||
|
".ktx2",
|
||||||
|
".astc",
|
||||||
|
".kodak",
|
||||||
|
".fpx",
|
||||||
|
".pcd",
|
||||||
|
".cmx",
|
||||||
|
".drw",
|
||||||
|
".cgm",
|
||||||
|
".plt",
|
||||||
|
".hpgl",
|
||||||
|
".iff",
|
||||||
|
".ilbm",
|
||||||
|
".lbm",
|
||||||
|
".mac",
|
||||||
|
".msp",
|
||||||
|
".pct",
|
||||||
|
".pic",
|
||||||
|
".pict",
|
||||||
|
".pntg",
|
||||||
|
".qtif",
|
||||||
|
".qti",
|
||||||
|
".ras",
|
||||||
|
".sun",
|
||||||
|
".tpic",
|
||||||
|
".wpg",
|
||||||
|
".g3",
|
||||||
|
".g4",
|
||||||
|
".dcm",
|
||||||
|
".dicom",
|
||||||
|
".ora",
|
||||||
|
".kra",
|
||||||
|
".clip":
|
||||||
|
return "image"
|
||||||
|
case ".mp3",
|
||||||
|
".mp2",
|
||||||
|
".mp1",
|
||||||
|
".mpa",
|
||||||
|
".mpga",
|
||||||
|
".ogg",
|
||||||
|
".oga",
|
||||||
|
".opus",
|
||||||
|
".spx",
|
||||||
|
".wav",
|
||||||
|
".wave",
|
||||||
|
".flac",
|
||||||
|
".aac",
|
||||||
|
".adts",
|
||||||
|
".wma",
|
||||||
|
".m4a",
|
||||||
|
".m4b",
|
||||||
|
".m4p",
|
||||||
|
".m4r",
|
||||||
|
".aif",
|
||||||
|
".aiff",
|
||||||
|
".aifc",
|
||||||
|
".au",
|
||||||
|
".snd",
|
||||||
|
".mid",
|
||||||
|
".midi",
|
||||||
|
".rmi",
|
||||||
|
".kar",
|
||||||
|
".ra",
|
||||||
|
".ram",
|
||||||
|
".mka",
|
||||||
|
".ape",
|
||||||
|
".wv",
|
||||||
|
".ac3",
|
||||||
|
".ec3",
|
||||||
|
".eac3",
|
||||||
|
".dts",
|
||||||
|
".dtshd",
|
||||||
|
".amr",
|
||||||
|
".awb",
|
||||||
|
".caf",
|
||||||
|
".gsm",
|
||||||
|
".mpc",
|
||||||
|
".shn",
|
||||||
|
".tta",
|
||||||
|
".voc",
|
||||||
|
".vox",
|
||||||
|
".8svx",
|
||||||
|
".mod",
|
||||||
|
".s3m",
|
||||||
|
".xm",
|
||||||
|
".it",
|
||||||
|
".stm",
|
||||||
|
".med",
|
||||||
|
".mtm",
|
||||||
|
".umx",
|
||||||
|
".669",
|
||||||
|
".far",
|
||||||
|
".amf",
|
||||||
|
".dsm",
|
||||||
|
".gdm",
|
||||||
|
".imf",
|
||||||
|
".okt",
|
||||||
|
".sfx",
|
||||||
|
".ult",
|
||||||
|
".uni",
|
||||||
|
".psm",
|
||||||
|
".j2b",
|
||||||
|
".dbm",
|
||||||
|
".digi",
|
||||||
|
".dtm",
|
||||||
|
".plm",
|
||||||
|
".nsf",
|
||||||
|
".nsfe",
|
||||||
|
".spc",
|
||||||
|
".gym",
|
||||||
|
".vgm",
|
||||||
|
".vgz",
|
||||||
|
".gbs",
|
||||||
|
".hes",
|
||||||
|
".ay",
|
||||||
|
".sid",
|
||||||
|
".oma",
|
||||||
|
".aa3",
|
||||||
|
".at3",
|
||||||
|
".at9",
|
||||||
|
".qcp",
|
||||||
|
".tak",
|
||||||
|
".ofr",
|
||||||
|
".ofs",
|
||||||
|
".sox",
|
||||||
|
".weba",
|
||||||
|
".dss",
|
||||||
|
".alac",
|
||||||
|
".vqf",
|
||||||
|
".vql",
|
||||||
|
".mxmf",
|
||||||
|
".ota",
|
||||||
|
".imy",
|
||||||
|
".rtttl",
|
||||||
|
".rtx",
|
||||||
|
".xmf",
|
||||||
|
".w64",
|
||||||
|
".rf64",
|
||||||
|
".bwf",
|
||||||
|
".cda",
|
||||||
|
".aup":
|
||||||
|
return "audio"
|
||||||
|
case ".mp4",
|
||||||
|
".m4v",
|
||||||
|
".mp4v",
|
||||||
|
".webm",
|
||||||
|
".mov",
|
||||||
|
".qt",
|
||||||
|
".avi",
|
||||||
|
".mkv",
|
||||||
|
".flv",
|
||||||
|
".f4v",
|
||||||
|
".f4p",
|
||||||
|
".f4a",
|
||||||
|
".f4b",
|
||||||
|
".wmv",
|
||||||
|
".mpg",
|
||||||
|
".mpeg",
|
||||||
|
".mpe",
|
||||||
|
".m1v",
|
||||||
|
".m2v",
|
||||||
|
".mpv",
|
||||||
|
".mp2v",
|
||||||
|
".mpv2",
|
||||||
|
".ogv",
|
||||||
|
".ogx",
|
||||||
|
".3gp",
|
||||||
|
".3g2",
|
||||||
|
".3gpp",
|
||||||
|
".3gpp2",
|
||||||
|
".asf",
|
||||||
|
".asx",
|
||||||
|
".vob",
|
||||||
|
".ts",
|
||||||
|
".mts",
|
||||||
|
".m2ts",
|
||||||
|
".tsv",
|
||||||
|
".tsa",
|
||||||
|
".divx",
|
||||||
|
".xvid",
|
||||||
|
".rm",
|
||||||
|
".rmvb",
|
||||||
|
".swf",
|
||||||
|
".dv",
|
||||||
|
".dif",
|
||||||
|
".gifv",
|
||||||
|
".roq",
|
||||||
|
".nsv",
|
||||||
|
".svi",
|
||||||
|
".annodex",
|
||||||
|
".axv",
|
||||||
|
".amv",
|
||||||
|
".bik",
|
||||||
|
".bk2",
|
||||||
|
".smk",
|
||||||
|
".ivf",
|
||||||
|
".mxf",
|
||||||
|
".nut",
|
||||||
|
".ogm",
|
||||||
|
".fli",
|
||||||
|
".flc",
|
||||||
|
".y4m",
|
||||||
|
".264",
|
||||||
|
".h264",
|
||||||
|
".265",
|
||||||
|
".h265",
|
||||||
|
".hevc",
|
||||||
|
".av1",
|
||||||
|
".vc1",
|
||||||
|
".vp8",
|
||||||
|
".vp9",
|
||||||
|
".wtv",
|
||||||
|
".yuv",
|
||||||
|
".str",
|
||||||
|
".pva",
|
||||||
|
".trp",
|
||||||
|
".rec",
|
||||||
|
".vid",
|
||||||
|
".rv",
|
||||||
|
".cpk",
|
||||||
|
".film":
|
||||||
|
return "video"
|
||||||
|
case:
|
||||||
|
return "iframe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_type_hint :: proc(type_hint: string) -> string {
|
||||||
|
switch type_hint {
|
||||||
|
case "i", "image", "img":
|
||||||
|
return "image"
|
||||||
|
case "a", "audio":
|
||||||
|
return "audio"
|
||||||
|
case "v", "video":
|
||||||
|
return "video"
|
||||||
|
case "f", "iframe", "frame":
|
||||||
|
return "iframe"
|
||||||
|
case:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
-74
@@ -1,74 +0,0 @@
|
|||||||
fn get_ext(url string) string {
|
|
||||||
mut clean := url
|
|
||||||
if question := clean.index('?') {
|
|
||||||
clean = clean[..question]
|
|
||||||
}
|
|
||||||
if hash := clean.index('#') {
|
|
||||||
clean = clean[..hash]
|
|
||||||
}
|
|
||||||
if dot := clean.last_index('.') {
|
|
||||||
return clean[dot..].to_lower()
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
fn detect_type(url string) string {
|
|
||||||
ext := get_ext(url)
|
|
||||||
return match ext {
|
|
||||||
'.jpg', '.jpeg', '.jpe', '.jfif', '.jif', '.pjpeg', '.pjp', '.png', '.apng', '.gif',
|
|
||||||
'.webp', '.avif', '.heic', '.heif', '.hif', '.bmp', '.dib', '.tif', '.tiff', '.ico',
|
|
||||||
'.cur', '.svg', '.svgz', '.raw', '.cr2', '.cr3', '.nef', '.nrw', '.orf', '.sr2', '.arw',
|
|
||||||
'.srf', '.rw2', '.pef', '.raf', '.dng', '.3fr', '.ari', '.bay', '.cap', '.dcr', '.erf',
|
|
||||||
'.fff', '.iiq', '.k25', '.kdc', '.mdc', '.mos', '.mrw', '.obm', '.ptx', '.pxn', '.r3d',
|
|
||||||
'.rwl', '.rwz', '.srw', '.x3f', '.gpr', '.pgm', '.ppm', '.pbm', '.pnm', '.pam', '.pfm',
|
|
||||||
'.tga', '.icb', '.vda', '.vst', '.pcx', '.xbm', '.xpm', '.xwd', '.sgi', '.rgb', '.rgba',
|
|
||||||
'.bw', '.jp2', '.j2k', '.j2c', '.jpf', '.jpx', '.jpm', '.mj2', '.wbmp', '.emf', '.wmf',
|
|
||||||
'.eps', '.epsi', '.epsf', '.psd', '.psb', '.ai', '.cdr', '.xcf', '.gbr', '.gih', '.pat',
|
|
||||||
'.art', '.jxl', '.jxr', '.wdp', '.hdp', '.exr', '.hdr', '.dpx', '.cin', '.fits', '.fit',
|
|
||||||
'.fts', '.icns', '.flif', '.dds', '.ktx', '.ktx2', '.astc', '.kodak', '.fpx', '.pcd',
|
|
||||||
'.cmx', '.drw', '.cgm', '.plt', '.hpgl', '.iff', '.ilbm', '.lbm', '.mac', '.msp', '.pct',
|
|
||||||
'.pic', '.pict', '.pntg', '.qtif', '.qti', '.ras', '.sun', '.tpic', '.wpg', '.g3', '.g4',
|
|
||||||
'.dcm', '.dicom', '.ora', '.kra', '.clip' {
|
|
||||||
'image'
|
|
||||||
}
|
|
||||||
'.mp3', '.mp2', '.mp1', '.mpa', '.mpga', '.ogg', '.oga', '.opus', '.spx', '.wav', '.wave',
|
|
||||||
'.flac', '.aac', '.adts', '.wma', '.m4a', '.m4b', '.m4p', '.m4r', '.aif', '.aiff', '.aifc',
|
|
||||||
'.au', '.snd', '.mid', '.midi', '.rmi', '.kar', '.ra', '.ram', '.mka', '.ape', '.wv',
|
|
||||||
'.ac3', '.ec3', '.eac3', '.dts', '.dtshd', '.amr', '.awb', '.caf', '.gsm', '.mpc', '.shn',
|
|
||||||
'.tta', '.voc', '.vox', '.8svx', '.mod', '.s3m', '.xm', '.it', '.stm', '.med', '.mtm',
|
|
||||||
'.umx', '.669', '.far', '.amf', '.dsm', '.gdm', '.imf', '.okt', '.sfx', '.ult', '.uni',
|
|
||||||
'.psm', '.j2b', '.dbm', '.digi', '.dtm', '.plm', '.nsf', '.nsfe', '.spc', '.gym', '.vgm',
|
|
||||||
'.vgz', '.gbs', '.hes', '.ay', '.sid', '.oma', '.aa3', '.at3', '.at9', '.qcp', '.tak',
|
|
||||||
'.ofr', '.ofs', '.sox', '.weba', '.dss', '.alac', '.vqf', '.vql', '.mxmf', '.ota', '.imy',
|
|
||||||
'.rtttl', '.rtx', '.xmf', '.w64', '.rf64', '.bwf', '.cda', '.aup' {
|
|
||||||
'audio'
|
|
||||||
}
|
|
||||||
'.mp4', '.m4v', '.mp4v', '.webm', '.mov', '.qt', '.avi', '.mkv', '.flv', '.f4v', '.f4p',
|
|
||||||
'.f4a', '.f4b', '.wmv', '.mpg', '.mpeg', '.mpe', '.m1v', '.m2v', '.mpv', '.mp2v', '.mpv2',
|
|
||||||
'.ogv', '.ogx', '.3gp', '.3g2', '.3gpp', '.3gpp2', '.asf', '.asx', '.vob', '.ts', '.mts',
|
|
||||||
'.m2ts', '.tsv', '.tsa', '.divx', '.xvid', '.rm', '.rmvb', '.swf', '.dv', '.dif', '.gifv',
|
|
||||||
'.roq', '.nsv', '.svi', '.annodex', '.axv', '.amv', '.bik', '.bk2', '.smk', '.ivf', '.mxf',
|
|
||||||
'.nut', '.ogm', '.fli', '.flc', '.y4m', '.264', '.h264', '.265', '.h265', '.hevc', '.av1',
|
|
||||||
'.vc1', '.vp8', '.vp9', '.wtv', '.yuv', '.str', '.pva', '.trp', '.rec', '.vid', '.rv',
|
|
||||||
'.cpk', '.film' {
|
|
||||||
'video'
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
'iframe'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// will look like this:
|
|
||||||
// $[https://krzak.org/krzak-icon.png|i]
|
|
||||||
// $(https://krzak.org/krzak-icon.png|image)
|
|
||||||
// $[Krzak.org icon](https://krzak.org/krzak-icon.png|i)
|
|
||||||
fn parse_type_hint(type_hint string) string {
|
|
||||||
return match type_hint {
|
|
||||||
'i', 'image', 'img' { 'image' }
|
|
||||||
'a', 'audio' { 'audio' }
|
|
||||||
'v', 'video' { 'video' }
|
|
||||||
'f', 'iframe' { 'iframe' }
|
|
||||||
else { '' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:os"
|
||||||
|
import "core:strings"
|
||||||
|
|
||||||
|
read_stdin :: proc() -> []string {
|
||||||
|
data, err := os.read_entire_file_from_file(os.stdin, context.allocator)
|
||||||
|
content := string(data)
|
||||||
|
return strings.split_lines(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
print_token :: proc(token: Token, depth: int = 0) {
|
||||||
|
indent := strings.repeat(" ", depth, context.temp_allocator)
|
||||||
|
|
||||||
|
type_str := ""
|
||||||
|
switch token.type {
|
||||||
|
case TokenType.Root:
|
||||||
|
type_str = "Root"
|
||||||
|
case TokenType.Text:
|
||||||
|
type_str = "Text"
|
||||||
|
case TokenType.Italics:
|
||||||
|
type_str = "Italics"
|
||||||
|
case TokenType.Bold:
|
||||||
|
type_str = "Bold"
|
||||||
|
case TokenType.BreakLine:
|
||||||
|
type_str = "BreakLine"
|
||||||
|
case TokenType.Heading:
|
||||||
|
type_str = "Heading"
|
||||||
|
case TokenType.Paragraph:
|
||||||
|
type_str = "Paragraph"
|
||||||
|
}
|
||||||
|
|
||||||
|
value_str := ""
|
||||||
|
switch v in token.value {
|
||||||
|
case string:
|
||||||
|
value_str = v
|
||||||
|
case int:
|
||||||
|
value_str = fmt.aprintf("%d", v, allocator = context.temp_allocator)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value_str != "" {
|
||||||
|
fmt.printf("%s%s(%s)", indent, type_str, value_str)
|
||||||
|
} else {
|
||||||
|
fmt.printf("%s%s", indent, type_str)
|
||||||
|
}
|
||||||
|
fmt.println()
|
||||||
|
|
||||||
|
for child in token.children {
|
||||||
|
print_token(child, depth + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
lines := read_stdin()
|
||||||
|
parsed := parse(lines)
|
||||||
|
print_token(parsed)
|
||||||
|
}
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
import os
|
|
||||||
|
|
||||||
fn read_stdin() []string {
|
|
||||||
mut lines := []string{}
|
|
||||||
for {
|
|
||||||
line := os.get_line()
|
|
||||||
if line.len == 0 && os.stdin().eof() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
lines << line
|
|
||||||
}
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
lines := read_stdin()
|
|
||||||
println(parse(lines))
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:strings"
|
||||||
|
|
||||||
|
TokenType :: enum {
|
||||||
|
Text,
|
||||||
|
Italics,
|
||||||
|
Bold,
|
||||||
|
BreakLine,
|
||||||
|
Heading,
|
||||||
|
Paragraph,
|
||||||
|
Root,
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenValue :: union {
|
||||||
|
string,
|
||||||
|
int,
|
||||||
|
}
|
||||||
|
|
||||||
|
Token :: struct {
|
||||||
|
type: TokenType,
|
||||||
|
value: TokenValue,
|
||||||
|
children: [dynamic]Token,
|
||||||
|
parent: ^Token,
|
||||||
|
}
|
||||||
|
|
||||||
|
current_token: ^Token
|
||||||
|
|
||||||
|
replace_text :: proc(text: string, start: int, len_: int, repl: string) -> string {
|
||||||
|
builder := strings.builder_make(context.temp_allocator)
|
||||||
|
strings.write_string(&builder, text[:start])
|
||||||
|
strings.write_string(&builder, repl)
|
||||||
|
strings.write_string(&builder, text[start + len_:])
|
||||||
|
return strings.to_string(builder)
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_header :: proc(line: string) -> (int, string) {
|
||||||
|
if len(line) == 0 {
|
||||||
|
return 0, line
|
||||||
|
}
|
||||||
|
|
||||||
|
lvl := 0
|
||||||
|
for lvl < len(line) && line[lvl] == '!' {
|
||||||
|
lvl += 1
|
||||||
|
}
|
||||||
|
if lvl == 0 || lvl >= len(line) || line[lvl] != ' ' {
|
||||||
|
return 0, line
|
||||||
|
}
|
||||||
|
return lvl, line[lvl + 1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
parse :: proc(lines: []string, allocator := context.allocator) -> Token {
|
||||||
|
root := Token{TokenType.Root, nil, nil, nil}
|
||||||
|
current_token := &root
|
||||||
|
append(¤t_token.children, Token{TokenType.Paragraph, nil, nil, current_token})
|
||||||
|
current_token = ¤t_token.children[0]
|
||||||
|
|
||||||
|
for untrimmed_line, line_index in lines {
|
||||||
|
line := strings.trim_space(untrimmed_line)
|
||||||
|
|
||||||
|
if len(line) == 0 && line_index != len(lines) - 1 {
|
||||||
|
if current_token.parent != nil {
|
||||||
|
current_token = current_token.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
append(¤t_token.children, Token{TokenType.Paragraph, nil, nil, current_token})
|
||||||
|
current_token = ¤t_token.children[len(current_token.children) - 1]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
append(¤t_token.children, Token{TokenType.Text, line, nil, current_token})
|
||||||
|
|
||||||
|
// lvl, text := parse_header(trimmed)
|
||||||
|
// is_header := lvl > 0
|
||||||
|
|
||||||
|
// if is_header {
|
||||||
|
// fmt.sbprintf(&builder, "<h%d>", lvl)
|
||||||
|
// strings.write_string(&builder, text)
|
||||||
|
// fmt.sbprintf(&builder, "</h%d>", lvl)
|
||||||
|
// } else {
|
||||||
|
// strings.write_string(&builder, text)
|
||||||
|
// strings.write_string(&builder, "<br>")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// strings.write_string(&builder, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
return root
|
||||||
|
}
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
fn replace(text string, start int, len int, repl string) string {
|
|
||||||
return text[..start] + repl + text[start + len..]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_header(line string) (int, string) {
|
|
||||||
if line.len == 0 {
|
|
||||||
return 0, line
|
|
||||||
}
|
|
||||||
|
|
||||||
mut lvl := 0
|
|
||||||
for lvl < line.len && line[lvl] == '!'.bytes()[0] {
|
|
||||||
lvl++
|
|
||||||
}
|
|
||||||
if lvl == 0 || lvl >= line.len || line[lvl] != ' '.bytes()[0] {
|
|
||||||
return 0, line
|
|
||||||
}
|
|
||||||
return lvl, line[lvl + 1..]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse(lines []string) string {
|
|
||||||
mut output := '<p>'
|
|
||||||
for line in lines {
|
|
||||||
mut trimmed := line.trim_space()
|
|
||||||
|
|
||||||
if trimmed.len == 0 {
|
|
||||||
output += '<br>\n'
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
lvl, mut text := parse_header(trimmed)
|
|
||||||
|
|
||||||
is_header := lvl > 0
|
|
||||||
|
|
||||||
if is_header {
|
|
||||||
output += '<h' + lvl.str() + '>'
|
|
||||||
output += text + '</h' + lvl.str() + '>'
|
|
||||||
} else {
|
|
||||||
output += text
|
|
||||||
output += '<br>'
|
|
||||||
}
|
|
||||||
|
|
||||||
output += '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
output += '</p>'
|
|
||||||
return output
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
clear && make format && cat README.tlm | make run | ./preview
|
clear && make format && cat README.tlm | make run # | ./preview
|
||||||
|
|||||||
Reference in New Issue
Block a user