Модуль:SummaryII/types

Материал из свободной русской энциклопедии «Традиция»
Перейти к навигации Перейти к поиску
Description Value Parsed

Number

param	<- {| mode1 / mode2 / tail |} !.
close	<- "]]"
class	<- { %d^3 }
tag1	<- {`[[ wikilink ]]`}
suffix2	<- {:suffix: ( !value2 !separator irrelevant )+ :}
dot	<- "."
mode2	<- item2 ( separator? item2 )* tail? {:mode: tag2 :}
int_dot	<- {:classes: {| senior ( {:class_sep: %s+ / dot / "" :} class )* |} :}
screened	<- "[[" %s* ":" ( !"]]" . )+ "]]"
float_comma	<- int_dot ( {:decimal: comma :} frac )? !( dot %d )
irrelevant	<- ( screened / . )
float_dot	<- int_comma ({:decimal: dot :} frac)?
item2	<- {| prefix2? value2 suffix2? |}
pipe	<- "|"
exp_10caron	<- multiply %s* "10" %s* "^" %s* {:exp: sign? %s* %d+ :}
separator	<- {:separator: ( ( "<br" ( %s* "/" )? ">" ) / [,;%nl] %s* ) :}
exp_e	<- [eE] %s* {:exp: sign? %s* %d+ :}
mode1	<- item1 ( separator? item1 )* tail? {:mode: tag1 :}
prefix1	<- {:prefix: ( !value1 irrelevant )+ :}
exp	<- exp_e / exp_10caron / exp_10sup
prefix2	<- {:prefix: ( !value2 irrelevant )+ :}
screen	<- ":"
alias	<- {:alias: ( !close . )+ :}
value1	<- open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close
tail	<- {:tail: .+ :}
frac	<- {:frac: %d+ :}
exp_10sup	<- multiply %s* "10" %s* "<sup>" %s* {:exp: sign? %s* %d+ :} %s* "</sup>"
value_quoted	<- quantity
int_comma	<- {:classes: {| senior ( {:class_sep: %s+ / comma / "" :} class )* |} :}
senior	<- { %d+ }
open	<- "[["
sign	<- [+-]?
tag2	<- {`plain`}
quantity	<- {:sign: sign :} %s* ( float_comma / float_dot ) %s* exp?
comma	<- ","
multiply	<- [*•⋅]
value_plain	<- quantity
value2	<- value_plain
suffix1	<- {:suffix: ( !value1 !separator irrelevant )+ :}
item1	<- {| prefix1? value1 suffix1? |}
Quoted and irrelevant
[[42]] (in [[Russia]])
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "42",
    },
    ["sign"] = "",
    ["suffix"] = " (in [[Russia]])",
  },
  ["mode"] = "[[ wikilink ]]",
}
Plain dot-separated float with spaces
1 004.5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = " ",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Comma-sep. two plain dot-sep. floats
4.5, 6.7
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  table#4 {
    ["classes"] = table#5 {
      "6",
    },
    ["decimal"] = ".",
    ["frac"] = "7",
    ["sign"] = "",
  },
  ["mode"] = "plain",
  ["separator"] = ", ",
}
Plain comma-separated float
4,5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Quoted integer and screened
[[45]] (in [[:1945]])
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "45",
    },
    ["sign"] = "",
    ["suffix"] = " (in [[:1945]])",
  },
  ["mode"] = "[[ wikilink ]]",
}
Plain two-digits integer
45
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "45",
    },
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Plain dot-separated float
4.5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Quoted comma-separated float with exp. e
[[1,5e2]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
    },
    ["decimal"] = ",",
    ["exp"] = "2",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted dot-separated float with commas
[[1,004.5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = ",",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted dot-separated float
[[4.5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted one-digit integer
[[5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "5",
    },
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Plain comma-separated float with dots
1.004,5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = ".",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Comma-sep. two plain comma-sep. floats
4,5, 6,7
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  table#4 {
    ["classes"] = table#5 {
      "6",
    },
    ["decimal"] = ",",
    ["frac"] = "7",
    ["sign"] = "",
  },
  ["mode"] = "plain",
  ["separator"] = ", ",
}
Plain one-digit integer
5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "5",
    },
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Plain dot-separated float with commas
1,004.5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = ",",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Quoted comma-separated float
[[4,5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Two quoted two-digits integer
[[45]] and [[67]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "45",
    },
    ["sign"] = "",
    ["suffix"] = " and ",
  },
  table#4 {
    ["classes"] = table#5 {
      "67",
    },
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted comma-separated float with dots
[[1.004,5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = ".",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted comma-separated float with spaces
[[1 004,5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = " ",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted dot-separated float with spaces
[[1 004.5]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = " ",
    },
    ["decimal"] = ".",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Plain comma-separated float with spaces
1 004,5
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
      "004",
      ["class_sep"] = " ",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
Quoted two-digits integer
[[45]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "45",
    },
    ["sign"] = "",
  },
  ["mode"] = "[[ wikilink ]]",
}
Plain comma-separated float with exponent e
1,5e2
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "1",
    },
    ["decimal"] = ",",
    ["exp"] = "2",
    ["frac"] = "5",
    ["sign"] = "",
  },
  ["mode"] = "plain",
}
S.-comma-sep. two plain comma-sep. floats
4,5; 6,7
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
  },
  table#4 {
    ["classes"] = table#5 {
      "6",
    },
    ["decimal"] = ",",
    ["frac"] = "7",
    ["sign"] = "",
  },
  ["mode"] = "plain",
  ["separator"] = "; ",
}

Free string

param	<- {| mode1 / mode2 / tail |} !.
mode1	<- item1 ( separator? item1 )* tail? {:mode: tag1 :}
prefix1	<- {:prefix: ( !value1 irrelevant )+ :}
close	<- "]]"
prefix2	<- {:prefix: ( !value2 irrelevant )+ :}
tail	<- {:tail: .+ :}
screen	<- ":"
tag1	<- {`[[ wikilink ]]`}
suffix2	<- {:suffix: ( !value2 !separator irrelevant )+ :}
mode2	<- item2 ( separator? item2 )* tail? {:mode: tag2 :}
value_quoted	<- {:value: ( !pipe !close . )+ :}
value1	<- open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close
irrelevant	<- ( screened / . )
screened	<- "[[" %s* ":" ( !"]]" . )+ "]]"
open	<- "[["
tag2	<- {`plain`}
item2	<- {| prefix2? value2 suffix2? |}
pipe	<- "|"
alias	<- {:alias: ( !close . )+ :}
separator	<- {:separator: ( ( "<br" ( %s* "/" )? ">" ) / [,;%nl] %s* ) :}
value_plain	<- {:value: ( !separator !screened . )+ :}
value2	<- value_plain
suffix1	<- {:suffix: ( !value1 !separator irrelevant )+ :}
item1	<- {| prefix1? value1 suffix1? |}
Single plain with suffix
01.234.567 or something
table#1 {
  table#2 {
    ["value"] = "01.234.567 or something",
  },
  ["mode"] = "plain",
}
Several quoted
[[01.234.567]] [[89.012.345]]
table#1 {
  table#2 {
    ["suffix"] = " ",
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single quoted
[[01.234.567]]
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Separated plain
01.234.567, 89.012.345
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "plain",
  ["separator"] = ", ",
}
Quoted but screened
[[:01.234.567]]
table#1 {
  ["tail"] = "[[:01.234.567]]",
}
Screened and not
[[:01.234.567]] [[89.012.345]]
table#1 {
  table#2 {
    ["prefix"] = "[[:01.234.567]] ",
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
}
Screened and plain
[[:01.234.567]] 89.012.345
table#1 {
  table#2 {
    ["prefix"] = "[[:01.234.567]]",
    ["value"] = " 89.012.345",
  },
  ["mode"] = "plain",
}
Separated quoted
[[01.234.567]], [[89.012.345]]
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
  ["separator"] = ", ",
}
Several quoted, prefixed
[[01.234.567]] and [[89.012.345]]
table#1 {
  table#2 {
    ["suffix"] = " and ",
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single plain
01.234.567
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  ["mode"] = "plain",
}
Quoted with alias
[[01.234.567|you know]]
table#1 {
  table#2 {
    ["alias"] = "you know",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single quoted with prefix
About [[01.234.567]]
table#1 {
  table#2 {
    ["prefix"] = "About ",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single quoted with suffix
[[01.234.567]] or something
table#1 {
  table#2 {
    ["suffix"] = " or something",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single plain with prefix
About 01.234.567
table#1 {
  table#2 {
    ["value"] = "About 01.234.567",
  },
  ["mode"] = "plain",
}

Quantity

param	<- {| mode1 / mode2 / tail |} !.
close	<- "]]"
class	<- { %d^3 }
tag1	<- {`[[ wikilink ]]`}
suffix2	<- {:suffix: ( !value2 !separator irrelevant )+ :}
dot	<- "."
mode2	<- item2 ( separator? item2 )* tail? {:mode: tag2 :}
int_dot	<- {:classes: {| senior ( {:class_sep: %s+ / dot / "" :} class )* |} :}
screened	<- "[[" %s* ":" ( !"]]" . )+ "]]"
float_comma	<- int_dot ( {:decimal: comma :} frac )? !( dot %d )
irrelevant	<- ( screened / . )
float_dot	<- int_comma ({:decimal: dot :} frac)?
item2	<- {| prefix2? value2 suffix2? |}
pipe	<- "|"
exp_10caron	<- multiply %s* "10" %s* "^" %s* {:exp: sign? %s* %d+ :}
separator	<- {:separator: ( ( "<br" ( %s* "/" )? ">" ) / [,;%nl] %s* ) :}
exp_e	<- [eE] %s* {:exp: sign? %s* %d+ :}
mode1	<- item1 ( separator? item1 )* tail? {:mode: tag1 :}
prefix1	<- {:prefix: ( !value1 irrelevant )+ :}
exp	<- exp_e / exp_10caron / exp_10sup
prefix2	<- {:prefix: ( !value2 irrelevant )+ :}
screen	<- ":"
alias	<- {:alias: ( !close . )+ :}
value1	<- open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close
tail	<- {:tail: .+ :}
frac	<- {:frac: %d+ :}
exp_10sup	<- multiply %s* "10" %s* "<sup>" %s* {:exp: sign? %s* %d+ :} %s* "</sup>"
value_quoted	<- quantity
int_comma	<- {:classes: {| senior ( {:class_sep: %s+ / comma / "" :} class )* |} :}
senior	<- { %d+ }
open	<- "[["
sign	<- [+-]?
tag2	<- {`plain`}
quantity	<- {:sign: sign :} %s* ( float_comma / float_dot ) %s* exp? %s* {:unit: "мкм" / "мм" / "см" / "м" / "км" :}
comma	<- ","
multiply	<- [*•⋅]
value_plain	<- quantity
value2	<- value_plain
suffix1	<- {:suffix: ( !value1 !separator irrelevant )+ :}
item1	<- {| prefix1? value1 suffix1? |}
Quoted and irrelevant
[[42]] (in [[Russia]])
table#1 {
  ["tail"] = "[[42]] (in [[Russia]])",
}
Plain dot-separated float with spaces
1 004.5
table#1 {
  ["tail"] = "1 004.5",
}
Comma-sep. two plain dot-sep. floats
4.5, 6.7
table#1 {
  ["tail"] = "4.5, 6.7",
}
Plain comma-separated float
4,5
table#1 {
  ["tail"] = "4,5",
}
Quoted integer and screened
[[45]] (in [[:1945]])
table#1 {
  ["tail"] = "[[45]] (in [[:1945]])",
}
Plain two-digits integer; unit
45 м
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "45",
    },
    ["sign"] = "",
    ["unit"] = "м",
  },
  ["mode"] = "plain",
}
Quoted comma-separated float with exp. e
[[1,5e2]]
table#1 {
  ["tail"] = "[[1,5e2]]",
}
Quoted dot-separated float with commas
[[1,004.5]]
table#1 {
  ["tail"] = "[[1,004.5]]",
}
Plain two-digits integer
45
table#1 {
  ["tail"] = "45",
}
Plain comma-separated float; unit
4,5 м
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
    ["unit"] = "м",
  },
  ["mode"] = "plain",
}
Plain comma-separated float with exponent e
1,5e2
table#1 {
  ["tail"] = "1,5e2",
}
Quoted comma-separated float with dots
[[1.004,5]]
table#1 {
  ["tail"] = "[[1.004,5]]",
}
Quoted comma-separated float with spaces
[[1 004,5]]
table#1 {
  ["tail"] = "[[1 004,5]]",
}
Quoted dot-separated float
[[4.5]]
table#1 {
  ["tail"] = "[[4.5]]",
}
Quoted one-digit integer
[[5]]
table#1 {
  ["tail"] = "[[5]]",
}
Plain comma-separated float with dots
1.004,5
table#1 {
  ["tail"] = "1.004,5",
}
Comma-sep. two plain comma-sep. floats
4,5, 6,7
table#1 {
  ["tail"] = "4,5, 6,7",
}
Plain one-digit integer
5
table#1 {
  ["tail"] = "5",
}
Plain dot-separated float with commas
1,004.5
table#1 {
  ["tail"] = "1,004.5",
}
Quoted comma-separated float
[[4,5]]
table#1 {
  ["tail"] = "[[4,5]]",
}
Two quoted two-digits integer
[[45]] and [[67]]
table#1 {
  ["tail"] = "[[45]] and [[67]]",
}
Comma-sep. two plain comma-sep. floats; u.
4,5 м, 6,7 м
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "4",
    },
    ["decimal"] = ",",
    ["frac"] = "5",
    ["sign"] = "",
    ["unit"] = "м",
  },
  table#4 {
    ["classes"] = table#5 {
      "6",
    },
    ["decimal"] = ",",
    ["frac"] = "7",
    ["sign"] = "",
    ["unit"] = "м",
  },
  ["mode"] = "plain",
  ["separator"] = ", ",
}
Quoted two-digits integer
[[45]]
table#1 {
  ["tail"] = "[[45]]",
}
Quoted dot-separated float with spaces
[[1 004.5]]
table#1 {
  ["tail"] = "[[1 004.5]]",
}
Plain comma-separated float with spaces
1 004,5
table#1 {
  ["tail"] = "1 004,5",
}
Plain dot-separated float
4.5
table#1 {
  ["tail"] = "4.5",
}
Two quoted two-digits integer, unit
[[45 м]] and [[67м]]
table#1 {
  table#2 {
    ["classes"] = table#3 {
      "45",
    },
    ["sign"] = "",
    ["suffix"] = " and ",
    ["unit"] = "м",
  },
  table#4 {
    ["classes"] = table#5 {
      "67",
    },
    ["sign"] = "",
    ["unit"] = "м",
  },
  ["mode"] = "[[ wikilink ]]",
}
S.-comma-sep. two plain comma-sep. floats
4,5; 6,7
table#1 {
  ["tail"] = "4,5; 6,7",
}

Page

param	<- {| mode1 / mode2 / tail |} !.
mode1	<- item1 ( separator? item1 )* tail? {:mode: tag1 :}
prefix1	<- {:prefix: ( !value1 irrelevant )+ :}
close	<- "]]"
prefix2	<- {:prefix: ( !value2 irrelevant )+ :}
tail	<- {:tail: .+ :}
screen	<- ":"
tag1	<- {`[[ wikilink ]]`}
suffix2	<- {:suffix: ( !value2 !separator irrelevant )+ :}
ns	<- "Обсуждение" / "Talk" / "Участник" / "User" / "Участница" / "Обсуждение участника" / "User talk" / "Обсуждение участницы" / "Традиция" / "Project" / "Т" / "Traditio" / "Обсуждение Традиции" / "Project talk" / "Обсуждение Traditio" / "Файл" / "File" / "Изображение" / "Image" / "Обсуждение файла" / "File talk" / "Обсуждение изображения" / "Image talk" / "MediaWiki" / "MediaWiki" / "Обсуждение MediaWiki" / "MediaWiki talk" / "Шаблон" / "Template" / "Обсуждение шаблона" / "Template talk" / "Справка" / "Help" / "Обсуждение справки" / "Help talk" / "Категория" / "Category" / "Обсуждение категории" / "Category talk" / "smw/schema" / "smw/schema" / "Обсуждение текста" / "Обсуждение текста" / "Text talk" / "Служебная" / "Special" / "Медиа" / "Media" / "TimedText talk" / "TimedText talk" / "Свойство" / "Свойство" / "Property" / "Обсуждение концепции" / "Обсуждение концепции" / "Concept talk" / "smw/schema talk" / "smw/schema talk" / "Черновик" / "Черновик" / "Draft" / "Обсуждение портала" / "Обсуждение портала" / "Обсуждение определения гаджета" / "Gadget definition talk" / "Обсуждение формы" / "Form talk" / "Гаджет" / "Gadget" / "Определение гаджета" / "Gadget definition" / "" / "" / "(Основное)" / "Rule" / "Rule" / "Обсуждение черновика" / "Обсуждение черновика" / "Draft talk" / "Campaign" / "Campaign" / "Обсуждение свойства" / "Обсуждение свойства" / "Property talk" / "Текст" / "Текст" / "Text" / "Модуль" / "Module" / "Campaign talk" / "Campaign talk" / "Обсуждение модуля" / "Module talk" / "Rule talk" / "Rule talk" / "Портал" / "Портал" / "GeoJson talk" / "GeoJson talk" / "Форма" / "Form" / "GeoJson" / "GeoJson" / "Обсуждение гаджета" / "Gadget talk" / "Концепция" / "Концепция" / "Concept" / "TimedText" / "TimedText"
mode2	<- item2 ( separator? item2 )* tail? {:mode: tag2 :}
alias	<- {:alias: ( !close . )+ :}
value1	<- open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close
screened	<- "[[" %s* ":" ( !"]]" . )+ "]]"
value_quoted	<- ( {:namespace: ns :} %s* ":" %s* )? {:page: ( !pipe !close legal )+ :} ( hashtag {:section: ( !pipe !close . )+ :} )?
irrelevant	<- ( screened / . )
hashtag	<- "#"
open	<- "[["
legal	<- [^]#<>[|{}_]
item2	<- {| prefix2? value2 suffix2? |}
pipe	<- "|"
tag2	<- {`plain`}
separator	<- {:separator: ( ( "<br" ( %s* "/" )? ">" ) / [,;%nl] %s* ) :}
value_plain	<- ( {:namespace: ns :} %s* ":" %s* )? {:page: ( !separator legal )+ :} ( hashtag {:section: ( !%s !separator . )+ :} )?
value2	<- value_plain
suffix1	<- {:suffix: ( !value1 !separator irrelevant )+ :}
item1	<- {| prefix1? value1 suffix1? |}
Quoted section
[[Title#section 1]]
table#1 {
  table#2 {
    ["page"] = "Title",
    ["section"] = "section 1",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted, ,-separated
[[Title1]], [[title2]]
table#1 {
  table#2 {
    ["page"] = "Title1",
  },
  table#3 {
    ["page"] = "title2",
  },
  ["mode"] = "[[ wikilink ]]",
  ["separator"] = ", ",
}
Plain text, NL-separated
Plain 1
Plain 2
table#1 {
  table#2 {
    ["page"] = "Plain 1",
  },
  table#3 {
    ["page"] = "Plain 2",
  },
  ["mode"] = "plain",
  ["separator"] = "\
",
}
Only screened
[[:screened]]
table#1 {
  ["tail"] = "[[:screened]]",
}
Plain section
Title#section_1
table#1 {
  table#2 {
    ["page"] = "Title",
    ["section"] = "section_1",
  },
  ["mode"] = "plain",
}
Alias
[[Title|Alias]]
table#1 {
  table#2 {
    ["alias"] = "Alias",
    ["page"] = "Title",
  },
  ["mode"] = "[[ wikilink ]]",
}
Several quoted, not prefixed
[[Title1]] [[title2]]
table#1 {
  table#2 {
    ["page"] = "Title1",
    ["suffix"] = " ",
  },
  table#3 {
    ["page"] = "title2",
  },
  ["mode"] = "[[ wikilink ]]",
}
With namespace
Текст:О величии
table#1 {
  table#2 {
    ["page"] = "Текст:О величии",
  },
  ["mode"] = "plain",
}
Quoted
[[Title]]
table#1 {
  table#2 {
    ["page"] = "Title",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted, ,-separated, suffices
[[Title1]] (before), [[title2]] (now)
table#1 {
  table#2 {
    ["page"] = "Title1",
    ["suffix"] = " (before)",
  },
  table#3 {
    ["page"] = "title2",
    ["suffix"] = " (now)",
  },
  ["mode"] = "[[ wikilink ]]",
  ["separator"] = ", ",
}
Screened and some plain
[[:screened]] and some plain
table#1 {
  table#2 {
    ["page"] = " and some plain",
    ["prefix"] = "[[:screened]]",
  },
  ["mode"] = "plain",
}
Plain text
Plain text 1
table#1 {
  table#2 {
    ["page"] = "Plain text 1",
  },
  ["mode"] = "plain",
}
Alias and no alias
[[Title1|Alias]], [[Title2]]
table#1 {
  table#2 {
    ["alias"] = "Alias",
    ["page"] = "Title1",
  },
  table#3 {
    ["page"] = "Title2",
  },
  ["mode"] = "[[ wikilink ]]",
  ["separator"] = ", ",
}
Several quoted, prefixed
[[Title1]] and [[title2]]
table#1 {
  table#2 {
    ["page"] = "Title1",
    ["suffix"] = " and ",
  },
  table#3 {
    ["page"] = "title2",
  },
  ["mode"] = "[[ wikilink ]]",
}
Aliases, prefixes
Two titles [[Title1|1]] and [[Title2|2]]
table#1 {
  table#2 {
    ["alias"] = "1",
    ["page"] = "Title1",
    ["prefix"] = "Two titles ",
    ["suffix"] = " and ",
  },
  table#3 {
    ["alias"] = "2",
    ["page"] = "Title2",
  },
  ["mode"] = "[[ wikilink ]]",
}
Screened
[[Title]] (in [[:1942]])
table#1 {
  table#2 {
    ["page"] = "Title",
    ["suffix"] = " (in [[:1942]])",
  },
  ["mode"] = "[[ wikilink ]]",
}
Tail
[[Title]] (in [[:1942]]), allegedly
table#1 {
  table#2 {
    ["page"] = "Title",
    ["suffix"] = " (in [[:1942]])",
  },
  ["mode"] = "[[ wikilink ]]",
  ["tail"] = ", allegedly",
}
Plain text, ,-separated
Plain text 1, plain text 2
table#1 {
  table#2 {
    ["page"] = "Plain text 1",
  },
  table#3 {
    ["page"] = "plain text 2",
  },
  ["mode"] = "plain",
  ["separator"] = ", ",
}

Formatted string

param	<- {| mode1 / mode2 / tail |} !.
mode1	<- item1 ( separator? item1 )* tail? {:mode: tag1 :}
prefix1	<- {:prefix: ( !value1 irrelevant )+ :}
close	<- "]]"
prefix2	<- {:prefix: ( !value2 irrelevant )+ :}
tail	<- {:tail: .+ :}
screen	<- ":"
tag1	<- {`[[ wikilink ]]`}
suffix2	<- {:suffix: ( !value2 !separator irrelevant )+ :}
mode2	<- item2 ( separator? item2 )* tail? {:mode: tag2 :}
value_quoted	<- {:value: {/\d\d\.\d\d\d\.\d\d\d/} :}
value1	<- open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close
irrelevant	<- ( screened / . )
screened	<- "[[" %s* ":" ( !"]]" . )+ "]]"
open	<- "[["
tag2	<- {`plain`}
item2	<- {| prefix2? value2 suffix2? |}
pipe	<- "|"
alias	<- {:alias: ( !close . )+ :}
separator	<- {:separator: ( ( "<br" ( %s* "/" )? ">" ) / [,;%nl] %s* ) :}
value_plain	<- {:value: {/\d\d\.\d\d\d\.\d\d\d/} :}
value2	<- value_plain
suffix1	<- {:suffix: ( !value1 !separator irrelevant )+ :}
item1	<- {| prefix1? value1 suffix1? |}
Quoted and irrelevant
[[01.234.567]] (in [[Russia]])
table#1 {
  table#2 {
    ["suffix"] = " (in [[Russia]])",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single plain with suffix
01.234.567 or something
table#1 {
  table#2 {
    ["suffix"] = " or something",
    ["value"] = "01.234.567",
  },
  ["mode"] = "plain",
}
Several quoted
[[01.234.567]] [[89.012.345]]
table#1 {
  table#2 {
    ["suffix"] = " ",
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single quoted
[[01.234.567]]
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Several quoted, prefixed
[[01.234.567]] and [[89.012.345]]
table#1 {
  table#2 {
    ["suffix"] = " and ",
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
}
Separated plain
01.234.567, 89.012.345
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "plain",
  ["separator"] = ", ",
}
Screened and not
[[:01.234.567]] [[89.012.345]]
table#1 {
  table#2 {
    ["prefix"] = "[[:01.234.567]] ",
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
}
Quoted but screened
[[:01.234.567]]
table#1 {
  ["tail"] = "[[:01.234.567]]",
}
Screened and plain
[[:01.234.567]] 89.012.345
table#1 {
  table#2 {
    ["prefix"] = "[[:01.234.567]] ",
    ["value"] = "89.012.345",
  },
  ["mode"] = "plain",
}
Separated quoted
[[01.234.567]], [[89.012.345]]
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "[[ wikilink ]]",
  ["separator"] = ", ",
}
Quoted with alias
[[01.234.567|you know]]
table#1 {
  table#2 {
    ["alias"] = "you know",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single plain
01.234.567
table#1 {
  table#2 {
    ["value"] = "01.234.567",
  },
  ["mode"] = "plain",
}
Several plain
01.234.567 and 89.012.345
table#1 {
  table#2 {
    ["suffix"] = " and ",
    ["value"] = "01.234.567",
  },
  table#3 {
    ["value"] = "89.012.345",
  },
  ["mode"] = "plain",
}
Single quoted with prefix
About [[01.234.567]]
table#1 {
  table#2 {
    ["prefix"] = "About ",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single quoted with suffix
[[01.234.567]] or something
table#1 {
  table#2 {
    ["suffix"] = " or something",
    ["value"] = "01.234.567",
  },
  ["mode"] = "[[ wikilink ]]",
}
Single plain with prefix
About 01.234.567
table#1 {
  table#2 {
    ["prefix"] = "About ",
    ["value"] = "01.234.567",
  },
  ["mode"] = "plain",
}

local dependencies = require 'Module:SummaryII/dependencies'
local gsub, merge, concat = dependencies.gsub, dependencies.merge, dependencies.join

local p = {
	open		= '[[',
	screen		= ':',
	pipe		= '|',
	close		= ']]',
	separator	= '( ( "<br" ( %s* "/" )? ">" ) / [,;%nl] %s* )',
	four_dots	= '::'
}

local function dq (str)
	return '"' .. str .. '"'
end

p.screened = dq (p.open) .. ' %s* ' .. dq (p.screen) .. ' ( !' .. dq (p.close) .. ' . )+ ' .. dq (p.close)

local modes = {
	internal = {
		__mode		= '[[ wikilink ]]',
		open		= dq (p.open),
		screen		= dq (p.screen),
		pipe		= dq (p.pipe),
		close		= dq (p.close),
		value		= 'open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close',
		alias		= '{:alias: ( !close . )+ :}'
	},
	external = {
		__mode		= '[ url ]',
		open		= dq '[',
		pipe		= '%s+',
		close		= dq ']'
	},
	plain = {
		__mode		= 'plain',
		value		= 'value_plain'
	}
}

local function ns (...)
	local namespaces = {...}
	local content = namespaces[1] == 'content'
	local subject = namespaces[1] == 'subject'
	local list
	if namespaces [1] == 0 then
		-- main namespace:
		list = ''
	else
		-- other namespace(s):
		namespaces = #namespaces == 0				and dependencies.namespace_ids.all
				  or namespaces [1] == 'content'	and dependencies.namespace_ids.content
				  or namespaces [1] == 'subject'	and dependencies.namespace_ids.subject
				  or namespaces

		local aliases = {}
		for _, id in ipairs (namespaces) do
			local config = dependencies.namespaces [id]
			if config then
				aliases [#aliases + 1] = config.name
				aliases [#aliases + 1] = config.canonicalName
				if config.displayName then
					aliases [#aliases + 1] = config.displayName
				end
				for _, alias in ipairs (config.aliases) do
					aliases [#aliases + 1] = alias
				end
			end
		end
		list = '"' .. gsub (concat (aliases, '" / "'), '_', ' ') .. '"'
	end
	return list, namespace and dependencies.namespaces [namespaces [1]].name or ''
end

local function quantity (units)
	return '{:sign: sign :} %s* ( float_comma / float_dot ) %s* exp?'
		.. (units and ' %s* {:unit: ' .. units .. ' :}' or '')
end

local types = {
	Page = {
		value_quoted	= '( {:namespace: ns :} %s* ":" %s* )? {:page: ( !pipe !close legal )+ :} ( hashtag {:section: ( !pipe !close . )+ :} )?',
		value_plain		= '( {:namespace: ns :} %s* ":" %s* )? {:page: ( !separator legal )+ :} ( hashtag {:section: ( !%s !separator . )+ :} )?',
		ns				= ns,
		legal			= '[^]#<>[|{}_]',
		hashtag			= '"#"'
	},
	String = {
		value_quoted = function (regex)
			return '{:value: ' .. (regex and '{/' .. regex .. '/}' or '( !pipe !close . )+') .. ' :}'
		end,
		value_plain = function (regex)
			return '{:value: ' .. (regex and '{/' .. regex .. '/}' or '( !separator !screened . )+') .. ' :}'
		end
	},
	Number = {
		value_plain		= 'quantity',
		value_quoted	= 'quantity',
		quantity		= quantity,
		sign			= '[+-]?',
	    float_comma		= 'int_dot ( {:decimal: comma :} frac )? !( dot %d )',
	    int_dot			= '{:classes: {| senior ( {:class_sep: %s+ / dot / "" :} class )* |} :}',
	    float_dot		= 'int_comma ({:decimal: dot :} frac)?',
	    int_comma		= '{:classes: {| senior ( {:class_sep: %s+ / comma / "" :} class )* |} :}',
	    senior			= '{ %d+ }',
	    class			= '{ %d^3 }',
	    frac			= '{:frac: %d+ :}',
	    exp				= 'exp_e / exp_10caron / exp_10sup',
	    exp_e			= '[eE] %s* {:exp: sign? %s* %d+ :}',
	    exp_10caron		= 'multiply %s* "10" %s* "^" %s* {:exp: sign? %s* %d+ :}',
	    exp_10sup		= 'multiply %s* "10" %s* "<sup>" %s* {:exp: sign? %s* %d+ :} %s* "</sup>"',
	    multiply		= '[*•⋅]',
	    dot				= '"."',
	    comma			= '","'
	}
}

local function concat_dict (dict)
	local array = {}
	for _, value in ipairs (dict) do
		array [#array + 1] = value
	end
	for key, value in pairs (dict) do
		if type (key) ~= 'number' then
			array [#array + 1] = tostring (key) .. '	<- ' .. tostring (value)
		end
	end
	return concat (array, '\n')
end

local function resolve (tbl, ...)
	for key, value in pairs (tbl) do
		if type (value) == 'function' then
			tbl [key] = value (...)
		end
	end
	return tbl
end

local function sequence (mode, defs, ...)
	local m, tag, item, value, prefix, suffix = 'mode' .. mode, 'tag' .. mode, 'item' .. mode, 'value' .. mode, 'prefix' .. mode, 'suffix' .. mode
	local seq = merge ({
		[m]				= item .. ' ( separator? ' .. item .. ' )* tail? {:mode: ' .. tag .. ' :}',
		[item]			= '{| ' .. prefix .. '? ' .. value .. ' ' .. suffix .. '? |}',
		[prefix]		= '{:prefix: ( !' .. value .. ' irrelevant )+ :}',
		[suffix]		= '{:suffix: ( !' .. value .. ' !separator irrelevant )+ :}',
		[tag]			= '{`' .. defs.__mode .. '`}',
		[value]			= defs.value
	}, defs)
	seq.__mode, seq.value = nil, nil
	return resolve (seq, ...)
end

local function syntaxes (variants, ...)
	local selection, grammar = {}, {}
	for i, variant in ipairs (variants) do
		grammar = merge (grammar, sequence (i, variant, ...))
		selection [#selection + 1] = 'mode' .. i
	end
	return 'param	<- {| ' .. concat (selection, ' / ') .. ' / tail |} !.\n'
		.. concat_dict (merge (
			grammar, {
				screened	= p.screened,
				separator	= '{:separator: ' .. p.separator .. ' :}',
				irrelevant	= '( screened / . )',				
				tail		= '{:tail: .+ :}'
			}
		))
end

local formats = {
	Page = {
		-- Quoted:
		merge (modes.internal, types.Page),
		-- Plain:
		merge (modes.plain, types.Page)
	},
	String = {
		-- Quoted:
		merge (modes.internal, types.String),
	-- Plain:
		merge (modes.plain, types.String)
	},
	Number = {
		-- Quoted:
		merge (modes.internal, types.Number),
	-- Plain:
		merge (modes.plain, types.Number)
	}
}

local test_cases = {
	Page = {
		format = 'Page',
		cases = {
			['Plain text']						= 'Plain text 1',
			['Plain text, ,-separated']			= 'Plain text 1, plain text 2',
			['Plain text, NL-separated']		= 'Plain 1\nPlain 2',
			['Quoted']							= '[[Title]]',
			['Quoted, ,-separated']				= '[[Title1]], [[title2]]',
			['Several quoted, prefixed']		= '[[Title1]] and [[title2]]',
			['Several quoted, not prefixed']	= '[[Title1]] [[title2]]',
			['Quoted, ,-separated, suffices']	= '[[Title1]] (before), [[title2]] (now)',
			['Tail']							= '[[Title]] (in [[:1942]]), allegedly',
			['Screened']						= '[[Title]] (in [[:1942]])',
			['Alias']							= '[[Title|Alias]]',
			['Alias and no alias']				= '[[Title1|Alias]], [[Title2]]',
			['Aliases, prefixes']				= 'Two titles [[Title1|1]] and [[Title2|2]]',
			['Quoted section']					= '[[Title#section 1]]',
			['Plain section']					= 'Title#section_1',
			['Only screened']					= '[[:screened]]',
			['Screened and some plain']			= '[[:screened]] and some plain',
			['With namespace']					= 'Текст:О величии'
		}
	},
	['Free string'] = {
		format = 'String',
		cases = {
			['Single plain']					= '01.234.567',
			['Single plain with suffix']		= '01.234.567 or something',
			['Single plain with prefix']		= 'About 01.234.567',
			['Separated plain']					= '01.234.567, 89.012.345',
			['Single quoted']					= '[[01.234.567]]',
			['Single quoted with prefix']		= 'About [[01.234.567]]',
			['Single quoted with suffix']		= '[[01.234.567]] or something',
			['Quoted with alias']				= '[[01.234.567|you know]]',
			['Several quoted, prefixed']		= '[[01.234.567]] and [[89.012.345]]',
			['Several quoted']					= '[[01.234.567]] [[89.012.345]]',
			['Separated quoted']				= '[[01.234.567]], [[89.012.345]]',
			['Quoted but screened']				= '[[:01.234.567]]',
			['Screened and not']				= '[[:01.234.567]] [[89.012.345]]',
			['Screened and plain']				= '[[:01.234.567]] 89.012.345'
		}
	},
	['Formatted string'] = {
		format = 'String',
		cases = {
			['Single plain']					= '01.234.567',
			['Single plain with suffix']		= '01.234.567 or something',
			['Single plain with prefix']		= 'About 01.234.567',
			['Separated plain']					= '01.234.567, 89.012.345',
			['Several plain']					= '01.234.567 and 89.012.345',			
			['Single quoted']					= '[[01.234.567]]',
			['Single quoted with prefix']		= 'About [[01.234.567]]',
			['Single quoted with suffix']		= '[[01.234.567]] or something',
			['Quoted with alias']				= '[[01.234.567|you know]]',
			['Several quoted']					= '[[01.234.567]] [[89.012.345]]',
			['Separated quoted']				= '[[01.234.567]], [[89.012.345]]',
			['Several quoted, prefixed']		= '[[01.234.567]] and [[89.012.345]]',			
			['Quoted but screened']				= '[[:01.234.567]]',
			['Quoted and irrelevant']			= '[[01.234.567]] (in [[Russia]])',
			['Screened and not']				= '[[:01.234.567]] [[89.012.345]]',
			['Screened and plain']				= '[[:01.234.567]] 89.012.345'
		},
		params = { '\\d\\d\\.\\d\\d\\d\\.\\d\\d\\d' }
	},
	['Number'] = {
		format	= 'Number',
		cases	= {
			['Plain one-digit integer']						= '5',
			['Plain two-digits integer']					= '45',
			['Plain comma-separated float']					= '4,5',
			['Comma-sep. two plain comma-sep. floats']		= '4,5, 6,7',
			['S.-comma-sep. two plain comma-sep. floats']	= '4,5; 6,7',
			['Plain dot-separated float']					= '4.5',
			['Comma-sep. two plain dot-sep. floats']		= '4.5, 6.7',
			['Plain comma-separated float with spaces']		= '1 004,5',
			['Plain comma-separated float with dots']		= '1.004,5',
			['Plain dot-separated float with spaces']		= '1 004.5',
			['Plain dot-separated float with commas']		= '1,004.5',
			['Plain comma-separated float with exponent e']	= '1,5e2',
			['Plain comma-separated float with exponent e']	= '1,5e2',
			['Quoted one-digit integer']					= '[[5]]',
			['Quoted two-digits integer']					= '[[45]]',
			['Quoted integer and screened']					= '[[45]] (in [[:1945]])',
			['Quoted and irrelevant']						= '[[42]] (in [[Russia]])',			
			['Two quoted two-digits integer']				= '[[45]] and [[67]]',
			['Quoted comma-separated float']				= '[[4,5]]',
			['Quoted dot-separated float']					= '[[4.5]]',
			['Quoted comma-separated float with spaces']	= '[[1 004,5]]',
			['Quoted comma-separated float with dots']		= '[[1.004,5]]',
			['Quoted dot-separated float with spaces']		= '[[1 004.5]]',
			['Quoted dot-separated float with commas']		= '[[1,004.5]]',
			['Quoted comma-separated float with exp. e']	= '[[1,5e2]]',
			['Quoted comma-separated float with exp. e']	= '[[1,5e2]]',
		}
	},
	['Quantity'] = {
		format	= 'Number',
		cases	= {
			['Plain one-digit integer']						= '5',
			['Plain two-digits integer']					= '45',
			['Plain comma-separated float']					= '4,5',
			['Comma-sep. two plain comma-sep. floats']		= '4,5, 6,7',
			['S.-comma-sep. two plain comma-sep. floats']	= '4,5; 6,7',			
			['Plain two-digits integer; unit']				= '45 м',
			['Plain comma-separated float; unit']			= '4,5 м',
			['Comma-sep. two plain comma-sep. floats; u.']	= '4,5 м, 6,7 м',
			['Plain dot-separated float']					= '4.5',
			['Comma-sep. two plain dot-sep. floats']		= '4.5, 6.7',
			['Plain comma-separated float with spaces']		= '1 004,5',
			['Plain comma-separated float with dots']		= '1.004,5',
			['Plain dot-separated float with spaces']		= '1 004.5',
			['Plain dot-separated float with commas']		= '1,004.5',
			['Plain comma-separated float with exponent e']	= '1,5e2',
			['Plain comma-separated float with exponent e']	= '1,5e2',
			['Quoted one-digit integer']					= '[[5]]',
			['Quoted two-digits integer']					= '[[45]]',
			['Quoted integer and screened']					= '[[45]] (in [[:1945]])',
			['Quoted and irrelevant']						= '[[42]] (in [[Russia]])',			
			['Two quoted two-digits integer']				= '[[45]] and [[67]]',
			['Two quoted two-digits integer, unit']			= '[[45 м]] and [[67м]]',
			['Quoted comma-separated float']				= '[[4,5]]',
			['Quoted dot-separated float']					= '[[4.5]]',
			['Quoted comma-separated float with spaces']	= '[[1 004,5]]',
			['Quoted comma-separated float with dots']		= '[[1.004,5]]',
			['Quoted dot-separated float with spaces']		= '[[1 004.5]]',
			['Quoted dot-separated float with commas']		= '[[1,004.5]]',
			['Quoted comma-separated float with exp. e']	= '[[1,5e2]]',
			['Quoted comma-separated float with exp. e']	= '[[1,5e2]]',
		},
		params	= { '"мкм" / "мм" / "см" / "м" / "км"' }
	}
}

p.test = function (frame)
	local output = {}
	local re = require 'Module:Re'
	local dump = mw.dumpObject
	for name, settings in pairs (test_cases) do
		output [#output + 1] = '|-'
		output [#output + 1] = '! colspan="3" |\n=='	.. name .. '=='
		output [#output + 1] = '|-'
		local grammar = syntaxes (formats [settings.format], unpack (settings.params or {}))
		output [#output + 1] = '| colspan="3" | <pre>' .. grammar .. '</pre>'
		local compiled = re.compile (grammar)
		for desc, case in pairs (settings.cases) do
			output [#output + 1] = '|-'
			output [#output + 1] = '| ' .. desc
			output [#output + 1] = '| <pre><nowiki>' .. case .. '</nowiki></pre>'
			output [#output + 1] = '| <pre><nowiki>' .. dump (compiled and compiled:match (case) or 'skipped') .. '</nowiki></pre>'
		end
	end
	local tbl = '__TOC__\n{| class="wikitable"\n! Description !! Value !! Parsed\n'
			 .. concat (output, '\n')
			 .. '\n|}'
	if frame then
		tbl = frame:preprocess (tbl)
	end
	return tbl
end

local grammar_persistent = [[
	param			<- ( quoted / plain / tail ) !.
	quoted			<- item ( separator? item )* tail?
	item			<- {| prefix? link suffix? |}
	link			<- open !screen %s* value_quoted ( %s* pipe %s* alias )? %s* close
	atom			<- screened / ( !open . )
	prefix			<- {:prefix: atom+ :}
	alias			<- {:alias: ( !close . )+ :}
	suffix			<- {:suffix: ( !separator atom )+ :}
	tail			<- {:tail: atom+ :}
	plain			<- {| value_plain |} ( separator {| value_plain |} )* tail?
	screened		<- open screen (!close .)* close
]]

p.legal = '.'
function p.value (value_plain, value_quoted, open, property, screen, pipe, close, separator)
	local default_value
= [==[{| {:value: ( !sep legal )+ :} |}
	legal	<- ]==] .. p.legal
	return 're', grammar_persistent
		.. '	value_plain		<- ' .. (value_plain or default_value)
		.. '\n	value_quoted	<- ' .. (value_quoted or value_plain or default_value)
		.. '\n	open			<- ' .. dq (open or p.open)
		.. '\n	screen			<- ' .. dq (screen or p.screen)
		.. '\n	pipe			<- ' .. dq (pipe or p.pipe)
		.. '\n	close			<- ' .. dq (close or p.close)
		.. '\n	separator		<- {:separator: ' .. (separator or p.separator) .. ' %s* :}'
		..	'\n'
end

function p.format (property)
	return '<<|<<#|'
		.. '(<<?prefix>>)'
		.. p.open .. (property and property .. p.four_dots or '')
		.. '((<<value>>))'
		.. '<<|' .. '\\' .. p.pipe .. '<<alias>>|>>' .. p.close
		.. '<<?suffix>><<,|<<?separator>>>>'
		.. '|>>>>{<<?tail>>}'
	--[[
	return '<<|<<#|'
		.. 'prefix: <<?prefix>>, '
		.. 'value: <<value>>, '
		.. 'alias: <<alias>>, '
		.. 'suffix: <<?suffix>>, separator: <<?separator>>, '
		.. '|>>>>, tail: <<?tail>>'
	]]
end

return p