WHITESPACE_S = _{ " " | "\t" }
// Characters
alt_char = _{ (!(NEWLINE | WHITESPACE_S | "[" | "]") ~ ANY)+ }
b_char = _{ (!(NEWLINE | comment | WHITESPACE_S | "**") ~ ANY)+ }
c_char = _{ (!(NEWLINE | WHITESPACE_S | "`") ~ ANY)+ }
c_line_char = _{ (!(NEWLINE | "```" | "~~~") ~ ANY)+ }
comment_char = _{ (!(NEWLINE | "-->") ~ ANY)+ }
digit = _{ '0'..'9' }
i_char = _{ (!(NEWLINE | comment | WHITESPACE_S | "_" | "*") ~ ANY)+ }
indent = { WHITESPACE_S* }
latex_char = _{ (!(NEWLINE | WHITESPACE_S | "$") ~ ANY)+ }
link_char = _{ (!(NEWLINE | WHITESPACE_S | "[" | "]" | "(" | ")") ~ ANY)+ }
p_char = _{ (!(NEWLINE | comment | footnote_ref_container | code | bold_italic | italic | bold | strikethrough | latex | WHITESPACE_S | link) ~ ANY)+ }
s_char = _{ (!(NEWLINE | comment | WHITESPACE_S | "~~") ~ ANY)+ }
t_char = _{ (!(NEWLINE | comment | code | bold_italic | italic | bold | strikethrough | latex | WHITESPACE_S | "|") ~ ANY)+ }
wiki_link_char = _{ (!(NEWLINE | WHITESPACE_S | "|" | "[[" | "]]") ~ ANY)+ }
inline_link_char = _{ (!(NEWLINE | WHITESPACE_S | "<" | ">") ~ ANY)+ }
// Words
word = {
!(forbidden_sentence_prefix | footnote_ref_container | latex | bold_italic | bold | italic | strikethrough | code | link) ~ NEWLINE? ~ WHITESPACE_S* ~ p_char+
}
t_word = {
!(forbidden_sentence_prefix | latex | bold_italic | bold | italic | strikethrough | code | link) ~ NEWLINE? ~ WHITESPACE_S* ~ t_char+
}
alt_word = _{ WHITESPACE_S* ~ alt_char+ }
bold_italic_word = { WHITESPACE_S* ~ b_char+ }
bold_word = { WHITESPACE_S* ~ b_char+ }
code_word = { WHITESPACE_S* ~ c_char+ }
h_word = { p_char+ ~ WHITESPACE_S? }
italic_word = { WHITESPACE_S* ~ i_char+ }
latex_word = { WHITESPACE_S* ~ latex_char+ }
link_data = { link_char+ }
link_word = { (link_char | WHITESPACE_S | "(" | ")")+ }
strikethrough_word = { WHITESPACE_S* ~ s_char+ }
wiki_link_alone = { wiki_link_char+ }
wiki_link_data = { wiki_link_char+ }
wiki_link_word = { (link_char | WHITESPACE_S)+ }
inline_link = { inline_link_char+ }
footnote_ref = { (!"]" ~ ANY)+ }
footnote_ref_container = _{ (NEWLINE | WHITESPACE_S*)? ~ "[^" ~ footnote_ref ~ "]" }
// Prefixes
task_open = { "- [ ] " }
task_complete = { "- [x] " | "- [X] " }
task_prefix = _{ task_open | task_complete }
quote_prefix = _{ ">" }
code_block_prefix = { "```" | "~~~" }
table_prefix = { "|" }
list_prefix = { (WHITESPACE_S* ~ "-") | (NUMBER+ ~ ". ") }
heading_prefix = { "#" }
forbidden_sentence_prefix = {
NEWLINE ~ WHITESPACE_S* ~ (image | task_prefix | quote_prefix | code_block_prefix | table_prefix | list_prefix | heading_prefix)
}
// Lines
alt_text = { WHITESPACE_S* ~ alt_word+ }
bold = { NEWLINE? ~ WHITESPACE_S* ~ !"\\" ~ "**" ~ (bold_word | (NEWLINE ~ quote_prefix?))+ ~ "**" }
bold_italic = {
(NEWLINE? ~ WHITESPACE_S* ~ !"\\" ~ "***" ~ (bold_italic_word | (NEWLINE ~ (quote_prefix ~ WHITESPACE_S)?))+ ~ "***")
| ((NEWLINE | WHITESPACE_S) ~ WHITESPACE_S* ~ !"\\" ~ "_**" ~ (bold_italic_word | (NEWLINE ~ quote_prefix?))+ ~ "**_")
}
code = { NEWLINE? ~ WHITESPACE_S* ~ ("`" ~ code_word+ ~ "`") | ("```" ~ code_word+ ~ "```") }
code_line = { NEWLINE ~ (c_line_char | WHITESPACE_S)* }
indented_code_line = { NEWLINE ~ (" " | "\t") ~ " "* ~ (!(NEWLINE) ~ ANY)* }
indented_code_newline = { NEWLINE }
latex = {
NEWLINE? ~ WHITESPACE_S* ~ !"\\" ~ "$"+ ~ !" " ~ latex_word ~ (latex_word | (NEWLINE ~ quote_prefix?))* ~ "$"+ ~ !ASCII_ALPHANUMERIC
}
link = { NEWLINE? ~ WHITESPACE_S* ~ (link_line | wiki_link | inline_link_wrapper) }
link_line = _{ "[" ~ (link_word | NEWLINE)+ ~ "]" ~ "(" ~ link_data+ ~ ")" }
inline_link_wrapper = _{ !comment ~ "<" ~ inline_link ~ ">" }
wiki_link = _{ ("[[" ~ wiki_link_alone+ ~ "]]") | ("[[" ~ wiki_link_data+ ~ "|" ~ wiki_link_word+ ~ "]]") }
normal = _{ word+ }
o_list_counter = { digit+ ~ ". " }
programming_language = { (!NEWLINE ~ ANY)+ }
strikethrough = { NEWLINE? ~ WHITESPACE_S* ~ !"\\" ~ "~~" ~ !"~" ~ (strikethrough_word | (NEWLINE ~ quote_prefix?))+ ~ "~~" }
t_normal = _{ t_word+ }
italic = {
(NEWLINE? ~ WHITESPACE_S* ~ !"\\" ~ "*" ~ (italic_word | (NEWLINE ~ quote_prefix?))+ ~ "*")
| ((NEWLINE | WHITESPACE_S) ~ WHITESPACE_S* ~ !"\\" ~ "_" ~ (italic_word | (NEWLINE ~ quote_prefix?))+ ~ "_")
}
sentence = _{ (latex | footnote_ref_container | code | link | bold_italic | italic | bold | strikethrough | normal+)+ }
t_sentence = _{ (!"|" ~ (latex | footnote_ref_container | code | link | bold_italic | italic | bold | strikethrough | t_normal))+ }
footnote_sentence = _{ ((":" | (NEWLINE ~ " ")) ~ WHITESPACE_S* ~ (latex | code | link | bold_italic | italic | bold | strikethrough | normal+))+ }
table_cell = { !table_separator ~ "|" ~ WHITESPACE_S* ~ t_sentence* ~ WHITESPACE_S* ~ ("|" ~ " "* ~ NEWLINE)? }
table_separator = { ("|"? ~ (WHITESPACE_S | ":")* ~ "-"+ ~ (WHITESPACE_S | ":")* ~ "|") }
u_list = { indent ~ ("-" | "*") ~ WHITESPACE_S ~ sentence+ }
o_list = { indent ~ o_list_counter ~ sentence+ }
// Headings
h1 = { "# " ~ (h_word | WHITESPACE_S)+ }
h2 = { "## " ~ (h_word | WHITESPACE_S)+ }
h3 = { "### " ~ (h_word | WHITESPACE_S)+ }
h4 = { "#### " ~ (h_word | WHITESPACE_S)+ }
h5 = { "##### " ~ (h_word | WHITESPACE_S)+ }
h6 = { "###### " ~ (h_word | WHITESPACE_S)+ }
// Quote markings
important = { ^"[!important]" }
note = { ^"[!note]" }
tip = { ^"[!tip]" }
warning = { ^"[!warning]" }
caution = { ^"[!caution]" }
quote_marking = _{ WHITESPACE_S* ~ (important | note | tip | warning | caution) }
// Blocks
heading = { (h1 | h2 | h3 | h4 | h5 | h6) }
list_container = { (NEWLINE? ~ !comment ~ (u_list | o_list))+ }
paragraph = { sentence+ }
indented_code_block = {
indented_code_line ~ (indented_code_line | (indented_code_newline ~ indented_code_line))+ ~ (!(NEWLINE ~ (" " | "\t")) ~ NEWLINE)?
}
code_block = {
NEWLINE? ~ " "* ~ (("```" ~ programming_language? ~ code_line+ ~ " "* ~ "```") | ("~~~" ~ programming_language? ~ code_line+ ~ " "* ~ "~~~") | indented_code_block)
}
table = {
NEWLINE? ~ table_cell+ ~ NEWLINE? ~ table_separator+ ~ (NEWLINE? ~ table_cell)*
}
quote = { (NEWLINE? ~ WHITESPACE_S* ~ ">" ~ ((quote_marking | sentence | " ")+ | NEWLINE))+ }
task = { NEWLINE? ~ task_prefix ~ sentence }
footnote = { NEWLINE? ~ "[^" ~ footnote_ref ~ "]" ~ footnote_sentence+ }
block_sep = { NEWLINE }
horizontal_sep = { NEWLINE? ~ "---" ~ "-"* }
image = { NEWLINE? ~ "" }
comment = _{ "<!--" ~ (NEWLINE | comment_char)+ ~ "-->" }
txt = {
(horizontal_sep | image | footnote | task | comment | table | quote | list_container | code_block | heading | paragraph | block_sep | WHITESPACE_S)+
}