ftml 0.5.0

Foundation Text Markup Language - a library to render Wikidot text as HTML
Documentation
//
// include/grammar.pest
//
// ftml - Library to parse Wikidot text
// Copyright (C) 2019-2021 Wikijump Team
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

// A simple parser generation exclusively to extract [[include]] directives
// within the wikitext. Other elements should be ignored and left as-is.

// The "include" rule has some strange logic:
//
// [[include]]s can have leading *and* trailing pipe separators,
// for instance [[include page | a = 1 ]] or [[include page a = 1 | ]] (or both)
//
// Additionally, each argument must be separated from each other with a pipe.
// We encapsulate this logic by essentially doing "(parameter ~ pipe)* ~ (parameter ~ pipe?)?
// That is, all internal parameters need pipes inside, but the last does not,
// and is optional should the sequence end in a pipe.

include = {
    SOI ~
    "[[" ~ space ~ ^"include" ~ space ~
    page_ref ~ space ~
    "|"? ~ space ~
    (argument ~ space ~ "|" ~ space)* ~
    (argument ~ space ~ ("|" ~ space)?)? ~
    "]]"
}

argument = {
    identifier ~ space ~
    "=" ~ space ~
    value
}

// This implements Wikidot's logic of "escaping" newlines or ]]s in
// an argument's value by placing a space after.

value = {
    (
        ("]]"? ~ " " ~ NEWLINE) |
        (!("|" | "]]" | NEWLINE) ~ ANY)
    )+
}

// Reference to a page, possibly not on this wiki

page_ref = {
    (":" ~ identifier ~ ":")? ~ page_name
}
site_name = _{ identifier }
page_name = { (ASCII_ALPHANUMERIC | "-" | "_" | ":")+ }

// Helpers

identifier = { (ASCII_ALPHANUMERIC | "-" | "_")+ }
space = _{ (" " | "\n" | "\t")* }

// vim: set fdm=marker foldlevel=0: