348ce400b593fac0158c269eff1db159d2ef4ce2
[wix.git] / src / wix.g
1 // WiX Grammar //////////////////////////////////////////////////////////////////////////////
2
3 #import url.g as url
4 #import indent.g as indent
5
6 //#import tokens.g as tokens // disabled until transinclusion bug is fixed
7
8 s                   = Doc
9
10 Doc::               = Header Body
11 Header::            = () // not yet specified
12 Body::              = Section */ br
13
14 // multi-line header by indenting second line?
15 Section::           = SectionHeader
16                     | SectionHeader (nl|br) >> Pars <<
17                     > SectionHeader (nl|br) Pars
18 SectionHeader::     = (^"=" [=]++) ws (Text & ~[\n]*)
19
20 Pars::              = (Par <<* & indent.Balanced &~ "=" ...) */ br
21
22 // An "unbalanced" paragraph (may need trailing outdents to balance)
23 Par                 = NonTextParagraph
24                     > TextParagraph
25
26 TextParagraph::     = Text
27
28 NonTextParagraph    = UL::         `("":: ("*"             BBullet nl)*) "*"             UBullet
29                     | OL::         `("":: (tok.Int! [.\)]! BBullet nl)*) tok.Int! [.\)]! UBullet
30                     | Blockquote:: "\"\"" ws >> Pars
31                     | HR::         "---" "-"*
32                     | Verbatim::   "\\pre" " "* "\n" (I:: [ ]*) >> Verbatim <<
33
34 // a "balanced bullet"
35 BBullet    = (UBullet <<*) & indent.Balanced
36
37 // an "unbalanced bullet"
38 UBullet    = whitespace (LI:: Par */ br)
39              & ~[\n]* ("\n" [ \r\n]* >> ...)?
40
41 Verbatim            = VerbatimBrace:: Verbatim >> Verbatim <<
42                     | Verbatim:: Verbatim ~[>><<]
43                     | Verbatim:: ()
44
45 // note that Text and TextWS are left-recursive because this is more
46 // efficient in LR parsers
47
48 // text followed by optional whitespace
49 TextWS               =  ()
50                      |  Text
51                      |  Text:: `Text (WS:: whitespace)
52
53 Text::              = `Text     nl            >> (Pars:: NonTextParagraph)
54                     > `TextWS   (Link::       Atom  "->" ws href)
55                     > `TextWS   styled                                                
56                     > `TextWS   Ordinal
57                     | `TextWS   Fraction
58                     > `TextWS   Atom
59                     | `TextWS   (Command::    "\\" ("":: [a-zA-Z0-9:]++ &~ "pre") Block)
60                     | `TextWS   (Command::    "\\" ("":: [a-zA-Z0-9:]++ &~ "pre") -> ~"{")     
61                     | `TextWS   (Quotes::  "\"" (Text & ~[\"]*) "\"")
62                     | `TextWS   glyph                                                 
63                     > `TextWS   sym
64                     > `Text     (WS:: br)     >> (Pars -> <<)   // subparagraph
65
66 href                =        url.Email
67                     >        url.URL          &~ ... url.avoidOnUrlTail
68                     >        url.Path         &~ ... url.avoidOnUrlTail
69                     | "{" ws url.Email ws "}"
70                     > "{" ws url.URL   ws "}"
71                     > "{" ws url.Path  ws "}"
72                  // > Citation:: "[" tok.alphanum++ "]"
73
74 Atom                = Word | Block
75 Block               = "{" ws TextWS "}"
76 Word::              = tok.alphanum++
77 Fraction::          =  ("":: [0-9]+) "/" ("":: [0-9]+)
78 Ordinal::           = `("":: [0-9]*) ( [1]    "st"
79                                      | [2]    "nd"
80                                      | [3]    "rd"
81                                      | [04-9] "th" )
82
83 styled              = Underline::     "__"       Text                       "__"      
84                     | Footnote::      "(("       Text                       "))"
85                     | TT::            "[["  ws  (Text & ((~[\]]! | "]" -> ~[\]])*))  ws  "]]"
86                     | Strikethrough:: "!!"       Text         "!!"      
87                     | Superscript::   "^^"       Atom
88                     | Subscript::     ",,"       Atom
89                     | Bold::          "++"      (Text & ((~[\+]! | "+" -> ~[\+])*))      "++"
90                     | Highlight::     "##"      (Text & ((~[\#]! | "#" -> ~[\#])*))      "##"
91                     | Math::          "$$"      (~[\$] | ([\$] -> ~[\$]))+     "$$"
92                     | Keyword::       "!"        Atom
93                     | Italic::        "**"      (Text & ((~[\*]! | "*" -> ~[\*])*))      "**"
94
95 glyph               = ^"(e)" | ^"(r)" | ^"(c)" | ^"(tm)" | ^"--" | ^"---"
96                     | ^"..." | ^"<-" | ^"<=" | ^"=>" | ^"<->"
97                     | ^"<=>" | ^"<-" | ^"^o"
98                     // ^"->"
99
100
101
102
103 // Chars ///////////////////////////////////////////////////////////////
104
105 sym         = Word:: "\\" ~tok.alphanum
106             | Word:: ~(tok.alphanum | [\r\n \\{}>><<])
107
108 hws!        = [ \r>>]
109 ws!         = (hws* "\n")? hws*                   -> ~[ \n\r]
110 whitespace! =  hws+                               -> ~[ \n\r]
111             |  hws* "\n"   hws*                   -> ~[ \n\r]
112
113 // these don't include indents-as-whitespace
114 nl!         = [ \r]* "\n"  [ \r]*                 -> ~[ \n\r]
115 br!         = [ \r]* "\n"  [ \r]*  "\n" [ \r\n]*  -> ~[ \n\r]
116
117