diff --git a/Makefile b/Makefile
index fb1266a..df29639 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,13 @@
all: build
build:
- v src/
+ odin build src/ -out:TypoML
run:
- v run src/
+ odin run src/
clean:
rm -f TypoML
format:
- v fmt -w src/
+ odinfmt -w src/
diff --git a/preview b/preview
index eff50f0..758a11d 100755
--- a/preview
+++ b/preview
@@ -1,10 +1,9 @@
#!/bin/sh
input=$(cat -)
-input="${input#v run src/}"
+input="${input#odin run src/}"
style=""
start="
TypoML Preview$style"
end=""
output="$start$input$end"
echo "$output" > /tmp/preview.html
xdg-open /tmp/preview.html
-
diff --git a/src/embed.odin b/src/embed.odin
new file mode 100644
index 0000000..d10c6bd
--- /dev/null
+++ b/src/embed.odin
@@ -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 ""
+ }
+}
diff --git a/src/embed.v b/src/embed.v
deleted file mode 100644
index 5be260c..0000000
--- a/src/embed.v
+++ /dev/null
@@ -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 { '' }
- }
-}
diff --git a/src/main.odin b/src/main.odin
new file mode 100644
index 0000000..edf2a20
--- /dev/null
+++ b/src/main.odin
@@ -0,0 +1,17 @@
+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)
+}
+
+main :: proc() {
+ lines := read_stdin()
+ parsed := parse(lines)
+ fmt.println(parsed)
+}
diff --git a/src/main.v b/src/main.v
deleted file mode 100644
index 421f414..0000000
--- a/src/main.v
+++ /dev/null
@@ -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))
-}
diff --git a/src/parser.odin b/src/parser.odin
new file mode 100644
index 0000000..34820d8
--- /dev/null
+++ b/src/parser.odin
@@ -0,0 +1,58 @@
+package main
+
+import "core:fmt"
+import "core:strings"
+
+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) -> string {
+ builder := strings.builder_make(allocator)
+ strings.write_string(&builder, "")
+
+ for line in lines {
+ trimmed := strings.trim_space(line)
+
+ if len(trimmed) == 0 {
+ strings.write_string(&builder, "
\n")
+ continue
+ }
+
+ lvl, text := parse_header(trimmed)
+ is_header := lvl > 0
+
+ if is_header {
+ fmt.sbprintf(&builder, "", lvl)
+ strings.write_string(&builder, text)
+ fmt.sbprintf(&builder, "", lvl)
+ } else {
+ strings.write_string(&builder, text)
+ strings.write_string(&builder, "
")
+ }
+
+ strings.write_string(&builder, "\n")
+ }
+
+ strings.write_string(&builder, "
")
+ return strings.to_string(builder)
+}
diff --git a/src/parser.v b/src/parser.v
deleted file mode 100644
index 17370be..0000000
--- a/src/parser.v
+++ /dev/null
@@ -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 := ''
- for line in lines {
- mut trimmed := line.trim_space()
-
- if trimmed.len == 0 {
- output += '
\n'
- continue
- }
-
- lvl, mut text := parse_header(trimmed)
-
- is_header := lvl > 0
-
- if is_header {
- output += ''
- output += text + ''
- } else {
- output += text
- output += '
'
- }
-
- output += '\n'
- }
-
- output += '
'
- return output
-}
diff --git a/v.mod b/v.mod
deleted file mode 100644
index 152bf4f..0000000
--- a/v.mod
+++ /dev/null
@@ -1,7 +0,0 @@
-Module {
- name: 'TypoML'
- description: ''
- version: '0.0.0'
- license: 'ISC'
- dependencies: []
-}