76 lines
2.0 KiB
Gleam
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 != "" })
|
|
}
|