Files
Luma-Parser/src/parser.gleam
T
deck 5bcae0e0d6
Build and Bundle Gleam App / build-and-bundle (push) Successful in 15s
some cleanup
2026-07-09 20:30:16 +02:00

76 lines
2.0 KiB
Gleam

import definition
import gleam/dict
import gleam/int
import gleam/list
import gleam/result
import gleam/string
import mode
pub fn handler(line: String) -> definition.Line {
let result = parse(line)
let result = list.map(result, whatsthat)
definition.Line(result)
}
fn whatsthat(mod: String) -> definition.Inline {
let modes =
dict.from_list([
#("!", #(mode.Marking, definition.Marking)),
#("@", #(mode.Truth, definition.Truth)),
#(">", #(mode.Quote, definition.Quote)),
#("#", #(mode.Hirachy, definition.Hirachy)),
])
case string.pop_grapheme(mod) {
Ok(#(prefix, rest)) -> {
case dict.get(modes, prefix) {
Ok(#(m, make_definition)) -> {
case rest {
"-" -> definition.Pop(m)
_ -> {
let value = int.parse(rest) |> result.unwrap(1)
definition.Push(make_definition(value))
}
}
}
Error(_) -> definition.Text(mod)
}
}
Error(_) -> definition.Text(mod)
}
}
fn parse(modificators: String) -> List(String) {
modificators
// 1. Target the tags + their trailing space, wrapping them in "|"
|> string.replace(each: "#", with: " |#")
|> string.replace(each: "@", with: " |@")
|> string.replace(each: "!", with: " |!")
|> string.replace(each: ">", with: " |>")
// 2. Split by the space-marker combination
|> string.split(on: " |")
// 3. For each block, split out the tag itself from any trailing words
|> list.flat_map(fn(block) {
case
string.starts_with(block, "#")
|| string.starts_with(block, "@")
|| string.starts_with(block, "!")
|| string.starts_with(block, ">")
{
True -> {
// Separate the tag from the text following it
case string.split_once(block, on: " ") {
Ok(#(tag, rest)) -> [tag, rest]
Error(_) -> [block]
}
}
False -> [block]
}
})
// 4. Clean up padding and drop empty elements
|> list.map(string.trim)
|> list.filter(fn(x) { x != "" })
}