This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
peg-markdown / markdown_parser.leg
| ff582f78 » | jgm | 2008-05-05 | 1 | %{ | |
| 2 | /********************************************************************** | ||||
| 3 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 4 | markdown_parser.leg - markdown parser in C using a PEG grammar. | |
| ff582f78 » | jgm | 2008-05-05 | 5 | (c) 2008 John MacFarlane (jgm at berkeley dot edu). | |
| 6 | |||||
| 7 | This program is free software; you can redistribute it and/or modify | ||||
| 8 | it under the terms of the GNU General Public License as published by | ||||
| 9 | the Free Software Foundation; version 2 of the License. | ||||
| 10 | |||||
| 11 | This program is distributed in the hope that it will be useful, | ||||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| 14 | GNU General Public License for more details. | ||||
| 15 | |||||
| 16 | ***********************************************************************/ | ||||
| 17 | |||||
| 18 | #include <stdbool.h> | ||||
| 19 | #include <assert.h> | ||||
| 20 | #include "markdown_peg.h" | ||||
| bea5f65c » | jgm | 2008-06-12 | 21 | #include "utility_functions.c" | |
| ff582f78 » | jgm | 2008-05-05 | 22 | ||
| 23 | /********************************************************************** | ||||
| 24 | |||||
| 25 | PEG grammar and parser actions for markdown syntax. | ||||
| 26 | |||||
| 27 | ***********************************************************************/ | ||||
| 28 | |||||
| 29 | %} | ||||
| 30 | |||||
| 2a7ef09f » | jgm | 2008-06-12 | 31 | Doc = a:StartList ( Block { a = cons($$, a); } )* | |
| 4483b2f8 » | jgm | 2008-06-10 | 32 | { parse_result = reverse(a); } | |
| ff582f78 » | jgm | 2008-05-05 | 33 | ||
| 34 | Block = BlankLine* | ||||
| 3ac63587 » | jgm | 2008-06-09 | 35 | ( BlockQuote | |
| 10bca596 » | jgm | 2008-05-10 | 36 | | Verbatim | |
| 37 | | Note | ||||
| 3ac63587 » | jgm | 2008-06-09 | 38 | | Reference | |
| 5ac4b233 » | jgm | 2008-06-16 | 39 | | HorizontalRule | |
| 3ac63587 » | jgm | 2008-06-09 | 40 | | Heading | |
| 41 | | OrderedList | ||||
| 42 | | BulletList | ||||
| 43 | | HtmlBlock | ||||
| 51ea8667 » | jgm | 2008-07-16 | 44 | | StyleBlock | |
| 3ac63587 » | jgm | 2008-06-09 | 45 | | Para | |
| ff582f78 » | jgm | 2008-05-05 | 46 | | Plain ) | |
| 47 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 48 | Para = NonindentSpace a:Inlines BlankLine+ | |
| 332b562e » | jgm | 2008-06-09 | 49 | { $$ = a; $$->key = PARA; } | |
| ff582f78 » | jgm | 2008-05-05 | 50 | ||
| 51 | Plain = a:Inlines | ||||
| 332b562e » | jgm | 2008-06-09 | 52 | { $$ = a; $$->key = PLAIN; } | |
| ff582f78 » | jgm | 2008-05-05 | 53 | ||
| 54 | AtxInline = !Newline !(Sp '#'* Sp Newline) Inline | ||||
| 55 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 56 | AtxStart = < ( "######" | "#####" | "####" | "###" | "##" | "#" ) > | |
| 332b562e » | jgm | 2008-06-09 | 57 | { $$ = mk_element(H1 + (strlen(yytext) - 1)); } | |
| 3ac63587 » | jgm | 2008-06-09 | 58 | ||
| 2a7ef09f » | jgm | 2008-06-12 | 59 | AtxHeading = s:AtxStart Sp a:StartList ( AtxInline { a = cons($$, a); } )+ (Sp '#'* Sp)? Newline | |
| 2217d5a9 » | jgm | 2008-06-11 | 60 | { $$ = mk_list(s->key, a); | |
| 61 | free(s); } | ||||
| ff582f78 » | jgm | 2008-05-05 | 62 | ||
| 63 | SetextHeading = SetextHeading1 | SetextHeading2 | ||||
| 64 | |||||
| 2a7ef09f » | jgm | 2008-06-12 | 65 | SetextHeading1 = a:StartList ( !Endline Inline { a = cons($$, a); } )+ Newline "===" '='* Newline | |
| ff582f78 » | jgm | 2008-05-05 | 66 | { $$ = mk_list(H1, a); } | |
| 67 | |||||
| 2a7ef09f » | jgm | 2008-06-12 | 68 | SetextHeading2 = a:StartList ( !Endline Inline { a = cons($$, a); } )+ Newline "---" '-'* Newline | |
| ff582f78 » | jgm | 2008-05-05 | 69 | { $$ = mk_list(H2, a); } | |
| 70 | |||||
| 71 | Heading = AtxHeading | SetextHeading | ||||
| 72 | |||||
| 10bca596 » | jgm | 2008-05-10 | 73 | BlockQuote = a:BlockQuoteRaw | |
| 332b562e » | jgm | 2008-06-09 | 74 | { $$ = mk_element(BLOCKQUOTE); | |
| 75 | $$->children = a; | ||||
| 3ac63587 » | jgm | 2008-06-09 | 76 | } | |
| ff582f78 » | jgm | 2008-05-05 | 77 | ||
| a2e3e304 » | jgm | 2008-05-15 | 78 | BlockQuoteRaw = a:StartList | |
| 2a7ef09f » | jgm | 2008-06-12 | 79 | (( '>' ' '? Line { a = cons($$, a); } ) | |
| 80 | ( !'>' !BlankLine Line { a = cons($$, a); } )* | ||||
| 81 | ( BlankLine { a = cons(mk_str("\n"), a); } )* | ||||
| a2e3e304 » | jgm | 2008-05-15 | 82 | )+ | |
| 4483b2f8 » | jgm | 2008-06-10 | 83 | { $$ = mk_str_from_list(a, true); | |
| 332b562e » | jgm | 2008-06-09 | 84 | $$->key = RAW; | |
| ff582f78 » | jgm | 2008-05-05 | 85 | } | |
| 86 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 87 | NonblankIndentedLine = !BlankLine IndentedLine | |
| ff582f78 » | jgm | 2008-05-05 | 88 | ||
| 3ac63587 » | jgm | 2008-06-09 | 89 | VerbatimChunk = a:StartList | |
| 2a7ef09f » | jgm | 2008-06-12 | 90 | ( BlankLine { a = cons(mk_str("\n"), a); } )* | |
| 91 | ( NonblankIndentedLine { a = cons($$, a); } )+ | ||||
| 4483b2f8 » | jgm | 2008-06-10 | 92 | { $$ = mk_str_from_list(a, false); } | |
| ff582f78 » | jgm | 2008-05-05 | 93 | ||
| 2a7ef09f » | jgm | 2008-06-12 | 94 | Verbatim = a:StartList ( VerbatimChunk { a = cons($$, a); } )+ | |
| 4483b2f8 » | jgm | 2008-06-10 | 95 | { $$ = mk_str_from_list(a, false); | |
| 332b562e » | jgm | 2008-06-09 | 96 | $$->key = VERBATIM; } | |
| ff582f78 » | jgm | 2008-05-05 | 97 | ||
| 3ac63587 » | jgm | 2008-06-09 | 98 | HorizontalRule = NonindentSpace | |
| 99 | ( '*' Sp '*' Sp '*' (Sp '*')* | ||||
| ff582f78 » | jgm | 2008-05-05 | 100 | | '-' Sp '-' Sp '-' (Sp '-')* | |
| 101 | | '_' Sp '_' Sp '_' (Sp '_')*) | ||||
| 102 | Sp Newline BlankLine+ | ||||
| 25f29cc1 » | jgm | 2008-06-09 | 103 | { $$ = mk_element(HRULE); } | |
| ff582f78 » | jgm | 2008-05-05 | 104 | ||
| 98f54c73 » | jgm | 2008-09-10 | 105 | Bullet = !HorizontalRule NonindentSpace ('+' | '*' | '-') Spacechar+ | |
| 106 | |||||
| 107 | BulletList = &Bullet (ListTight | ListLoose) | ||||
| 108 | { $$->key = BULLETLIST; } | ||||
| 109 | |||||
| 110 | ListTight = a:StartList | ||||
| 111 | ( ListItem { a = cons($$, a); } )+ | ||||
| 6afc0660 » | jgm | 2009-01-19 | 112 | BlankLine* !(Bullet | Enumerator) | |
| 98f54c73 » | jgm | 2008-09-10 | 113 | { $$ = mk_list(LIST, a); } | |
| 114 | |||||
| 115 | ListLoose = a:StartList | ||||
| 116 | ( b:ListItem BlankLine* | ||||
| 117 | { element *li; | ||||
| 118 | li = b->children; | ||||
| 119 | li->contents.str = realloc(li->contents.str, strlen(li->contents.str) + 3); | ||||
| 120 | strcat(li->contents.str, "\n\n"); /* In loose list, \n\n added to end of each element */ | ||||
| 121 | a = cons(b, a); | ||||
| 122 | } )+ | ||||
| 123 | { $$ = mk_list(LIST, a); } | ||||
| 124 | |||||
| 125 | ListItem = ( Bullet | Enumerator ) | ||||
| 126 | a:StartList | ||||
| 127 | ListBlock { a = cons($$, a); } | ||||
| 128 | ( ListContinuationBlock { a = cons($$, a); } )* | ||||
| 129 | { element *raw; | ||||
| 130 | raw = mk_str_from_list(a, false); | ||||
| 131 | raw->key = RAW; | ||||
| 132 | $$ = mk_element(LISTITEM); | ||||
| 133 | $$->children = raw; | ||||
| 134 | } | ||||
| ff582f78 » | jgm | 2008-05-05 | 135 | ||
| 3ac63587 » | jgm | 2008-06-09 | 136 | ListBlock = a:StartList | |
| 2a7ef09f » | jgm | 2008-06-12 | 137 | Line { a = cons($$, a); } | |
| 138 | ( ListBlockLine { a = cons($$, a); } )* | ||||
| 4483b2f8 » | jgm | 2008-06-10 | 139 | { $$ = mk_str_from_list(a, false); } | |
| ff582f78 » | jgm | 2008-05-05 | 140 | ||
| 3ac63587 » | jgm | 2008-06-09 | 141 | ListContinuationBlock = a:StartList | |
| 33c56384 » | jgm | 2008-06-11 | 142 | ( < BlankLine* > | |
| 143 | { if (strlen(yytext) == 0) | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 144 | a = cons(mk_str("\001"), a); /* block separator */ | |
| 33c56384 » | jgm | 2008-06-11 | 145 | else | |
| 2a7ef09f » | jgm | 2008-06-12 | 146 | a = cons(mk_str(yytext), a); } ) | |
| 147 | ( Indent ListBlock { a = cons($$, a); } )+ | ||||
| 4483b2f8 » | jgm | 2008-06-10 | 148 | { $$ = mk_str_from_list(a, false); } | |
| ff582f78 » | jgm | 2008-05-05 | 149 | ||
| 150 | Enumerator = NonindentSpace [0-9]+ '.' Spacechar+ | ||||
| 151 | |||||
| 98f54c73 » | jgm | 2008-09-10 | 152 | OrderedList = &Enumerator (ListTight | ListLoose) | |
| 153 | { $$->key = ORDEREDLIST; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 154 | ||
| c33826b4 » | jgm | 2009-01-19 | 155 | ListBlockLine = !( Indent? (Bullet | Enumerator) ) | |
| ff582f78 » | jgm | 2008-05-05 | 156 | !BlankLine | |
| 98f54c73 » | jgm | 2008-09-10 | 157 | !HorizontalRule | |
| 3ac63587 » | jgm | 2008-06-09 | 158 | OptionallyIndentedLine | |
| ff582f78 » | jgm | 2008-05-05 | 159 | ||
| 160 | # Parsers for different kinds of block-level HTML content. | ||||
| 161 | # This is repetitive due to constraints of PEG grammar. | ||||
| 162 | |||||
| 163 | HtmlBlockOpenAddress = '<' Spnl ("address" | "ADDRESS") Spnl HtmlAttribute* '>' | ||||
| 164 | HtmlBlockCloseAddress = '<' Spnl '/' ("address" | "ADDRESS") Spnl '>' | ||||
| 165 | |||||
| 166 | HtmlBlockOpenBlockquote = '<' Spnl ("blockquote" | "BLOCKQUOTE") Spnl HtmlAttribute* '>' | ||||
| 167 | HtmlBlockCloseBlockquote = '<' Spnl '/' ("blockquote" | "BLOCKQUOTE") Spnl '>' | ||||
| 168 | |||||
| 169 | HtmlBlockOpenCenter = '<' Spnl ("center" | "CENTER") Spnl HtmlAttribute* '>' | ||||
| 170 | HtmlBlockCloseCenter = '<' Spnl '/' ("center" | "CENTER") Spnl '>' | ||||
| 171 | |||||
| 172 | HtmlBlockOpenDir = '<' Spnl ("dir" | "DIR") Spnl HtmlAttribute* '>' | ||||
| 173 | HtmlBlockCloseDir = '<' Spnl '/' ("dir" | "DIR") Spnl '>' | ||||
| 174 | |||||
| 175 | HtmlBlockOpenDiv = '<' Spnl ("div" | "DIV") Spnl HtmlAttribute* '>' | ||||
| 176 | HtmlBlockCloseDiv = '<' Spnl '/' ("div" | "DIV") Spnl '>' | ||||
| 177 | |||||
| 178 | HtmlBlockOpenDl = '<' Spnl ("dl" | "DL") Spnl HtmlAttribute* '>' | ||||
| 179 | HtmlBlockCloseDl = '<' Spnl '/' ("dl" | "DL") Spnl '>' | ||||
| 180 | |||||
| 181 | HtmlBlockOpenFieldset = '<' Spnl ("fieldset" | "FIELDSET") Spnl HtmlAttribute* '>' | ||||
| 182 | HtmlBlockCloseFieldset = '<' Spnl '/' ("fieldset" | "FIELDSET") Spnl '>' | ||||
| 183 | |||||
| 184 | HtmlBlockOpenForm = '<' Spnl ("form" | "FORM") Spnl HtmlAttribute* '>' | ||||
| 185 | HtmlBlockCloseForm = '<' Spnl '/' ("form" | "FORM") Spnl '>' | ||||
| 186 | |||||
| 187 | HtmlBlockOpenH1 = '<' Spnl ("h1" | "H1") Spnl HtmlAttribute* '>' | ||||
| 188 | HtmlBlockCloseH1 = '<' Spnl '/' ("h1" | "H1") Spnl '>' | ||||
| 189 | |||||
| 190 | HtmlBlockOpenH2 = '<' Spnl ("h2" | "H2") Spnl HtmlAttribute* '>' | ||||
| 191 | HtmlBlockCloseH2 = '<' Spnl '/' ("h2" | "H2") Spnl '>' | ||||
| 192 | |||||
| 193 | HtmlBlockOpenH3 = '<' Spnl ("h3" | "H3") Spnl HtmlAttribute* '>' | ||||
| 194 | HtmlBlockCloseH3 = '<' Spnl '/' ("h3" | "H3") Spnl '>' | ||||
| 195 | |||||
| 196 | HtmlBlockOpenH4 = '<' Spnl ("h4" | "H4") Spnl HtmlAttribute* '>' | ||||
| 197 | HtmlBlockCloseH4 = '<' Spnl '/' ("h4" | "H4") Spnl '>' | ||||
| 198 | |||||
| 199 | HtmlBlockOpenH5 = '<' Spnl ("h5" | "H5") Spnl HtmlAttribute* '>' | ||||
| 200 | HtmlBlockCloseH5 = '<' Spnl '/' ("h5" | "H5") Spnl '>' | ||||
| 201 | |||||
| 202 | HtmlBlockOpenH6 = '<' Spnl ("h6" | "H6") Spnl HtmlAttribute* '>' | ||||
| 203 | HtmlBlockCloseH6 = '<' Spnl '/' ("h6" | "H6") Spnl '>' | ||||
| 204 | |||||
| 205 | HtmlBlockOpenMenu = '<' Spnl ("menu" | "MENU") Spnl HtmlAttribute* '>' | ||||
| 206 | HtmlBlockCloseMenu = '<' Spnl '/' ("menu" | "MENU") Spnl '>' | ||||
| 207 | |||||
| 208 | HtmlBlockOpenNoframes = '<' Spnl ("noframes" | "NOFRAMES") Spnl HtmlAttribute* '>' | ||||
| 209 | HtmlBlockCloseNoframes = '<' Spnl '/' ("noframes" | "NOFRAMES") Spnl '>' | ||||
| 210 | |||||
| 211 | HtmlBlockOpenNoscript = '<' Spnl ("noscript" | "NOSCRIPT") Spnl HtmlAttribute* '>' | ||||
| 212 | HtmlBlockCloseNoscript = '<' Spnl '/' ("noscript" | "NOSCRIPT") Spnl '>' | ||||
| 213 | |||||
| 214 | HtmlBlockOpenOl = '<' Spnl ("ol" | "OL") Spnl HtmlAttribute* '>' | ||||
| 215 | HtmlBlockCloseOl = '<' Spnl '/' ("ol" | "OL") Spnl '>' | ||||
| 216 | |||||
| 217 | HtmlBlockOpenP = '<' Spnl ("p" | "P") Spnl HtmlAttribute* '>' | ||||
| 218 | HtmlBlockCloseP = '<' Spnl '/' ("p" | "P") Spnl '>' | ||||
| 219 | |||||
| 220 | HtmlBlockOpenPre = '<' Spnl ("pre" | "PRE") Spnl HtmlAttribute* '>' | ||||
| 221 | HtmlBlockClosePre = '<' Spnl '/' ("pre" | "PRE") Spnl '>' | ||||
| 222 | |||||
| 223 | HtmlBlockOpenTable = '<' Spnl ("table" | "TABLE") Spnl HtmlAttribute* '>' | ||||
| 224 | HtmlBlockCloseTable = '<' Spnl '/' ("table" | "TABLE") Spnl '>' | ||||
| 225 | |||||
| 226 | HtmlBlockOpenUl = '<' Spnl ("ul" | "UL") Spnl HtmlAttribute* '>' | ||||
| 227 | HtmlBlockCloseUl = '<' Spnl '/' ("ul" | "UL") Spnl '>' | ||||
| 228 | |||||
| 229 | HtmlBlockOpenDd = '<' Spnl ("dd" | "DD") Spnl HtmlAttribute* '>' | ||||
| 230 | HtmlBlockCloseDd = '<' Spnl '/' ("dd" | "DD") Spnl '>' | ||||
| 231 | |||||
| 232 | HtmlBlockOpenDt = '<' Spnl ("dt" | "DT") Spnl HtmlAttribute* '>' | ||||
| 233 | HtmlBlockCloseDt = '<' Spnl '/' ("dt" | "DT") Spnl '>' | ||||
| 234 | |||||
| 235 | HtmlBlockOpenFrameset = '<' Spnl ("frameset" | "FRAMESET") Spnl HtmlAttribute* '>' | ||||
| 236 | HtmlBlockCloseFrameset = '<' Spnl '/' ("frameset" | "FRAMESET") Spnl '>' | ||||
| 237 | |||||
| 238 | HtmlBlockOpenLi = '<' Spnl ("li" | "LI") Spnl HtmlAttribute* '>' | ||||
| 239 | HtmlBlockCloseLi = '<' Spnl '/' ("li" | "LI") Spnl '>' | ||||
| 240 | |||||
| 241 | HtmlBlockOpenTbody = '<' Spnl ("tbody" | "TBODY") Spnl HtmlAttribute* '>' | ||||
| 242 | HtmlBlockCloseTbody = '<' Spnl '/' ("tbody" | "TBODY") Spnl '>' | ||||
| 243 | |||||
| 244 | HtmlBlockOpenTd = '<' Spnl ("td" | "TD") Spnl HtmlAttribute* '>' | ||||
| 245 | HtmlBlockCloseTd = '<' Spnl '/' ("td" | "TD") Spnl '>' | ||||
| 246 | |||||
| 247 | HtmlBlockOpenTfoot = '<' Spnl ("tfoot" | "TFOOT") Spnl HtmlAttribute* '>' | ||||
| 248 | HtmlBlockCloseTfoot = '<' Spnl '/' ("tfoot" | "TFOOT") Spnl '>' | ||||
| 249 | |||||
| 250 | HtmlBlockOpenTh = '<' Spnl ("th" | "TH") Spnl HtmlAttribute* '>' | ||||
| 251 | HtmlBlockCloseTh = '<' Spnl '/' ("th" | "TH") Spnl '>' | ||||
| 252 | |||||
| 253 | HtmlBlockOpenThead = '<' Spnl ("thead" | "THEAD") Spnl HtmlAttribute* '>' | ||||
| 254 | HtmlBlockCloseThead = '<' Spnl '/' ("thead" | "THEAD") Spnl '>' | ||||
| 255 | |||||
| 256 | HtmlBlockOpenTr = '<' Spnl ("tr" | "TR") Spnl HtmlAttribute* '>' | ||||
| 257 | HtmlBlockCloseTr = '<' Spnl '/' ("tr" | "TR") Spnl '>' | ||||
| 258 | |||||
| 259 | HtmlBlockOpenScript = '<' Spnl ("script" | "SCRIPT") Spnl HtmlAttribute* '>' | ||||
| 260 | HtmlBlockCloseScript = '<' Spnl '/' ("script" | "SCRIPT") Spnl '>' | ||||
| 261 | |||||
| 262 | HtmlBlockInTags = HtmlBlockOpenAddress (HtmlBlockInTags | !HtmlBlockCloseAddress .)* HtmlBlockCloseAddress | ||||
| 263 | | HtmlBlockOpenBlockquote (HtmlBlockInTags | !HtmlBlockCloseBlockquote .)* HtmlBlockCloseBlockquote | ||||
| 264 | | HtmlBlockOpenCenter (HtmlBlockInTags | !HtmlBlockCloseCenter .)* HtmlBlockCloseCenter | ||||
| 265 | | HtmlBlockOpenDir (HtmlBlockInTags | !HtmlBlockCloseDir .)* HtmlBlockCloseDir | ||||
| 266 | | HtmlBlockOpenDiv (HtmlBlockInTags | !HtmlBlockCloseDiv .)* HtmlBlockCloseDiv | ||||
| 267 | | HtmlBlockOpenDl (HtmlBlockInTags | !HtmlBlockCloseDl .)* HtmlBlockCloseDl | ||||
| 268 | | HtmlBlockOpenFieldset (HtmlBlockInTags | !HtmlBlockCloseFieldset .)* HtmlBlockCloseFieldset | ||||
| 269 | | HtmlBlockOpenForm (HtmlBlockInTags | !HtmlBlockCloseForm .)* HtmlBlockCloseForm | ||||
| 270 | | HtmlBlockOpenH1 (HtmlBlockInTags | !HtmlBlockCloseH1 .)* HtmlBlockCloseH1 | ||||
| 271 | | HtmlBlockOpenH2 (HtmlBlockInTags | !HtmlBlockCloseH2 .)* HtmlBlockCloseH2 | ||||
| 272 | | HtmlBlockOpenH3 (HtmlBlockInTags | !HtmlBlockCloseH3 .)* HtmlBlockCloseH3 | ||||
| 273 | | HtmlBlockOpenH4 (HtmlBlockInTags | !HtmlBlockCloseH4 .)* HtmlBlockCloseH4 | ||||
| 274 | | HtmlBlockOpenH5 (HtmlBlockInTags | !HtmlBlockCloseH5 .)* HtmlBlockCloseH5 | ||||
| 275 | | HtmlBlockOpenH6 (HtmlBlockInTags | !HtmlBlockCloseH6 .)* HtmlBlockCloseH6 | ||||
| 276 | | HtmlBlockOpenMenu (HtmlBlockInTags | !HtmlBlockCloseMenu .)* HtmlBlockCloseMenu | ||||
| 277 | | HtmlBlockOpenNoframes (HtmlBlockInTags | !HtmlBlockCloseNoframes .)* HtmlBlockCloseNoframes | ||||
| 278 | | HtmlBlockOpenNoscript (HtmlBlockInTags | !HtmlBlockCloseNoscript .)* HtmlBlockCloseNoscript | HtmlBlockOpenOl (HtmlBlockInTags | !HtmlBlockCloseOl .)* HtmlBlockCloseOl | ||||
| 279 | | HtmlBlockOpenP (HtmlBlockInTags | !HtmlBlockCloseP .)* HtmlBlockCloseP | ||||
| 280 | | HtmlBlockOpenPre (HtmlBlockInTags | !HtmlBlockClosePre .)* HtmlBlockClosePre | ||||
| 281 | | HtmlBlockOpenTable (HtmlBlockInTags | !HtmlBlockCloseTable .)* HtmlBlockCloseTable | ||||
| 282 | | HtmlBlockOpenUl (HtmlBlockInTags | !HtmlBlockCloseUl .)* HtmlBlockCloseUl | ||||
| 283 | | HtmlBlockOpenDd (HtmlBlockInTags | !HtmlBlockCloseDd .)* HtmlBlockCloseDd | ||||
| 284 | | HtmlBlockOpenDt (HtmlBlockInTags | !HtmlBlockCloseDt .)* HtmlBlockCloseDt | ||||
| 285 | | HtmlBlockOpenFrameset (HtmlBlockInTags | !HtmlBlockCloseFrameset .)* HtmlBlockCloseFrameset | ||||
| 286 | | HtmlBlockOpenLi (HtmlBlockInTags | !HtmlBlockCloseLi .)* HtmlBlockCloseLi | ||||
| 287 | | HtmlBlockOpenTbody (HtmlBlockInTags | !HtmlBlockCloseTbody .)* HtmlBlockCloseTbody | ||||
| 288 | | HtmlBlockOpenTd (HtmlBlockInTags | !HtmlBlockCloseTd .)* HtmlBlockCloseTd | ||||
| 289 | | HtmlBlockOpenTfoot (HtmlBlockInTags | !HtmlBlockCloseTfoot .)* HtmlBlockCloseTfoot | ||||
| 290 | | HtmlBlockOpenTh (HtmlBlockInTags | !HtmlBlockCloseTh .)* HtmlBlockCloseTh | ||||
| 291 | | HtmlBlockOpenThead (HtmlBlockInTags | !HtmlBlockCloseThead .)* HtmlBlockCloseThead | ||||
| 292 | | HtmlBlockOpenTr (HtmlBlockInTags | !HtmlBlockCloseTr .)* HtmlBlockCloseTr | ||||
| 293 | | HtmlBlockOpenScript (HtmlBlockInTags | !HtmlBlockCloseScript .)* HtmlBlockCloseScript | ||||
| 294 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 295 | HtmlBlock = < ( HtmlBlockInTags | HtmlComment | HtmlBlockSelfClosing ) > | |
| efdfaee1 » | jgm | 2008-05-06 | 296 | BlankLine+ | |
| e6d9fad9 » | jgm | 2008-07-16 | 297 | { if (extension(EXT_FILTER_HTML)) { | |
| 298 | $$ = mk_list(LIST, NULL); | ||||
| 299 | } else { | ||||
| 300 | $$ = mk_str(yytext); | ||||
| 301 | $$->key = HTMLBLOCK; | ||||
| 302 | } | ||||
| 303 | } | ||||
| ff582f78 » | jgm | 2008-05-05 | 304 | ||
| 305 | HtmlBlockSelfClosing = '<' Spnl HtmlBlockType Spnl HtmlAttribute* '/' Spnl '>' | ||||
| 306 | |||||
| 307 | HtmlBlockType = "address" | "blockquote" | "center" | "dir" | "div" | "dl" | "fieldset" | "form" | "h1" | "h2" | "h3" | | ||||
| 308 | "h4" | "h5" | "h6" | "hr" | "isindex" | "menu" | "noframes" | "noscript" | "ol" | "p" | "pre" | "table" | | ||||
| 309 | "ul" | "dd" | "dt" | "frameset" | "li" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "script" | | ||||
| 310 | "ADDRESS" | "BLOCKQUOTE" | "CENTER" | "DIR" | "DIV" | "DL" | "FIELDSET" | "FORM" | "H1" | "H2" | "H3" | | ||||
| 311 | "H4" | "H5" | "H6" | "HR" | "ISINDEX" | "MENU" | "NOFRAMES" | "NOSCRIPT" | "OL" | "P" | "PRE" | "TABLE" | | ||||
| 312 | "UL" | "DD" | "DT" | "FRAMESET" | "LI" | "TBODY" | "TD" | "TFOOT" | "TH" | "THEAD" | "TR" | "SCRIPT" | ||||
| 313 | |||||
| 51ea8667 » | jgm | 2008-07-16 | 314 | StyleOpen = '<' Spnl ("style" | "STYLE") Spnl HtmlAttribute* '>' | |
| 315 | StyleClose = '<' Spnl '/' ("style" | "STYLE") Spnl '>' | ||||
| 316 | InStyleTags = StyleOpen (!StyleClose .)* StyleClose | ||||
| 317 | StyleBlock = < InStyleTags > | ||||
| 318 | BlankLine* | ||||
| 319 | { if (extension(EXT_FILTER_STYLES)) { | ||||
| 320 | $$ = mk_list(LIST, NULL); | ||||
| 321 | } else { | ||||
| 322 | $$ = mk_str(yytext); | ||||
| 323 | $$->key = HTMLBLOCK; | ||||
| 324 | } | ||||
| 325 | } | ||||
| 326 | |||||
| 2a7ef09f » | jgm | 2008-06-12 | 327 | Inlines = a:StartList ( !Endline Inline { a = cons($$, a); } | |
| 328 | | c:Endline &Inline { a = cons(c, a); } )+ Endline? | ||||
| ff582f78 » | jgm | 2008-05-05 | 329 | { $$ = mk_list(LIST, a); } | |
| 330 | |||||
| 331 | Inline = Str | ||||
| 332 | | Endline | ||||
| 0162c4ca » | jgm | 2008-06-17 | 333 | | UlOrStarLine | |
| 22058c5a » | jgm | 2008-06-18 | 334 | | Space | |
| ff582f78 » | jgm | 2008-05-05 | 335 | | Strong | |
| 336 | | Emph | ||||
| 337 | | Image | ||||
| 338 | | Link | ||||
| 10bca596 » | jgm | 2008-05-10 | 339 | | NoteReference | |
| 340 | | InlineNote | ||||
| ff582f78 » | jgm | 2008-05-05 | 341 | | Code | |
| 342 | | RawHtml | ||||
| 343 | | Entity | ||||
| 344 | | EscapedChar | ||||
| 66c29ef9 » | jgm | 2008-05-06 | 345 | | Smart | |
| ff582f78 » | jgm | 2008-05-05 | 346 | | Symbol | |
| 347 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 348 | Space = Spacechar+ | |
| ce774f0d » | jgm | 2008-06-11 | 349 | { $$ = mk_str(" "); | |
| 350 | $$->key = SPACE; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 351 | ||
| 3ac63587 » | jgm | 2008-06-09 | 352 | Str = < NormalChar+ > | |
| ff582f78 » | jgm | 2008-05-05 | 353 | { $$ = mk_str(yytext); } | |
| 354 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 355 | EscapedChar = '\\' !Newline < . > | |
| ff582f78 » | jgm | 2008-05-05 | 356 | { $$ = mk_str(yytext); } | |
| 357 | |||||
| 358 | Entity = ( HexEntity | DecEntity | CharEntity ) | ||||
| 332b562e » | jgm | 2008-06-09 | 359 | { $$ = mk_str(yytext); $$->key = HTML; } | |
| ff582f78 » | jgm | 2008-05-05 | 360 | ||
| c731b2d0 » | jgm | 2008-11-17 | 361 | Endline = LineBreak | TerminalEndline | NormalEndline | |
| ff582f78 » | jgm | 2008-05-05 | 362 | ||
| 1c0c0782 » | jgm | 2009-01-19 | 363 | NormalEndline = Sp Newline !BlankLine !'>' !AtxStart | |
| 467b8f63 » | jgm | 2008-05-15 | 364 | !(Line ("===" '='* | "---" '-'*) Newline) | |
| ce774f0d » | jgm | 2008-06-11 | 365 | { $$ = mk_str("\n"); | |
| 366 | $$->key = SPACE; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 367 | ||
| 368 | TerminalEndline = Sp Newline Eof | ||||
| f27569f1 » | jgm | 2008-06-11 | 369 | { $$ = NULL; } | |
| ff582f78 » | jgm | 2008-05-05 | 370 | ||
| c731b2d0 » | jgm | 2008-11-17 | 371 | LineBreak = " " NormalEndline | |
| e830bade » | jgm | 2008-06-08 | 372 | { $$ = mk_element(LINEBREAK); } | |
| ff582f78 » | jgm | 2008-05-05 | 373 | ||
| 3ac63587 » | jgm | 2008-06-09 | 374 | Symbol = < SpecialChar > | |
| ff582f78 » | jgm | 2008-05-05 | 375 | { $$ = mk_str(yytext); } | |
| 376 | |||||
| 22058c5a » | jgm | 2008-06-18 | 377 | # This keeps the parser from getting bogged down on long strings of '*' or '_', | |
| 378 | # or strings of '*' or '_' with space on each side: | ||||
| 8b016317 » | jgm | 2009-11-30 | 379 | UlOrStarLine = (UlLine | StarLine) { $$ = mk_str(yytext); } | |
| 656f5c30 » | jgm | 2008-07-23 | 380 | StarLine = < "****" '*'* > | < Spacechar '*'+ &Spacechar > | |
| 381 | UlLine = < "____" '_'* > | < Spacechar '_'+ &Spacechar > | ||||
| 0162c4ca » | jgm | 2008-06-17 | 382 | ||
| ff582f78 » | jgm | 2008-05-05 | 383 | Emph = EmphStar | EmphUl | |
| 384 | |||||
| 0162c4ca » | jgm | 2008-06-17 | 385 | OneStarOpen = !StarLine '*' !Spacechar !Newline | |
| 386 | OneStarClose = !Spacechar !Newline a:Inline !StrongStar '*' { $$ = a; } | ||||
| 5ac4b233 » | jgm | 2008-06-16 | 387 | ||
| 388 | EmphStar = OneStarOpen | ||||
| ff582f78 » | jgm | 2008-05-05 | 389 | a:StartList | |
| 5ac4b233 » | jgm | 2008-06-16 | 390 | ( !OneStarClose Inline { a = cons($$, a); } )* | |
| 391 | OneStarClose { a = cons($$, a); } | ||||
| ff582f78 » | jgm | 2008-05-05 | 392 | { $$ = mk_list(EMPH, a); } | |
| 393 | |||||
| 0162c4ca » | jgm | 2008-06-17 | 394 | OneUlOpen = !UlLine '_' !Spacechar !Newline | |
| 395 | OneUlClose = !Spacechar !Newline a:Inline !StrongUl '_' !Alphanumeric { $$ = a; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 396 | ||
| 5ac4b233 » | jgm | 2008-06-16 | 397 | EmphUl = OneUlOpen | |
| ff582f78 » | jgm | 2008-05-05 | 398 | a:StartList | |
| 5ac4b233 » | jgm | 2008-06-16 | 399 | ( !OneUlClose Inline { a = cons($$, a); } )* | |
| 400 | OneUlClose { a = cons($$, a); } | ||||
| ff582f78 » | jgm | 2008-05-05 | 401 | { $$ = mk_list(EMPH, a); } | |
| 402 | |||||
| 403 | Strong = StrongStar | StrongUl | ||||
| 404 | |||||
| 0162c4ca » | jgm | 2008-06-17 | 405 | TwoStarOpen = !StarLine "**" !Spacechar !Newline | |
| 406 | TwoStarClose = !Spacechar !Newline a:Inline "**" { $$ = a; } | ||||
| 5ac4b233 » | jgm | 2008-06-16 | 407 | ||
| 408 | StrongStar = TwoStarOpen | ||||
| ff582f78 » | jgm | 2008-05-05 | 409 | a:StartList | |
| 5ac4b233 » | jgm | 2008-06-16 | 410 | ( !TwoStarClose Inline { a = cons($$, a); } )* | |
| 411 | TwoStarClose { a = cons($$, a); } | ||||
| ff582f78 » | jgm | 2008-05-05 | 412 | { $$ = mk_list(STRONG, a); } | |
| 413 | |||||
| 0162c4ca » | jgm | 2008-06-17 | 414 | TwoUlOpen = !UlLine "__" !Spacechar !Newline | |
| 415 | TwoUlClose = !Spacechar !Newline a:Inline "__" !Alphanumeric { $$ = a; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 416 | ||
| 5ac4b233 » | jgm | 2008-06-16 | 417 | StrongUl = TwoUlOpen | |
| ff582f78 » | jgm | 2008-05-05 | 418 | a:StartList | |
| 5ac4b233 » | jgm | 2008-06-16 | 419 | ( !TwoUlClose Inline { a = cons($$, a); } )* | |
| 420 | TwoUlClose { a = cons($$, a); } | ||||
| ff582f78 » | jgm | 2008-05-05 | 421 | { $$ = mk_list(STRONG, a); } | |
| 422 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 423 | Image = '!' ( ExplicitLink | ReferenceLink ) | |
| 332b562e » | jgm | 2008-06-09 | 424 | { $$->key = IMAGE; } | |
| ff582f78 » | jgm | 2008-05-05 | 425 | ||
| 426 | Link = ExplicitLink | ReferenceLink | AutoLink | ||||
| 427 | |||||
| 428 | ReferenceLink = ReferenceLinkDouble | ReferenceLinkSingle | ||||
| 429 | |||||
| 69e99275 » | jgm | 2008-05-15 | 430 | ReferenceLinkDouble = a:Label < Spnl > !"[]" b:Label | |
| ff582f78 » | jgm | 2008-05-05 | 431 | { link match; | |
| 88bcde61 » | jgm | 2008-06-11 | 432 | if (find_reference(&match, b->children)) { | |
| 332b562e » | jgm | 2008-06-09 | 433 | $$ = mk_link(a->children, match.url, match.title); | |
| 88bcde61 » | jgm | 2008-06-11 | 434 | free(a); | |
| 435 | free_element_list(b); | ||||
| 436 | } else { | ||||
| 332b562e » | jgm | 2008-06-09 | 437 | element *result; | |
| 438 | result = mk_element(LIST); | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 439 | result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), cons(mk_str(yytext), | |
| 440 | cons(mk_str("["), cons(b, mk_str("]"))))))); | ||||
| 332b562e » | jgm | 2008-06-09 | 441 | $$ = result; | |
| ff582f78 » | jgm | 2008-05-05 | 442 | } | |
| 443 | } | ||||
| 444 | |||||
| 445 | ReferenceLinkSingle = a:Label < (Spnl "[]")? > | ||||
| 446 | { link match; | ||||
| 332b562e » | jgm | 2008-06-09 | 447 | if (find_reference(&match, a->children)) { | |
| 448 | $$ = mk_link(a->children, match.url, match.title); | ||||
| 88bcde61 » | jgm | 2008-06-11 | 449 | free(a); | |
| 3ac63587 » | jgm | 2008-06-09 | 450 | } | |
| ff582f78 » | jgm | 2008-05-05 | 451 | else { | |
| 332b562e » | jgm | 2008-06-09 | 452 | element *result; | |
| 453 | result = mk_element(LIST); | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 454 | result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), mk_str(yytext)))); | |
| 332b562e » | jgm | 2008-06-09 | 455 | $$ = result; | |
| ff582f78 » | jgm | 2008-05-05 | 456 | } | |
| 457 | } | ||||
| 458 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 459 | ExplicitLink = l:Label Spnl '(' Sp s:Source Spnl t:Title Sp ')' | |
| bd230235 » | jgm | 2008-06-11 | 460 | { $$ = mk_link(l->children, s->contents.str, t->contents.str); | |
| 461 | free_element(s); | ||||
| 462 | free_element(t); | ||||
| 463 | free(l); } | ||||
| ff582f78 » | jgm | 2008-05-05 | 464 | ||
| 465 | Source = ( '<' < SourceContents > '>' | < SourceContents > ) | ||||
| 466 | { $$ = mk_str(yytext); } | ||||
| 467 | |||||
| 69e99275 » | jgm | 2008-05-15 | 468 | SourceContents = ( ( !'(' !')' !'>' Nonspacechar )+ | '(' SourceContents ')')* | |
| 469 | | "" | ||||
| ff582f78 » | jgm | 2008-05-05 | 470 | ||
| 3ac63587 » | jgm | 2008-06-09 | 471 | Title = ( TitleSingle | TitleDouble | < "" > ) | |
| ff582f78 » | jgm | 2008-05-05 | 472 | { $$ = mk_str(yytext); } | |
| 473 | |||||
| 474 | TitleSingle = '\'' < ( !( '\'' Sp ( ')' | Newline ) ) !Newline . )* > '\'' | ||||
| 475 | |||||
| 476 | TitleDouble = '"' < ( !( '"' Sp ( ')' | Newline ) ) !Newline . )* > '"' | ||||
| 477 | |||||
| 478 | AutoLink = AutoLinkUrl | AutoLinkEmail | ||||
| 479 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 480 | AutoLinkUrl = '<' < [A-Za-z]+ "://" ( !Newline !'>' . )+ > '>' | |
| af5e1366 » | jgm | 2008-06-11 | 481 | { $$ = mk_link(mk_str(yytext), yytext, ""); } | |
| ff582f78 » | jgm | 2008-05-05 | 482 | ||
| 3ac63587 » | jgm | 2008-06-09 | 483 | AutoLinkEmail = '<' < [-A-Za-z0-9+_]+ '@' ( !Newline !'>' . )+ > '>' | |
| ff582f78 » | jgm | 2008-05-05 | 484 | { char *mailto = malloc(strlen(yytext) + 8); | |
| 485 | sprintf(mailto, "mailto:%s", yytext); | ||||
| af5e1366 » | jgm | 2008-06-11 | 486 | $$ = mk_link(mk_str(yytext), mailto, ""); | |
| 3df086e2 » | jgm | 2008-06-11 | 487 | free(mailto); | |
| 3ac63587 » | jgm | 2008-06-09 | 488 | } | |
| ff582f78 » | jgm | 2008-05-05 | 489 | ||
| 69e99275 » | jgm | 2008-05-15 | 490 | Reference = NonindentSpace !"[]" l:Label ':' Spnl s:RefSrc Spnl t:RefTitle BlankLine* | |
| bd230235 » | jgm | 2008-06-11 | 491 | { $$ = mk_link(l->children, s->contents.str, t->contents.str); | |
| 492 | free_element(s); | ||||
| 493 | free_element(t); | ||||
| 494 | free(l); | ||||
| 495 | $$->key = REFERENCE; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 496 | ||
| 10bca596 » | jgm | 2008-05-10 | 497 | Label = '[' ( !'^' &{ extension(EXT_NOTES) } | &. &{ !extension(EXT_NOTES) } ) | |
| 3ac63587 » | jgm | 2008-06-09 | 498 | a:StartList | |
| 2a7ef09f » | jgm | 2008-06-12 | 499 | ( !']' Inline { a = cons($$, a); } )* | |
| ff582f78 » | jgm | 2008-05-05 | 500 | ']' | |
| 501 | { $$ = mk_list(LIST, a); } | ||||
| 502 | |||||
| bd230235 » | jgm | 2008-06-11 | 503 | RefSrc = < Nonspacechar+ > | |
| 504 | { $$ = mk_str(yytext); | ||||
| 505 | $$->key = HTML; } | ||||
| ff582f78 » | jgm | 2008-05-05 | 506 | ||
| 507 | RefTitle = ( RefTitleSingle | RefTitleDouble | RefTitleParens | EmptyTitle ) | ||||
| 508 | { $$ = mk_str(yytext); } | ||||
| 509 | |||||
| 510 | EmptyTitle = < "" > | ||||
| 511 | |||||
| 512 | RefTitleSingle = '\'' < ( !( '\'' Sp Newline | Newline ) . )* > '\'' | ||||
| 513 | |||||
| 514 | RefTitleDouble = '"' < ( !('"' Sp Newline | Newline) . )* > '"' | ||||
| 515 | |||||
| 516 | RefTitleParens = '(' < ( !(')' Sp Newline | Newline) . )* > ')' | ||||
| 517 | |||||
| 518 | References = a:StartList | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 519 | ( b:Reference { a = cons(b, a); } | SkipBlock )* | |
| 4483b2f8 » | jgm | 2008-06-10 | 520 | { references = reverse(a); } | |
| ff582f78 » | jgm | 2008-05-05 | 521 | ||
| 522 | Ticks1 = "`" | ||||
| 523 | Ticks2 = "``" | ||||
| 524 | Ticks3 = "```" | ||||
| 525 | Ticks4 = "````" | ||||
| 526 | Ticks5 = "`````" | ||||
| 527 | |||||
| b6fa4ff2 » | jgm | 2008-05-08 | 528 | Code = ( Ticks1 Sp < ( ( !'`' Nonspacechar )+ | !Ticks1 '`'+ | !( Sp Ticks1 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks1 | |
| 529 | | Ticks2 Sp < ( ( !'`' Nonspacechar )+ | !Ticks2 '`'+ | !( Sp Ticks2 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks2 | ||||
| 530 | | Ticks3 Sp < ( ( !'`' Nonspacechar )+ | !Ticks3 '`'+ | !( Sp Ticks3 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks3 | ||||
| 531 | | Ticks4 Sp < ( ( !'`' Nonspacechar )+ | !Ticks4 '`'+ | !( Sp Ticks4 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks4 | ||||
| 532 | | Ticks5 Sp < ( ( !'`' Nonspacechar )+ | !Ticks5 '`'+ | !( Sp Ticks5 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks5 | ||||
| 3ac63587 » | jgm | 2008-06-09 | 533 | ) | |
| 332b562e » | jgm | 2008-06-09 | 534 | { $$ = mk_str(yytext); $$->key = CODE; } | |
| ff582f78 » | jgm | 2008-05-05 | 535 | ||
| 536 | RawHtml = < (HtmlComment | HtmlTag) > | ||||
| e6d9fad9 » | jgm | 2008-07-16 | 537 | { if (extension(EXT_FILTER_HTML)) { | |
| 538 | $$ = mk_list(LIST, NULL); | ||||
| 539 | } else { | ||||
| 540 | $$ = mk_str(yytext); | ||||
| 541 | $$->key = HTML; | ||||
| 542 | } | ||||
| 543 | } | ||||
| ff582f78 » | jgm | 2008-05-05 | 544 | ||
| 545 | BlankLine = Sp Newline | ||||
| 546 | |||||
| 547 | Quoted = '"' (!'"' .)* '"' | '\'' (!'\'' .)* '\'' | ||||
| efdfaee1 » | jgm | 2008-05-06 | 548 | HtmlAttribute = (Alphanumeric | '-')+ Spnl ('=' Spnl (Quoted | Nonspacechar+))? Spnl | |
| ff582f78 » | jgm | 2008-05-05 | 549 | HtmlComment = "<!--" (!"-->" .)* "-->" | |
| 550 | HtmlTag = '<' Spnl '/'? Alphanumeric+ Spnl HtmlAttribute* '/'? Spnl '>' | ||||
| 551 | Eof = !. | ||||
| 552 | Spacechar = ' ' | '\t' | ||||
| 553 | Nonspacechar = !Spacechar !Newline . | ||||
| 554 | Newline = '\n' | '\r' '\n'? | ||||
| 555 | Sp = Spacechar* | ||||
| 556 | Spnl = Sp (Newline Sp)? | ||||
| 66c29ef9 » | jgm | 2008-05-06 | 557 | SpecialChar = '*' | '_' | '`' | '&' | '[' | ']' | '<' | '!' | '\\' | ExtendedSpecialChar | |
| 3ac63587 » | jgm | 2008-06-09 | 558 | NormalChar = !( SpecialChar | Spacechar | Newline ) . | |
| ff582f78 » | jgm | 2008-05-05 | 559 | Alphanumeric = [A-Za-z0-9] | |
| 7738d529 » | jgm | 2008-05-08 | 560 | Digit = [0-9] | |
| ff582f78 » | jgm | 2008-05-05 | 561 | ||
| 3ac63587 » | jgm | 2008-06-09 | 562 | HexEntity = < '&' '#' [Xx] [0-9a-fA-F]+ ';' > | |
| ff582f78 » | jgm | 2008-05-05 | 563 | DecEntity = < '&' '#' [0-9]+ > ';' > | |
| 564 | CharEntity = < '&' [A-Za-z0-9]+ ';' > | ||||
| 565 | |||||
| 566 | NonindentSpace = " " | " " | " " | "" | ||||
| 567 | Indent = "\t" | " " | ||||
| 568 | IndentedLine = Indent Line | ||||
| 569 | OptionallyIndentedLine = Indent? Line | ||||
| 570 | |||||
| 2a7ef09f » | jgm | 2008-06-12 | 571 | # StartList starts a list data structure that can be added to with cons: | |
| ff582f78 » | jgm | 2008-05-05 | 572 | StartList = &. | |
| 4483b2f8 » | jgm | 2008-06-10 | 573 | { $$ = NULL; } | |
| ff582f78 » | jgm | 2008-05-05 | 574 | ||
| a7843b7e » | jgm | 2008-06-10 | 575 | Line = RawLine | |
| ff582f78 » | jgm | 2008-05-05 | 576 | { $$ = mk_str(yytext); } | |
| a7843b7e » | jgm | 2008-06-10 | 577 | RawLine = ( < (!'\r' !'\n' .)* Newline > | < .+ > Eof ) | |
| ff582f78 » | jgm | 2008-05-05 | 578 | ||
| a7843b7e » | jgm | 2008-06-10 | 579 | SkipBlock = ( !BlankLine RawLine )+ BlankLine* | |
| ff582f78 » | jgm | 2008-05-05 | 580 | | BlankLine+ | |
| 581 | |||||
| 66c29ef9 » | jgm | 2008-05-06 | 582 | # Syntax extensions | |
| 583 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 584 | ExtendedSpecialChar = &{ extension(EXT_SMART) } ('.' | '-' | '\'' | '"') | |
| 10bca596 » | jgm | 2008-05-10 | 585 | | &{ extension(EXT_NOTES) } ( '^' ) | |
| 66c29ef9 » | jgm | 2008-05-06 | 586 | ||
| 3ac63587 » | jgm | 2008-06-09 | 587 | Smart = &{ extension(EXT_SMART) } | |
| 595a4061 » | jgm | 2008-05-12 | 588 | ( Ellipsis | Dash | SingleQuoted | DoubleQuoted | Apostrophe ) | |
| 589 | |||||
| 590 | Apostrophe = '\'' | ||||
| 591 | { $$ = mk_element(APOSTROPHE); } | ||||
| 66c29ef9 » | jgm | 2008-05-06 | 592 | ||
| 3ac63587 » | jgm | 2008-06-09 | 593 | Ellipsis = ("..." | ". . .") | |
| 595a4061 » | jgm | 2008-05-12 | 594 | { $$ = mk_element(ELLIPSIS); } | |
| 7738d529 » | jgm | 2008-05-08 | 595 | ||
| 596 | Dash = EmDash | EnDash | ||||
| 597 | |||||
| 3ac63587 » | jgm | 2008-06-09 | 598 | EnDash = '-' &Digit | |
| 595a4061 » | jgm | 2008-05-12 | 599 | { $$ = mk_element(ENDASH); } | |
| 7738d529 » | jgm | 2008-05-08 | 600 | ||
| 5d9d2dae » | jgm | 2008-09-01 | 601 | EmDash = ("---" | "--") | |
| 595a4061 » | jgm | 2008-05-12 | 602 | { $$ = mk_element(EMDASH); } | |
| 29d95747 » | jgm | 2008-05-08 | 603 | ||
| 604 | SingleQuoteStart = '\'' ![)!\],.;:-? \t\n] !( ( "s" | "t" | "m" | "ve" | "ll" | "re" ) !Alphanumeric ) | ||||
| 605 | |||||
| 606 | SingleQuoteEnd = '\'' !Alphanumeric | ||||
| 607 | |||||
| 608 | SingleQuoted = SingleQuoteStart | ||||
| 3ac63587 » | jgm | 2008-06-09 | 609 | a:StartList | |
| 2a7ef09f » | jgm | 2008-06-12 | 610 | ( !SingleQuoteEnd b:Inline { a = cons(b, a); } )+ | |
| 29d95747 » | jgm | 2008-05-08 | 611 | SingleQuoteEnd | |
| 3ac63587 » | jgm | 2008-06-09 | 612 | { $$ = mk_list(SINGLEQUOTED, a); } | |
| 29d95747 » | jgm | 2008-05-08 | 613 | ||
| 614 | DoubleQuoteStart = '"' | ||||
| 615 | |||||
| 616 | DoubleQuoteEnd = '"' | ||||
| 617 | |||||
| 618 | DoubleQuoted = DoubleQuoteStart | ||||
| 619 | a:StartList | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 620 | ( !DoubleQuoteEnd b:Inline { a = cons(b, a); } )+ | |
| 29d95747 » | jgm | 2008-05-08 | 621 | DoubleQuoteEnd | |
| 622 | { $$ = mk_list(DOUBLEQUOTED, a); } | ||||
| 66c29ef9 » | jgm | 2008-05-06 | 623 | ||
| 10bca596 » | jgm | 2008-05-10 | 624 | NoteReference = &{ extension(EXT_NOTES) } | |
| 625 | ref:RawNoteReference | ||||
| 626 | { element *match; | ||||
| 332b562e » | jgm | 2008-06-09 | 627 | if (find_note(&match, ref->contents.str)) { | |
| 10bca596 » | jgm | 2008-05-10 | 628 | $$ = mk_element(NOTE); | |
| dcefbbae » | jgm | 2008-05-13 | 629 | assert(match->children != NULL); | |
| 332b562e » | jgm | 2008-06-09 | 630 | $$->children = match->children; | |
| 631 | $$->contents.str = 0; | ||||
| 10bca596 » | jgm | 2008-05-10 | 632 | } else { | |
| 633 | char *s; | ||||
| 332b562e » | jgm | 2008-06-09 | 634 | s = malloc(strlen(ref->contents.str) + 4); | |
| 3df086e2 » | jgm | 2008-06-11 | 635 | sprintf(s, "[^%s]", ref->contents.str); | |
| 10bca596 » | jgm | 2008-05-10 | 636 | $$ = mk_str(s); | |
| 3df086e2 » | jgm | 2008-06-11 | 637 | free(s); | |
| 3ac63587 » | jgm | 2008-06-09 | 638 | } | |
| 10bca596 » | jgm | 2008-05-10 | 639 | } | |
| 640 | |||||
| 641 | RawNoteReference = "[^" < ( !Newline !']' . )+ > ']' | ||||
| 642 | { $$ = mk_str(yytext); } | ||||
| 643 | |||||
| 644 | Note = &{ extension(EXT_NOTES) } | ||||
| 645 | NonindentSpace ref:RawNoteReference ':' Sp | ||||
| 646 | a:StartList | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 647 | ( RawNoteBlock { a = cons($$, a); } ) | |
| 648 | ( &Indent RawNoteBlock { a = cons($$, a); } )* | ||||
| 3ac63587 » | jgm | 2008-06-09 | 649 | { $$ = mk_list(NOTE, a); | |
| 650 | $$->contents.str = strdup(ref->contents.str); | ||||
| 10bca596 » | jgm | 2008-05-10 | 651 | } | |
| 652 | |||||
| 653 | InlineNote = &{ extension(EXT_NOTES) } | ||||
| 654 | "^[" | ||||
| 655 | a:StartList | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 656 | ( !']' Inline { a = cons($$, a); } )+ | |
| 10bca596 » | jgm | 2008-05-10 | 657 | ']' | |
| ce774f0d » | jgm | 2008-06-11 | 658 | { $$ = mk_list(NOTE, a); | |
| 659 | $$->contents.str = 0; } | ||||
| 10bca596 » | jgm | 2008-05-10 | 660 | ||
| 661 | Notes = a:StartList | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 662 | ( b:Note { a = cons(b, a); } | SkipBlock )* | |
| 4483b2f8 » | jgm | 2008-06-10 | 663 | { notes = reverse(a); } | |
| 10bca596 » | jgm | 2008-05-10 | 664 | ||
| 665 | RawNoteBlock = a:StartList | ||||
| 2a7ef09f » | jgm | 2008-06-12 | 666 | ( !BlankLine OptionallyIndentedLine { a = cons($$, a); } )+ | |
| 667 | ( < BlankLine* > { a = cons(mk_str(yytext), a); } ) | ||||
| 4483b2f8 » | jgm | 2008-06-10 | 668 | { $$ = mk_str_from_list(a, true); | |
| 332b562e » | jgm | 2008-06-09 | 669 | $$->key = RAW; | |
| 10bca596 » | jgm | 2008-05-10 | 670 | } | |
| 671 | |||||
| ff582f78 » | jgm | 2008-05-05 | 672 | %% | |
| 673 | |||||
| bea5f65c » | jgm | 2008-06-12 | 674 | #include "parsing_functions.c" | |
| ff582f78 » | jgm | 2008-05-05 | 675 | ||







