Files
Luma-Parser/src/luma/parser.gleam
T
deck f85a5c3cda
Build and Bundle Gleam App / format (push) Successful in 9s
Build and Bundle Gleam App / build-and-bundle (push) Successful in 43s
chore(format): formatted the code
2026-07-10 00:26:22 +02:00

78 lines
2.1 KiB
Gleam

import gleam/dict
import gleam/int
import gleam/list
import gleam/result
import gleam/string
import luma/definition
import luma/mode
/// main parse function
/// takes in some input text and returns instructions on how to parse it
pub fn handler(line: String) -> definition.TextInstructions {
let result = parse(line)
let result = list.map(result, whatsthat)
definition.TextInstructions(result)
}
fn whatsthat(mod: String) -> definition.Instruction {
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 != "" })
}