├── .gitignore ├── README.md ├── elm-package.json ├── explorer ├── Explorer.elm ├── Style.elm ├── Stylesheets.elm ├── elm-package.json ├── explorer.js ├── index.html ├── post-parser.js └── styles.css ├── package.json └── src └── post.pegjs /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | elm-stuff 3 | node_modules 4 | post-parser.js -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wp-post-grammar 2 | > Working towards a defined unambiguous grammar of WordPress posts and an associated parser. 3 | 4 | ## Contributing 5 | 6 | Please pardon the state of building and contributing as this project is new and started as a demo. 7 | The process for contributing involves updating `src/post.pegjs` for working on the actual grammar 8 | and then building all of the code and checking in the generated code on commit. 9 | We need to rebuild the generated parser so that the interactive explorer updates with the changes. 10 | 11 | ```bash 12 | npm run build:explorer 13 | ``` 14 | 15 | > **Note**: you will need to have Elm installed in order to build this 16 | 17 | ```bash 18 | npm install -g elm@0.18 19 | ``` 20 | 21 | ## Valuable references 22 | 23 | - [HTML5 syntax specification](https://www.w3.org/TR/html5/syntax.html) 24 | -------------------------------------------------------------------------------- /elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "explorer" 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-community/html-extra": "2.2.0 <= v < 3.0.0", 12 | "elm-lang/core": "5.0.0 <= v < 6.0.0", 13 | "elm-lang/html": "2.0.0 <= v < 3.0.0", 14 | "rtfeldman/elm-css": "7.0.0 <= v < 8.0.0", 15 | "rtfeldman/elm-css-helpers": "2.0.1 <= v < 3.0.0" 16 | }, 17 | "elm-version": "0.18.0 <= v < 0.19.0" 18 | } 19 | -------------------------------------------------------------------------------- /explorer/Explorer.elm: -------------------------------------------------------------------------------- 1 | port module Explorer exposing (..) 2 | 3 | import Html exposing (code, div, pre, text, textarea) 4 | import Html.Attributes exposing (style) 5 | import Html.Attributes.Extra exposing (innerHtml) 6 | import Html.Events exposing (onInput) 7 | import Style exposing (class, CssClasses(..)) 8 | 9 | 10 | port submitPost : String -> Cmd msg 11 | 12 | 13 | port receiveParse : (String -> msg) -> Sub msg 14 | 15 | 16 | type Msg 17 | = UpdateInput String 18 | | ReceiveParse String 19 | 20 | 21 | type ParseStatus 22 | = ParseGood 23 | | ParseBad 24 | 25 | 26 | type alias Model = 27 | { input : String 28 | , parse : String 29 | , status : ParseStatus 30 | } 31 | 32 | 33 | update : Msg -> Model -> ( Model, Cmd Msg ) 34 | update msg model = 35 | case msg of 36 | UpdateInput input -> 37 | ( { model 38 | | input = input 39 | , status = ParseBad 40 | } 41 | , submitPost input 42 | ) 43 | 44 | ReceiveParse parse -> 45 | case parse of 46 | "" -> 47 | ( { model | status = ParseBad }, Cmd.none ) 48 | 49 | _ -> 50 | ( { model | parse = parse, status = ParseGood }, Cmd.none ) 51 | 52 | 53 | subscriptions : Model -> Sub Msg 54 | subscriptions model = 55 | receiveParse ReceiveParse 56 | 57 | 58 | statusMessage : ParseStatus -> Html.Html Msg 59 | statusMessage status = 60 | case status of 61 | ParseGood -> 62 | div [ class [ ParseGood ] ] [ text "Complete parse" ] 63 | 64 | ParseBad -> 65 | div [ class [ ParseBad ] ] [ text "No valid parse" ] 66 | 67 | 68 | highlightClass : ParseStatus -> List CssClasses 69 | highlightClass status = 70 | case status of 71 | ParseGood -> 72 | [] 73 | 74 | ParseBad -> 75 | [ NoHighlight ] 76 | 77 | 78 | view : Model -> Html.Html Msg 79 | view { input, parse, status } = 80 | div 81 | [ class [ Layout ] ] 82 | [ div 83 | [ style 84 | [ ( "flex", "1 0 0" ) 85 | , ( "min-width", "50%" ) 86 | ] 87 | ] 88 | [ textarea 89 | [ class [ InputPane ] 90 | , onInput UpdateInput 91 | ] 92 | [ text input ] 93 | ] 94 | , div 95 | [ style 96 | [ ( "flex", "1 0 0" ) 97 | ] 98 | ] 99 | [ div [] [ statusMessage status ] 100 | , pre 101 | [ highlightClass status 102 | |> List.append 103 | [ OutputPane 104 | ] 105 | |> class 106 | ] 107 | [ code [ innerHtml parse ] [] ] 108 | ] 109 | ] 110 | 111 | 112 | main : Program Never Model Msg 113 | main = 114 | Html.program 115 | { init = ( Model initialInput "" ParseBad, submitPost initialInput ) 116 | , update = update 117 | , subscriptions = subscriptions 118 | , view = view 119 | } 120 | 121 | 122 | initialInput : String 123 | initialInput = 124 | """ 125 | Content 126 | 127 | 128 | ### Text 129 | 130 | The quick brown fox jumps over the lazy dog. 131 | 132 | 133 | 134 |

The quick brown fox jumps over the lazy dog.

135 | 136 | 137 | 138 |

The quick brown fox jumps over the lazy dog.

139 | 140 | 141 | ### Image 142 | 143 | 144 | 145 | 146 | 147 |
148 | 149 |
150 | 151 | 152 | ### Image with caption 153 | 154 | [caption] A picture is worth a thousand words.[/caption] 155 | 156 | 157 | 158 |
159 | 160 |
A picture is worth a thousand words.
161 |
162 | 163 | 164 | ### Quote 165 | 166 |
167 |

The quick brown fox jumps over the lazy dog.

168 | 169 |
170 | 171 | 172 | ### HTML 173 | 174 |
175 | 176 |

Look, Ma, canvas!

177 |
178 | """ 179 | -------------------------------------------------------------------------------- /explorer/Style.elm: -------------------------------------------------------------------------------- 1 | module Style exposing (..) 2 | 3 | import Css exposing (..) 4 | import Css.Elements exposing (body) 5 | import Css.Namespace exposing (namespace) 6 | import Html.CssHelpers exposing (withNamespace) 7 | import List exposing (append) 8 | 9 | 10 | { class } = 11 | withNamespace ns 12 | ns : String 13 | ns = 14 | "wppg" 15 | 16 | 17 | type CssClasses 18 | = GrammarPane 19 | | InputPane 20 | | Layout 21 | | NoHighlight 22 | | OutputPane 23 | | ParseBad 24 | | ParseGood 25 | 26 | 27 | css : Stylesheet 28 | css = 29 | (stylesheet << namespace ns) 30 | [ body 31 | [ overflow hidden 32 | ] 33 | , (.) InputPane inputPane 34 | , (.) Layout layout 35 | , (.) NoHighlight 36 | [ noHighlight 37 | , descendants [ everything [ noHighlight ] ] 38 | ] 39 | , (.) OutputPane outputPane 40 | , (.) ParseBad [ color red ] 41 | , (.) ParseGood [ color green ] 42 | ] 43 | 44 | 45 | red : Color 46 | red = 47 | rgb 200 0 0 48 | 49 | 50 | green : Color 51 | green = 52 | rgb 0 128 0 53 | 54 | 55 | inputPane : List Mixin 56 | inputPane = 57 | [ width (pct 95) 58 | , height (pct 100) 59 | , padding (em 1) 60 | , fontFamily monospace 61 | , fontSize (px 16) 62 | ] 63 | 64 | 65 | layout : List Mixin 66 | layout = 67 | [ displayFlex 68 | , flexDirection row 69 | , fontFamily monospace 70 | , fontSize (px 16) 71 | ] 72 | 73 | 74 | outputPane : List Mixin 75 | outputPane = 76 | [ height (pct 90) 77 | , overflow scroll 78 | , padding (em 1) 79 | ] 80 | 81 | 82 | noHighlight : Mixin 83 | noHighlight = 84 | mixin 85 | [ color <| rgb 208 208 208 86 | ] 87 | -------------------------------------------------------------------------------- /explorer/Stylesheets.elm: -------------------------------------------------------------------------------- 1 | port module Stylesheets exposing (..) 2 | 3 | import Css.File exposing (..) 4 | import Style 5 | 6 | 7 | port files : CssFileStructure -> Cmd msg 8 | 9 | 10 | cssFiles : CssFileStructure 11 | cssFiles = 12 | toFileStructure [ ( "styles.css", compile [ Style.css ] ) ] 13 | 14 | 15 | main : Program Never () msg 16 | main = 17 | Platform.program 18 | { init = ( (), files cssFiles ) 19 | , update = \_ _ -> ( (), Cmd.none ) 20 | , subscriptions = \_ -> Sub.none 21 | } 22 | -------------------------------------------------------------------------------- /explorer/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "helpful summary of your project, less than 80 characters", 4 | "repository": "https://github.com/user/project.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "." 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "elm-community/html-extra": "2.2.0 <= v < 3.0.0", 12 | "elm-lang/core": "5.0.0 <= v < 6.0.0", 13 | "elm-lang/html": "2.0.0 <= v < 3.0.0" 14 | }, 15 | "elm-version": "0.18.0 <= v < 0.19.0" 16 | } 17 | -------------------------------------------------------------------------------- /explorer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 23 | 24 | 0) { 106 | for (i = 1, j = 1; i < descriptions.length; i++) { 107 | if (descriptions[i - 1] !== descriptions[i]) { 108 | descriptions[j] = descriptions[i]; 109 | j++; 110 | } 111 | } 112 | descriptions.length = j; 113 | } 114 | 115 | switch (descriptions.length) { 116 | case 1: 117 | return descriptions[0]; 118 | 119 | case 2: 120 | return descriptions[0] + " or " + descriptions[1]; 121 | 122 | default: 123 | return descriptions.slice(0, -1).join(", ") 124 | + ", or " 125 | + descriptions[descriptions.length - 1]; 126 | } 127 | } 128 | 129 | function describeFound(found) { 130 | return found ? "\"" + literalEscape(found) + "\"" : "end of input"; 131 | } 132 | 133 | return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; 134 | }; 135 | 136 | function peg$parse(input, options) { 137 | options = options !== void 0 ? options : {}; 138 | 139 | var peg$FAILED = {}, 140 | 141 | peg$startRuleFunctions = { Document: peg$parseDocument }, 142 | peg$startRuleFunction = peg$parseDocument, 143 | 144 | peg$c0 = function(ts) { return { 145 | type: 'Text', 146 | value: ts 147 | } }, 148 | peg$c1 = /^[^<]/, 149 | peg$c2 = peg$classExpectation(["<"], true, false), 150 | peg$c3 = function(s, t) { return t }, 151 | peg$c4 = function(s, children, e) { return { 152 | type: 'WP_Block', 153 | blockType: s.blockType, 154 | attrs: orAsJSON( s.attrs ), 155 | rawContent: text(), 156 | children 157 | } }, 158 | peg$c5 = "", 163 | peg$c10 = peg$literalExpectation("-->", false), 164 | peg$c11 = function(blockType, attrs) { return { 165 | type: 'WP_Block_Start', 166 | blockType, 167 | attrs 168 | } }, 169 | peg$c12 = "/wp", 170 | peg$c13 = peg$literalExpectation("/wp", false), 171 | peg$c14 = function() { return { 172 | type: 'WP_Block_End' 173 | } }, 174 | peg$c15 = "/", 175 | peg$c16 = peg$literalExpectation("/", false), 176 | peg$c17 = peg$anyExpectation(), 177 | peg$c18 = function(c) { return c }, 178 | peg$c19 = function(cs) { return { 179 | type: "HTML_Comment", 180 | innerText: cs.join('') 181 | } }, 182 | peg$c20 = function(t) { return undefined !== { 183 | 'br': true, 184 | 'col': true, 185 | 'embed': true, 186 | 'hr': true, 187 | 'img': true, 188 | 'input': true 189 | }[ t.name.toLowerCase() ] }, 190 | peg$c21 = function(t) { return { 191 | type: 'HTML_Void_Tag', 192 | name: t.name, 193 | attrs: t.attrs 194 | } }, 195 | peg$c22 = function(s, ct) { return s.name === ct.name }, 196 | peg$c23 = function(s, children, e) { return s.name === e.name }, 197 | peg$c24 = function(s, children, e) { return { 198 | type: 'HTML_Tag', 199 | name: s.name, 200 | attrs: s.attrs, 201 | children 202 | } }, 203 | peg$c25 = "<", 204 | peg$c26 = peg$literalExpectation("<", false), 205 | peg$c27 = ">", 206 | peg$c28 = peg$literalExpectation(">", false), 207 | peg$c29 = function(name, attrs) { return { 208 | type: 'HTML_Tag_Open', 209 | name, 210 | attrs 211 | } }, 212 | peg$c30 = " Object.assign( 220 | attrs, 221 | { [ name ]: value } 222 | ), {} ) }, 223 | peg$c35 = function(name) { return [ name, true ] }, 224 | peg$c36 = "=", 225 | peg$c37 = peg$literalExpectation("=", false), 226 | peg$c38 = /^[a-zA-Z0-9]/, 227 | peg$c39 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"]], false, false), 228 | peg$c40 = function(name, value) { return [ name, value ] }, 229 | peg$c41 = "\"", 230 | peg$c42 = peg$literalExpectation("\"", false), 231 | peg$c43 = "'", 232 | peg$c44 = peg$literalExpectation("'", false), 233 | peg$c45 = /^[a-zA-Z0-9:.]/, 234 | peg$c46 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], ":", "."], false, false), 235 | peg$c47 = /^[a-zA-Z]/, 236 | peg$c48 = peg$classExpectation([["a", "z"], ["A", "Z"]], false, false), 237 | peg$c49 = /^[0-9]/, 238 | peg$c50 = peg$classExpectation([["0", "9"]], false, false), 239 | peg$c51 = /^[\r\n]/, 240 | peg$c52 = peg$classExpectation(["\r", "\n"], false, false), 241 | peg$c53 = /^[ \t]/, 242 | peg$c54 = peg$classExpectation([" ", "\t"], false, false), 243 | 244 | peg$currPos = 0, 245 | peg$savedPos = 0, 246 | peg$posDetailsCache = [{ line: 1, column: 1 }], 247 | peg$maxFailPos = 0, 248 | peg$maxFailExpected = [], 249 | peg$silentFails = 0, 250 | 251 | peg$result; 252 | 253 | if ("startRule" in options) { 254 | if (!(options.startRule in peg$startRuleFunctions)) { 255 | throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); 256 | } 257 | 258 | peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; 259 | } 260 | 261 | function text() { 262 | return input.substring(peg$savedPos, peg$currPos); 263 | } 264 | 265 | function location() { 266 | return peg$computeLocation(peg$savedPos, peg$currPos); 267 | } 268 | 269 | function expected(description, location) { 270 | location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos) 271 | 272 | throw peg$buildStructuredError( 273 | [peg$otherExpectation(description)], 274 | input.substring(peg$savedPos, peg$currPos), 275 | location 276 | ); 277 | } 278 | 279 | function error(message, location) { 280 | location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos) 281 | 282 | throw peg$buildSimpleError(message, location); 283 | } 284 | 285 | function peg$literalExpectation(text, ignoreCase) { 286 | return { type: "literal", text: text, ignoreCase: ignoreCase }; 287 | } 288 | 289 | function peg$classExpectation(parts, inverted, ignoreCase) { 290 | return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; 291 | } 292 | 293 | function peg$anyExpectation() { 294 | return { type: "any" }; 295 | } 296 | 297 | function peg$endExpectation() { 298 | return { type: "end" }; 299 | } 300 | 301 | function peg$otherExpectation(description) { 302 | return { type: "other", description: description }; 303 | } 304 | 305 | function peg$computePosDetails(pos) { 306 | var details = peg$posDetailsCache[pos], p; 307 | 308 | if (details) { 309 | return details; 310 | } else { 311 | p = pos - 1; 312 | while (!peg$posDetailsCache[p]) { 313 | p--; 314 | } 315 | 316 | details = peg$posDetailsCache[p]; 317 | details = { 318 | line: details.line, 319 | column: details.column 320 | }; 321 | 322 | while (p < pos) { 323 | if (input.charCodeAt(p) === 10) { 324 | details.line++; 325 | details.column = 1; 326 | } else { 327 | details.column++; 328 | } 329 | 330 | p++; 331 | } 332 | 333 | peg$posDetailsCache[pos] = details; 334 | return details; 335 | } 336 | } 337 | 338 | function peg$computeLocation(startPos, endPos) { 339 | var startPosDetails = peg$computePosDetails(startPos), 340 | endPosDetails = peg$computePosDetails(endPos); 341 | 342 | return { 343 | start: { 344 | offset: startPos, 345 | line: startPosDetails.line, 346 | column: startPosDetails.column 347 | }, 348 | end: { 349 | offset: endPos, 350 | line: endPosDetails.line, 351 | column: endPosDetails.column 352 | } 353 | }; 354 | } 355 | 356 | function peg$fail(expected) { 357 | if (peg$currPos < peg$maxFailPos) { return; } 358 | 359 | if (peg$currPos > peg$maxFailPos) { 360 | peg$maxFailPos = peg$currPos; 361 | peg$maxFailExpected = []; 362 | } 363 | 364 | peg$maxFailExpected.push(expected); 365 | } 366 | 367 | function peg$buildSimpleError(message, location) { 368 | return new peg$SyntaxError(message, null, null, location); 369 | } 370 | 371 | function peg$buildStructuredError(expected, found, location) { 372 | return new peg$SyntaxError( 373 | peg$SyntaxError.buildMessage(expected, found), 374 | expected, 375 | found, 376 | location 377 | ); 378 | } 379 | 380 | function peg$parseDocument() { 381 | var s0, s1; 382 | 383 | s0 = []; 384 | s1 = peg$parseToken(); 385 | while (s1 !== peg$FAILED) { 386 | s0.push(s1); 387 | s1 = peg$parseToken(); 388 | } 389 | 390 | return s0; 391 | } 392 | 393 | function peg$parseToken() { 394 | var s0, s1, s2, s3; 395 | 396 | s0 = peg$parseWP_Block_Balanced(); 397 | if (s0 === peg$FAILED) { 398 | s0 = peg$parseWP_Block_Start(); 399 | if (s0 === peg$FAILED) { 400 | s0 = peg$parseWP_Block_End(); 401 | if (s0 === peg$FAILED) { 402 | s0 = peg$parseHTML_Comment(); 403 | if (s0 === peg$FAILED) { 404 | s0 = peg$parseHTML_Tag_Void(); 405 | if (s0 === peg$FAILED) { 406 | s0 = peg$parseHTML_Tag_Balanced(); 407 | if (s0 === peg$FAILED) { 408 | s0 = peg$parseHTML_Tag_Open(); 409 | if (s0 === peg$FAILED) { 410 | s0 = peg$parseHTML_Tag_Close(); 411 | if (s0 === peg$FAILED) { 412 | s0 = peg$currPos; 413 | s1 = peg$currPos; 414 | s2 = []; 415 | s3 = peg$parseHTML_Text(); 416 | if (s3 !== peg$FAILED) { 417 | while (s3 !== peg$FAILED) { 418 | s2.push(s3); 419 | s3 = peg$parseHTML_Text(); 420 | } 421 | } else { 422 | s2 = peg$FAILED; 423 | } 424 | if (s2 !== peg$FAILED) { 425 | s1 = input.substring(s1, peg$currPos); 426 | } else { 427 | s1 = s2; 428 | } 429 | if (s1 !== peg$FAILED) { 430 | peg$savedPos = s0; 431 | s1 = peg$c0(s1); 432 | } 433 | s0 = s1; 434 | } 435 | } 436 | } 437 | } 438 | } 439 | } 440 | } 441 | } 442 | 443 | return s0; 444 | } 445 | 446 | function peg$parseHTML_Text() { 447 | var s0; 448 | 449 | if (peg$c1.test(input.charAt(peg$currPos))) { 450 | s0 = input.charAt(peg$currPos); 451 | peg$currPos++; 452 | } else { 453 | s0 = peg$FAILED; 454 | if (peg$silentFails === 0) { peg$fail(peg$c2); } 455 | } 456 | 457 | return s0; 458 | } 459 | 460 | function peg$parseWP_Block_Balanced() { 461 | var s0, s1, s2, s3, s4, s5; 462 | 463 | s0 = peg$currPos; 464 | s1 = peg$parseWP_Block_Start(); 465 | if (s1 !== peg$FAILED) { 466 | s2 = []; 467 | s3 = peg$currPos; 468 | s4 = peg$currPos; 469 | peg$silentFails++; 470 | s5 = peg$parseWP_Block_End(); 471 | peg$silentFails--; 472 | if (s5 === peg$FAILED) { 473 | s4 = void 0; 474 | } else { 475 | peg$currPos = s4; 476 | s4 = peg$FAILED; 477 | } 478 | if (s4 !== peg$FAILED) { 479 | s5 = peg$parseToken(); 480 | if (s5 !== peg$FAILED) { 481 | peg$savedPos = s3; 482 | s4 = peg$c3(s1, s5); 483 | s3 = s4; 484 | } else { 485 | peg$currPos = s3; 486 | s3 = peg$FAILED; 487 | } 488 | } else { 489 | peg$currPos = s3; 490 | s3 = peg$FAILED; 491 | } 492 | if (s3 !== peg$FAILED) { 493 | while (s3 !== peg$FAILED) { 494 | s2.push(s3); 495 | s3 = peg$currPos; 496 | s4 = peg$currPos; 497 | peg$silentFails++; 498 | s5 = peg$parseWP_Block_End(); 499 | peg$silentFails--; 500 | if (s5 === peg$FAILED) { 501 | s4 = void 0; 502 | } else { 503 | peg$currPos = s4; 504 | s4 = peg$FAILED; 505 | } 506 | if (s4 !== peg$FAILED) { 507 | s5 = peg$parseToken(); 508 | if (s5 !== peg$FAILED) { 509 | peg$savedPos = s3; 510 | s4 = peg$c3(s1, s5); 511 | s3 = s4; 512 | } else { 513 | peg$currPos = s3; 514 | s3 = peg$FAILED; 515 | } 516 | } else { 517 | peg$currPos = s3; 518 | s3 = peg$FAILED; 519 | } 520 | } 521 | } else { 522 | s2 = peg$FAILED; 523 | } 524 | if (s2 !== peg$FAILED) { 525 | s3 = peg$parseWP_Block_End(); 526 | if (s3 !== peg$FAILED) { 527 | peg$savedPos = s0; 528 | s1 = peg$c4(s1, s2, s3); 529 | s0 = s1; 530 | } else { 531 | peg$currPos = s0; 532 | s0 = peg$FAILED; 533 | } 534 | } else { 535 | peg$currPos = s0; 536 | s0 = peg$FAILED; 537 | } 538 | } else { 539 | peg$currPos = s0; 540 | s0 = peg$FAILED; 541 | } 542 | 543 | return s0; 544 | } 545 | 546 | function peg$parseWP_Block_Start() { 547 | var s0, s1, s2, s3, s4, s5, s6, s7; 548 | 549 | s0 = peg$currPos; 550 | if (input.substr(peg$currPos, 4) === peg$c5) { 551 | s1 = peg$c5; 552 | peg$currPos += 4; 553 | } else { 554 | s1 = peg$FAILED; 555 | if (peg$silentFails === 0) { peg$fail(peg$c6); } 556 | } 557 | if (s1 !== peg$FAILED) { 558 | s2 = peg$parse__(); 559 | if (s2 !== peg$FAILED) { 560 | if (input.substr(peg$currPos, 3) === peg$c7) { 561 | s3 = peg$c7; 562 | peg$currPos += 3; 563 | } else { 564 | s3 = peg$FAILED; 565 | if (peg$silentFails === 0) { peg$fail(peg$c8); } 566 | } 567 | if (s3 !== peg$FAILED) { 568 | s4 = peg$parseWP_Block_Type(); 569 | if (s4 !== peg$FAILED) { 570 | s5 = peg$parseHTML_Attribute_List(); 571 | if (s5 !== peg$FAILED) { 572 | s6 = peg$parse_(); 573 | if (s6 === peg$FAILED) { 574 | s6 = null; 575 | } 576 | if (s6 !== peg$FAILED) { 577 | if (input.substr(peg$currPos, 3) === peg$c9) { 578 | s7 = peg$c9; 579 | peg$currPos += 3; 580 | } else { 581 | s7 = peg$FAILED; 582 | if (peg$silentFails === 0) { peg$fail(peg$c10); } 583 | } 584 | if (s7 !== peg$FAILED) { 585 | peg$savedPos = s0; 586 | s1 = peg$c11(s4, s5); 587 | s0 = s1; 588 | } else { 589 | peg$currPos = s0; 590 | s0 = peg$FAILED; 591 | } 592 | } else { 593 | peg$currPos = s0; 594 | s0 = peg$FAILED; 595 | } 596 | } else { 597 | peg$currPos = s0; 598 | s0 = peg$FAILED; 599 | } 600 | } else { 601 | peg$currPos = s0; 602 | s0 = peg$FAILED; 603 | } 604 | } else { 605 | peg$currPos = s0; 606 | s0 = peg$FAILED; 607 | } 608 | } else { 609 | peg$currPos = s0; 610 | s0 = peg$FAILED; 611 | } 612 | } else { 613 | peg$currPos = s0; 614 | s0 = peg$FAILED; 615 | } 616 | 617 | return s0; 618 | } 619 | 620 | function peg$parseWP_Block_End() { 621 | var s0, s1, s2, s3, s4, s5; 622 | 623 | s0 = peg$currPos; 624 | if (input.substr(peg$currPos, 4) === peg$c5) { 625 | s1 = peg$c5; 626 | peg$currPos += 4; 627 | } else { 628 | s1 = peg$FAILED; 629 | if (peg$silentFails === 0) { peg$fail(peg$c6); } 630 | } 631 | if (s1 !== peg$FAILED) { 632 | s2 = peg$parse__(); 633 | if (s2 !== peg$FAILED) { 634 | if (input.substr(peg$currPos, 3) === peg$c12) { 635 | s3 = peg$c12; 636 | peg$currPos += 3; 637 | } else { 638 | s3 = peg$FAILED; 639 | if (peg$silentFails === 0) { peg$fail(peg$c13); } 640 | } 641 | if (s3 !== peg$FAILED) { 642 | s4 = peg$parse__(); 643 | if (s4 !== peg$FAILED) { 644 | if (input.substr(peg$currPos, 3) === peg$c9) { 645 | s5 = peg$c9; 646 | peg$currPos += 3; 647 | } else { 648 | s5 = peg$FAILED; 649 | if (peg$silentFails === 0) { peg$fail(peg$c10); } 650 | } 651 | if (s5 !== peg$FAILED) { 652 | peg$savedPos = s0; 653 | s1 = peg$c14(); 654 | s0 = s1; 655 | } else { 656 | peg$currPos = s0; 657 | s0 = peg$FAILED; 658 | } 659 | } else { 660 | peg$currPos = s0; 661 | s0 = peg$FAILED; 662 | } 663 | } else { 664 | peg$currPos = s0; 665 | s0 = peg$FAILED; 666 | } 667 | } else { 668 | peg$currPos = s0; 669 | s0 = peg$FAILED; 670 | } 671 | } else { 672 | peg$currPos = s0; 673 | s0 = peg$FAILED; 674 | } 675 | 676 | return s0; 677 | } 678 | 679 | function peg$parseWP_Block_Type() { 680 | var s0, s1, s2, s3, s4, s5, s6; 681 | 682 | s0 = peg$currPos; 683 | s1 = peg$currPos; 684 | s2 = peg$parseASCII_Letter(); 685 | if (s2 !== peg$FAILED) { 686 | s3 = []; 687 | s4 = peg$parseASCII_AlphaNumeric(); 688 | if (s4 === peg$FAILED) { 689 | s4 = peg$currPos; 690 | if (input.charCodeAt(peg$currPos) === 47) { 691 | s5 = peg$c15; 692 | peg$currPos++; 693 | } else { 694 | s5 = peg$FAILED; 695 | if (peg$silentFails === 0) { peg$fail(peg$c16); } 696 | } 697 | if (s5 !== peg$FAILED) { 698 | s6 = peg$parseASCII_AlphaNumeric(); 699 | if (s6 !== peg$FAILED) { 700 | s5 = [s5, s6]; 701 | s4 = s5; 702 | } else { 703 | peg$currPos = s4; 704 | s4 = peg$FAILED; 705 | } 706 | } else { 707 | peg$currPos = s4; 708 | s4 = peg$FAILED; 709 | } 710 | } 711 | while (s4 !== peg$FAILED) { 712 | s3.push(s4); 713 | s4 = peg$parseASCII_AlphaNumeric(); 714 | if (s4 === peg$FAILED) { 715 | s4 = peg$currPos; 716 | if (input.charCodeAt(peg$currPos) === 47) { 717 | s5 = peg$c15; 718 | peg$currPos++; 719 | } else { 720 | s5 = peg$FAILED; 721 | if (peg$silentFails === 0) { peg$fail(peg$c16); } 722 | } 723 | if (s5 !== peg$FAILED) { 724 | s6 = peg$parseASCII_AlphaNumeric(); 725 | if (s6 !== peg$FAILED) { 726 | s5 = [s5, s6]; 727 | s4 = s5; 728 | } else { 729 | peg$currPos = s4; 730 | s4 = peg$FAILED; 731 | } 732 | } else { 733 | peg$currPos = s4; 734 | s4 = peg$FAILED; 735 | } 736 | } 737 | } 738 | if (s3 !== peg$FAILED) { 739 | s2 = [s2, s3]; 740 | s1 = s2; 741 | } else { 742 | peg$currPos = s1; 743 | s1 = peg$FAILED; 744 | } 745 | } else { 746 | peg$currPos = s1; 747 | s1 = peg$FAILED; 748 | } 749 | if (s1 !== peg$FAILED) { 750 | s0 = input.substring(s0, peg$currPos); 751 | } else { 752 | s0 = s1; 753 | } 754 | 755 | return s0; 756 | } 757 | 758 | function peg$parseHTML_Comment() { 759 | var s0, s1, s2, s3, s4, s5; 760 | 761 | s0 = peg$currPos; 762 | if (input.substr(peg$currPos, 4) === peg$c5) { 763 | s1 = peg$c5; 764 | peg$currPos += 4; 765 | } else { 766 | s1 = peg$FAILED; 767 | if (peg$silentFails === 0) { peg$fail(peg$c6); } 768 | } 769 | if (s1 !== peg$FAILED) { 770 | s2 = []; 771 | s3 = peg$currPos; 772 | s4 = peg$currPos; 773 | peg$silentFails++; 774 | if (input.substr(peg$currPos, 3) === peg$c9) { 775 | s5 = peg$c9; 776 | peg$currPos += 3; 777 | } else { 778 | s5 = peg$FAILED; 779 | if (peg$silentFails === 0) { peg$fail(peg$c10); } 780 | } 781 | peg$silentFails--; 782 | if (s5 === peg$FAILED) { 783 | s4 = void 0; 784 | } else { 785 | peg$currPos = s4; 786 | s4 = peg$FAILED; 787 | } 788 | if (s4 !== peg$FAILED) { 789 | if (input.length > peg$currPos) { 790 | s5 = input.charAt(peg$currPos); 791 | peg$currPos++; 792 | } else { 793 | s5 = peg$FAILED; 794 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 795 | } 796 | if (s5 !== peg$FAILED) { 797 | peg$savedPos = s3; 798 | s4 = peg$c18(s5); 799 | s3 = s4; 800 | } else { 801 | peg$currPos = s3; 802 | s3 = peg$FAILED; 803 | } 804 | } else { 805 | peg$currPos = s3; 806 | s3 = peg$FAILED; 807 | } 808 | while (s3 !== peg$FAILED) { 809 | s2.push(s3); 810 | s3 = peg$currPos; 811 | s4 = peg$currPos; 812 | peg$silentFails++; 813 | if (input.substr(peg$currPos, 3) === peg$c9) { 814 | s5 = peg$c9; 815 | peg$currPos += 3; 816 | } else { 817 | s5 = peg$FAILED; 818 | if (peg$silentFails === 0) { peg$fail(peg$c10); } 819 | } 820 | peg$silentFails--; 821 | if (s5 === peg$FAILED) { 822 | s4 = void 0; 823 | } else { 824 | peg$currPos = s4; 825 | s4 = peg$FAILED; 826 | } 827 | if (s4 !== peg$FAILED) { 828 | if (input.length > peg$currPos) { 829 | s5 = input.charAt(peg$currPos); 830 | peg$currPos++; 831 | } else { 832 | s5 = peg$FAILED; 833 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 834 | } 835 | if (s5 !== peg$FAILED) { 836 | peg$savedPos = s3; 837 | s4 = peg$c18(s5); 838 | s3 = s4; 839 | } else { 840 | peg$currPos = s3; 841 | s3 = peg$FAILED; 842 | } 843 | } else { 844 | peg$currPos = s3; 845 | s3 = peg$FAILED; 846 | } 847 | } 848 | if (s2 !== peg$FAILED) { 849 | if (input.substr(peg$currPos, 3) === peg$c9) { 850 | s3 = peg$c9; 851 | peg$currPos += 3; 852 | } else { 853 | s3 = peg$FAILED; 854 | if (peg$silentFails === 0) { peg$fail(peg$c10); } 855 | } 856 | if (s3 !== peg$FAILED) { 857 | peg$savedPos = s0; 858 | s1 = peg$c19(s2); 859 | s0 = s1; 860 | } else { 861 | peg$currPos = s0; 862 | s0 = peg$FAILED; 863 | } 864 | } else { 865 | peg$currPos = s0; 866 | s0 = peg$FAILED; 867 | } 868 | } else { 869 | peg$currPos = s0; 870 | s0 = peg$FAILED; 871 | } 872 | 873 | return s0; 874 | } 875 | 876 | function peg$parseHTML_Tag_Void() { 877 | var s0, s1, s2; 878 | 879 | s0 = peg$currPos; 880 | s1 = peg$parseHTML_Tag_Open(); 881 | if (s1 !== peg$FAILED) { 882 | peg$savedPos = peg$currPos; 883 | s2 = peg$c20(s1); 884 | if (s2) { 885 | s2 = void 0; 886 | } else { 887 | s2 = peg$FAILED; 888 | } 889 | if (s2 !== peg$FAILED) { 890 | peg$savedPos = s0; 891 | s1 = peg$c21(s1); 892 | s0 = s1; 893 | } else { 894 | peg$currPos = s0; 895 | s0 = peg$FAILED; 896 | } 897 | } else { 898 | peg$currPos = s0; 899 | s0 = peg$FAILED; 900 | } 901 | 902 | return s0; 903 | } 904 | 905 | function peg$parseHTML_Tag_Balanced() { 906 | var s0, s1, s2, s3, s4, s5, s6, s7; 907 | 908 | s0 = peg$currPos; 909 | s1 = peg$parseHTML_Tag_Open(); 910 | if (s1 !== peg$FAILED) { 911 | s2 = []; 912 | s3 = peg$parseHTML_Tag_Balanced(); 913 | if (s3 === peg$FAILED) { 914 | s3 = peg$currPos; 915 | s4 = peg$currPos; 916 | peg$silentFails++; 917 | s5 = peg$currPos; 918 | s6 = peg$parseHTML_Tag_Close(); 919 | if (s6 !== peg$FAILED) { 920 | peg$savedPos = peg$currPos; 921 | s7 = peg$c22(s1, s6); 922 | if (s7) { 923 | s7 = void 0; 924 | } else { 925 | s7 = peg$FAILED; 926 | } 927 | if (s7 !== peg$FAILED) { 928 | s6 = [s6, s7]; 929 | s5 = s6; 930 | } else { 931 | peg$currPos = s5; 932 | s5 = peg$FAILED; 933 | } 934 | } else { 935 | peg$currPos = s5; 936 | s5 = peg$FAILED; 937 | } 938 | peg$silentFails--; 939 | if (s5 === peg$FAILED) { 940 | s4 = void 0; 941 | } else { 942 | peg$currPos = s4; 943 | s4 = peg$FAILED; 944 | } 945 | if (s4 !== peg$FAILED) { 946 | s5 = peg$parseToken(); 947 | if (s5 !== peg$FAILED) { 948 | peg$savedPos = s3; 949 | s4 = peg$c3(s1, s5); 950 | s3 = s4; 951 | } else { 952 | peg$currPos = s3; 953 | s3 = peg$FAILED; 954 | } 955 | } else { 956 | peg$currPos = s3; 957 | s3 = peg$FAILED; 958 | } 959 | } 960 | while (s3 !== peg$FAILED) { 961 | s2.push(s3); 962 | s3 = peg$parseHTML_Tag_Balanced(); 963 | if (s3 === peg$FAILED) { 964 | s3 = peg$currPos; 965 | s4 = peg$currPos; 966 | peg$silentFails++; 967 | s5 = peg$currPos; 968 | s6 = peg$parseHTML_Tag_Close(); 969 | if (s6 !== peg$FAILED) { 970 | peg$savedPos = peg$currPos; 971 | s7 = peg$c22(s1, s6); 972 | if (s7) { 973 | s7 = void 0; 974 | } else { 975 | s7 = peg$FAILED; 976 | } 977 | if (s7 !== peg$FAILED) { 978 | s6 = [s6, s7]; 979 | s5 = s6; 980 | } else { 981 | peg$currPos = s5; 982 | s5 = peg$FAILED; 983 | } 984 | } else { 985 | peg$currPos = s5; 986 | s5 = peg$FAILED; 987 | } 988 | peg$silentFails--; 989 | if (s5 === peg$FAILED) { 990 | s4 = void 0; 991 | } else { 992 | peg$currPos = s4; 993 | s4 = peg$FAILED; 994 | } 995 | if (s4 !== peg$FAILED) { 996 | s5 = peg$parseToken(); 997 | if (s5 !== peg$FAILED) { 998 | peg$savedPos = s3; 999 | s4 = peg$c3(s1, s5); 1000 | s3 = s4; 1001 | } else { 1002 | peg$currPos = s3; 1003 | s3 = peg$FAILED; 1004 | } 1005 | } else { 1006 | peg$currPos = s3; 1007 | s3 = peg$FAILED; 1008 | } 1009 | } 1010 | } 1011 | if (s2 !== peg$FAILED) { 1012 | s3 = peg$parseHTML_Tag_Close(); 1013 | if (s3 !== peg$FAILED) { 1014 | peg$savedPos = peg$currPos; 1015 | s4 = peg$c23(s1, s2, s3); 1016 | if (s4) { 1017 | s4 = void 0; 1018 | } else { 1019 | s4 = peg$FAILED; 1020 | } 1021 | if (s4 !== peg$FAILED) { 1022 | peg$savedPos = s0; 1023 | s1 = peg$c24(s1, s2, s3); 1024 | s0 = s1; 1025 | } else { 1026 | peg$currPos = s0; 1027 | s0 = peg$FAILED; 1028 | } 1029 | } else { 1030 | peg$currPos = s0; 1031 | s0 = peg$FAILED; 1032 | } 1033 | } else { 1034 | peg$currPos = s0; 1035 | s0 = peg$FAILED; 1036 | } 1037 | } else { 1038 | peg$currPos = s0; 1039 | s0 = peg$FAILED; 1040 | } 1041 | 1042 | return s0; 1043 | } 1044 | 1045 | function peg$parseHTML_Tag_Open() { 1046 | var s0, s1, s2, s3, s4, s5; 1047 | 1048 | s0 = peg$currPos; 1049 | if (input.charCodeAt(peg$currPos) === 60) { 1050 | s1 = peg$c25; 1051 | peg$currPos++; 1052 | } else { 1053 | s1 = peg$FAILED; 1054 | if (peg$silentFails === 0) { peg$fail(peg$c26); } 1055 | } 1056 | if (s1 !== peg$FAILED) { 1057 | s2 = peg$parseHTML_Tag_Name(); 1058 | if (s2 !== peg$FAILED) { 1059 | s3 = peg$parseHTML_Attribute_List(); 1060 | if (s3 !== peg$FAILED) { 1061 | s4 = []; 1062 | s5 = peg$parse_(); 1063 | while (s5 !== peg$FAILED) { 1064 | s4.push(s5); 1065 | s5 = peg$parse_(); 1066 | } 1067 | if (s4 !== peg$FAILED) { 1068 | if (input.charCodeAt(peg$currPos) === 62) { 1069 | s5 = peg$c27; 1070 | peg$currPos++; 1071 | } else { 1072 | s5 = peg$FAILED; 1073 | if (peg$silentFails === 0) { peg$fail(peg$c28); } 1074 | } 1075 | if (s5 !== peg$FAILED) { 1076 | peg$savedPos = s0; 1077 | s1 = peg$c29(s2, s3); 1078 | s0 = s1; 1079 | } else { 1080 | peg$currPos = s0; 1081 | s0 = peg$FAILED; 1082 | } 1083 | } else { 1084 | peg$currPos = s0; 1085 | s0 = peg$FAILED; 1086 | } 1087 | } else { 1088 | peg$currPos = s0; 1089 | s0 = peg$FAILED; 1090 | } 1091 | } else { 1092 | peg$currPos = s0; 1093 | s0 = peg$FAILED; 1094 | } 1095 | } else { 1096 | peg$currPos = s0; 1097 | s0 = peg$FAILED; 1098 | } 1099 | 1100 | return s0; 1101 | } 1102 | 1103 | function peg$parseHTML_Tag_Close() { 1104 | var s0, s1, s2, s3, s4; 1105 | 1106 | s0 = peg$currPos; 1107 | if (input.substr(peg$currPos, 2) === peg$c30) { 1108 | s1 = peg$c30; 1109 | peg$currPos += 2; 1110 | } else { 1111 | s1 = peg$FAILED; 1112 | if (peg$silentFails === 0) { peg$fail(peg$c31); } 1113 | } 1114 | if (s1 !== peg$FAILED) { 1115 | s2 = peg$parseHTML_Tag_Name(); 1116 | if (s2 !== peg$FAILED) { 1117 | s3 = []; 1118 | s4 = peg$parse_(); 1119 | while (s4 !== peg$FAILED) { 1120 | s3.push(s4); 1121 | s4 = peg$parse_(); 1122 | } 1123 | if (s3 !== peg$FAILED) { 1124 | if (input.charCodeAt(peg$currPos) === 62) { 1125 | s4 = peg$c27; 1126 | peg$currPos++; 1127 | } else { 1128 | s4 = peg$FAILED; 1129 | if (peg$silentFails === 0) { peg$fail(peg$c28); } 1130 | } 1131 | if (s4 !== peg$FAILED) { 1132 | peg$savedPos = s0; 1133 | s1 = peg$c32(s2); 1134 | s0 = s1; 1135 | } else { 1136 | peg$currPos = s0; 1137 | s0 = peg$FAILED; 1138 | } 1139 | } else { 1140 | peg$currPos = s0; 1141 | s0 = peg$FAILED; 1142 | } 1143 | } else { 1144 | peg$currPos = s0; 1145 | s0 = peg$FAILED; 1146 | } 1147 | } else { 1148 | peg$currPos = s0; 1149 | s0 = peg$FAILED; 1150 | } 1151 | 1152 | return s0; 1153 | } 1154 | 1155 | function peg$parseHTML_Tag_Name() { 1156 | var s0, s1, s2, s3, s4; 1157 | 1158 | s0 = peg$currPos; 1159 | s1 = peg$currPos; 1160 | s2 = peg$parseASCII_Letter(); 1161 | if (s2 !== peg$FAILED) { 1162 | s3 = []; 1163 | s4 = peg$parseASCII_AlphaNumeric(); 1164 | while (s4 !== peg$FAILED) { 1165 | s3.push(s4); 1166 | s4 = peg$parseASCII_AlphaNumeric(); 1167 | } 1168 | if (s3 !== peg$FAILED) { 1169 | s2 = [s2, s3]; 1170 | s1 = s2; 1171 | } else { 1172 | peg$currPos = s1; 1173 | s1 = peg$FAILED; 1174 | } 1175 | } else { 1176 | peg$currPos = s1; 1177 | s1 = peg$FAILED; 1178 | } 1179 | if (s1 !== peg$FAILED) { 1180 | s0 = input.substring(s0, peg$currPos); 1181 | } else { 1182 | s0 = s1; 1183 | } 1184 | 1185 | return s0; 1186 | } 1187 | 1188 | function peg$parseHTML_Attribute_List() { 1189 | var s0, s1, s2, s3, s4; 1190 | 1191 | s0 = peg$currPos; 1192 | s1 = []; 1193 | s2 = peg$currPos; 1194 | s3 = []; 1195 | s4 = peg$parse_(); 1196 | if (s4 !== peg$FAILED) { 1197 | while (s4 !== peg$FAILED) { 1198 | s3.push(s4); 1199 | s4 = peg$parse_(); 1200 | } 1201 | } else { 1202 | s3 = peg$FAILED; 1203 | } 1204 | if (s3 !== peg$FAILED) { 1205 | s4 = peg$parseHTML_Attribute_Item(); 1206 | if (s4 !== peg$FAILED) { 1207 | peg$savedPos = s2; 1208 | s3 = peg$c33(s4); 1209 | s2 = s3; 1210 | } else { 1211 | peg$currPos = s2; 1212 | s2 = peg$FAILED; 1213 | } 1214 | } else { 1215 | peg$currPos = s2; 1216 | s2 = peg$FAILED; 1217 | } 1218 | while (s2 !== peg$FAILED) { 1219 | s1.push(s2); 1220 | s2 = peg$currPos; 1221 | s3 = []; 1222 | s4 = peg$parse_(); 1223 | if (s4 !== peg$FAILED) { 1224 | while (s4 !== peg$FAILED) { 1225 | s3.push(s4); 1226 | s4 = peg$parse_(); 1227 | } 1228 | } else { 1229 | s3 = peg$FAILED; 1230 | } 1231 | if (s3 !== peg$FAILED) { 1232 | s4 = peg$parseHTML_Attribute_Item(); 1233 | if (s4 !== peg$FAILED) { 1234 | peg$savedPos = s2; 1235 | s3 = peg$c33(s4); 1236 | s2 = s3; 1237 | } else { 1238 | peg$currPos = s2; 1239 | s2 = peg$FAILED; 1240 | } 1241 | } else { 1242 | peg$currPos = s2; 1243 | s2 = peg$FAILED; 1244 | } 1245 | } 1246 | if (s1 !== peg$FAILED) { 1247 | peg$savedPos = s0; 1248 | s1 = peg$c34(s1); 1249 | } 1250 | s0 = s1; 1251 | 1252 | return s0; 1253 | } 1254 | 1255 | function peg$parseHTML_Attribute_Item() { 1256 | var s0; 1257 | 1258 | s0 = peg$parseHTML_Attribute_Quoted(); 1259 | if (s0 === peg$FAILED) { 1260 | s0 = peg$parseHTML_Attribute_Unquoted(); 1261 | if (s0 === peg$FAILED) { 1262 | s0 = peg$parseHTML_Attribute_Empty(); 1263 | } 1264 | } 1265 | 1266 | return s0; 1267 | } 1268 | 1269 | function peg$parseHTML_Attribute_Empty() { 1270 | var s0, s1; 1271 | 1272 | s0 = peg$currPos; 1273 | s1 = peg$parseHTML_Attribute_Name(); 1274 | if (s1 !== peg$FAILED) { 1275 | peg$savedPos = s0; 1276 | s1 = peg$c35(s1); 1277 | } 1278 | s0 = s1; 1279 | 1280 | return s0; 1281 | } 1282 | 1283 | function peg$parseHTML_Attribute_Unquoted() { 1284 | var s0, s1, s2, s3, s4, s5, s6, s7; 1285 | 1286 | s0 = peg$currPos; 1287 | s1 = peg$parseHTML_Attribute_Name(); 1288 | if (s1 !== peg$FAILED) { 1289 | s2 = []; 1290 | s3 = peg$parse_(); 1291 | while (s3 !== peg$FAILED) { 1292 | s2.push(s3); 1293 | s3 = peg$parse_(); 1294 | } 1295 | if (s2 !== peg$FAILED) { 1296 | if (input.charCodeAt(peg$currPos) === 61) { 1297 | s3 = peg$c36; 1298 | peg$currPos++; 1299 | } else { 1300 | s3 = peg$FAILED; 1301 | if (peg$silentFails === 0) { peg$fail(peg$c37); } 1302 | } 1303 | if (s3 !== peg$FAILED) { 1304 | s4 = []; 1305 | s5 = peg$parse_(); 1306 | while (s5 !== peg$FAILED) { 1307 | s4.push(s5); 1308 | s5 = peg$parse_(); 1309 | } 1310 | if (s4 !== peg$FAILED) { 1311 | s5 = peg$currPos; 1312 | s6 = []; 1313 | if (peg$c38.test(input.charAt(peg$currPos))) { 1314 | s7 = input.charAt(peg$currPos); 1315 | peg$currPos++; 1316 | } else { 1317 | s7 = peg$FAILED; 1318 | if (peg$silentFails === 0) { peg$fail(peg$c39); } 1319 | } 1320 | if (s7 !== peg$FAILED) { 1321 | while (s7 !== peg$FAILED) { 1322 | s6.push(s7); 1323 | if (peg$c38.test(input.charAt(peg$currPos))) { 1324 | s7 = input.charAt(peg$currPos); 1325 | peg$currPos++; 1326 | } else { 1327 | s7 = peg$FAILED; 1328 | if (peg$silentFails === 0) { peg$fail(peg$c39); } 1329 | } 1330 | } 1331 | } else { 1332 | s6 = peg$FAILED; 1333 | } 1334 | if (s6 !== peg$FAILED) { 1335 | s5 = input.substring(s5, peg$currPos); 1336 | } else { 1337 | s5 = s6; 1338 | } 1339 | if (s5 !== peg$FAILED) { 1340 | peg$savedPos = s0; 1341 | s1 = peg$c40(s1, s5); 1342 | s0 = s1; 1343 | } else { 1344 | peg$currPos = s0; 1345 | s0 = peg$FAILED; 1346 | } 1347 | } else { 1348 | peg$currPos = s0; 1349 | s0 = peg$FAILED; 1350 | } 1351 | } else { 1352 | peg$currPos = s0; 1353 | s0 = peg$FAILED; 1354 | } 1355 | } else { 1356 | peg$currPos = s0; 1357 | s0 = peg$FAILED; 1358 | } 1359 | } else { 1360 | peg$currPos = s0; 1361 | s0 = peg$FAILED; 1362 | } 1363 | 1364 | return s0; 1365 | } 1366 | 1367 | function peg$parseHTML_Attribute_Quoted() { 1368 | var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; 1369 | 1370 | s0 = peg$currPos; 1371 | s1 = peg$parseHTML_Attribute_Name(); 1372 | if (s1 !== peg$FAILED) { 1373 | s2 = []; 1374 | s3 = peg$parse_(); 1375 | while (s3 !== peg$FAILED) { 1376 | s2.push(s3); 1377 | s3 = peg$parse_(); 1378 | } 1379 | if (s2 !== peg$FAILED) { 1380 | if (input.charCodeAt(peg$currPos) === 61) { 1381 | s3 = peg$c36; 1382 | peg$currPos++; 1383 | } else { 1384 | s3 = peg$FAILED; 1385 | if (peg$silentFails === 0) { peg$fail(peg$c37); } 1386 | } 1387 | if (s3 !== peg$FAILED) { 1388 | s4 = []; 1389 | s5 = peg$parse_(); 1390 | while (s5 !== peg$FAILED) { 1391 | s4.push(s5); 1392 | s5 = peg$parse_(); 1393 | } 1394 | if (s4 !== peg$FAILED) { 1395 | if (input.charCodeAt(peg$currPos) === 34) { 1396 | s5 = peg$c41; 1397 | peg$currPos++; 1398 | } else { 1399 | s5 = peg$FAILED; 1400 | if (peg$silentFails === 0) { peg$fail(peg$c42); } 1401 | } 1402 | if (s5 !== peg$FAILED) { 1403 | s6 = peg$currPos; 1404 | s7 = []; 1405 | s8 = peg$currPos; 1406 | s9 = peg$currPos; 1407 | peg$silentFails++; 1408 | if (input.charCodeAt(peg$currPos) === 34) { 1409 | s10 = peg$c41; 1410 | peg$currPos++; 1411 | } else { 1412 | s10 = peg$FAILED; 1413 | if (peg$silentFails === 0) { peg$fail(peg$c42); } 1414 | } 1415 | peg$silentFails--; 1416 | if (s10 === peg$FAILED) { 1417 | s9 = void 0; 1418 | } else { 1419 | peg$currPos = s9; 1420 | s9 = peg$FAILED; 1421 | } 1422 | if (s9 !== peg$FAILED) { 1423 | if (input.length > peg$currPos) { 1424 | s10 = input.charAt(peg$currPos); 1425 | peg$currPos++; 1426 | } else { 1427 | s10 = peg$FAILED; 1428 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 1429 | } 1430 | if (s10 !== peg$FAILED) { 1431 | s9 = [s9, s10]; 1432 | s8 = s9; 1433 | } else { 1434 | peg$currPos = s8; 1435 | s8 = peg$FAILED; 1436 | } 1437 | } else { 1438 | peg$currPos = s8; 1439 | s8 = peg$FAILED; 1440 | } 1441 | while (s8 !== peg$FAILED) { 1442 | s7.push(s8); 1443 | s8 = peg$currPos; 1444 | s9 = peg$currPos; 1445 | peg$silentFails++; 1446 | if (input.charCodeAt(peg$currPos) === 34) { 1447 | s10 = peg$c41; 1448 | peg$currPos++; 1449 | } else { 1450 | s10 = peg$FAILED; 1451 | if (peg$silentFails === 0) { peg$fail(peg$c42); } 1452 | } 1453 | peg$silentFails--; 1454 | if (s10 === peg$FAILED) { 1455 | s9 = void 0; 1456 | } else { 1457 | peg$currPos = s9; 1458 | s9 = peg$FAILED; 1459 | } 1460 | if (s9 !== peg$FAILED) { 1461 | if (input.length > peg$currPos) { 1462 | s10 = input.charAt(peg$currPos); 1463 | peg$currPos++; 1464 | } else { 1465 | s10 = peg$FAILED; 1466 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 1467 | } 1468 | if (s10 !== peg$FAILED) { 1469 | s9 = [s9, s10]; 1470 | s8 = s9; 1471 | } else { 1472 | peg$currPos = s8; 1473 | s8 = peg$FAILED; 1474 | } 1475 | } else { 1476 | peg$currPos = s8; 1477 | s8 = peg$FAILED; 1478 | } 1479 | } 1480 | if (s7 !== peg$FAILED) { 1481 | s6 = input.substring(s6, peg$currPos); 1482 | } else { 1483 | s6 = s7; 1484 | } 1485 | if (s6 !== peg$FAILED) { 1486 | if (input.charCodeAt(peg$currPos) === 34) { 1487 | s7 = peg$c41; 1488 | peg$currPos++; 1489 | } else { 1490 | s7 = peg$FAILED; 1491 | if (peg$silentFails === 0) { peg$fail(peg$c42); } 1492 | } 1493 | if (s7 !== peg$FAILED) { 1494 | peg$savedPos = s0; 1495 | s1 = peg$c40(s1, s6); 1496 | s0 = s1; 1497 | } else { 1498 | peg$currPos = s0; 1499 | s0 = peg$FAILED; 1500 | } 1501 | } else { 1502 | peg$currPos = s0; 1503 | s0 = peg$FAILED; 1504 | } 1505 | } else { 1506 | peg$currPos = s0; 1507 | s0 = peg$FAILED; 1508 | } 1509 | } else { 1510 | peg$currPos = s0; 1511 | s0 = peg$FAILED; 1512 | } 1513 | } else { 1514 | peg$currPos = s0; 1515 | s0 = peg$FAILED; 1516 | } 1517 | } else { 1518 | peg$currPos = s0; 1519 | s0 = peg$FAILED; 1520 | } 1521 | } else { 1522 | peg$currPos = s0; 1523 | s0 = peg$FAILED; 1524 | } 1525 | if (s0 === peg$FAILED) { 1526 | s0 = peg$currPos; 1527 | s1 = peg$parseHTML_Attribute_Name(); 1528 | if (s1 !== peg$FAILED) { 1529 | s2 = []; 1530 | s3 = peg$parse_(); 1531 | while (s3 !== peg$FAILED) { 1532 | s2.push(s3); 1533 | s3 = peg$parse_(); 1534 | } 1535 | if (s2 !== peg$FAILED) { 1536 | if (input.charCodeAt(peg$currPos) === 61) { 1537 | s3 = peg$c36; 1538 | peg$currPos++; 1539 | } else { 1540 | s3 = peg$FAILED; 1541 | if (peg$silentFails === 0) { peg$fail(peg$c37); } 1542 | } 1543 | if (s3 !== peg$FAILED) { 1544 | s4 = []; 1545 | s5 = peg$parse_(); 1546 | while (s5 !== peg$FAILED) { 1547 | s4.push(s5); 1548 | s5 = peg$parse_(); 1549 | } 1550 | if (s4 !== peg$FAILED) { 1551 | if (input.charCodeAt(peg$currPos) === 39) { 1552 | s5 = peg$c43; 1553 | peg$currPos++; 1554 | } else { 1555 | s5 = peg$FAILED; 1556 | if (peg$silentFails === 0) { peg$fail(peg$c44); } 1557 | } 1558 | if (s5 !== peg$FAILED) { 1559 | s6 = peg$currPos; 1560 | s7 = []; 1561 | s8 = peg$currPos; 1562 | s9 = peg$currPos; 1563 | peg$silentFails++; 1564 | if (input.charCodeAt(peg$currPos) === 39) { 1565 | s10 = peg$c43; 1566 | peg$currPos++; 1567 | } else { 1568 | s10 = peg$FAILED; 1569 | if (peg$silentFails === 0) { peg$fail(peg$c44); } 1570 | } 1571 | peg$silentFails--; 1572 | if (s10 === peg$FAILED) { 1573 | s9 = void 0; 1574 | } else { 1575 | peg$currPos = s9; 1576 | s9 = peg$FAILED; 1577 | } 1578 | if (s9 !== peg$FAILED) { 1579 | if (input.length > peg$currPos) { 1580 | s10 = input.charAt(peg$currPos); 1581 | peg$currPos++; 1582 | } else { 1583 | s10 = peg$FAILED; 1584 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 1585 | } 1586 | if (s10 !== peg$FAILED) { 1587 | s9 = [s9, s10]; 1588 | s8 = s9; 1589 | } else { 1590 | peg$currPos = s8; 1591 | s8 = peg$FAILED; 1592 | } 1593 | } else { 1594 | peg$currPos = s8; 1595 | s8 = peg$FAILED; 1596 | } 1597 | while (s8 !== peg$FAILED) { 1598 | s7.push(s8); 1599 | s8 = peg$currPos; 1600 | s9 = peg$currPos; 1601 | peg$silentFails++; 1602 | if (input.charCodeAt(peg$currPos) === 39) { 1603 | s10 = peg$c43; 1604 | peg$currPos++; 1605 | } else { 1606 | s10 = peg$FAILED; 1607 | if (peg$silentFails === 0) { peg$fail(peg$c44); } 1608 | } 1609 | peg$silentFails--; 1610 | if (s10 === peg$FAILED) { 1611 | s9 = void 0; 1612 | } else { 1613 | peg$currPos = s9; 1614 | s9 = peg$FAILED; 1615 | } 1616 | if (s9 !== peg$FAILED) { 1617 | if (input.length > peg$currPos) { 1618 | s10 = input.charAt(peg$currPos); 1619 | peg$currPos++; 1620 | } else { 1621 | s10 = peg$FAILED; 1622 | if (peg$silentFails === 0) { peg$fail(peg$c17); } 1623 | } 1624 | if (s10 !== peg$FAILED) { 1625 | s9 = [s9, s10]; 1626 | s8 = s9; 1627 | } else { 1628 | peg$currPos = s8; 1629 | s8 = peg$FAILED; 1630 | } 1631 | } else { 1632 | peg$currPos = s8; 1633 | s8 = peg$FAILED; 1634 | } 1635 | } 1636 | if (s7 !== peg$FAILED) { 1637 | s6 = input.substring(s6, peg$currPos); 1638 | } else { 1639 | s6 = s7; 1640 | } 1641 | if (s6 !== peg$FAILED) { 1642 | if (input.charCodeAt(peg$currPos) === 39) { 1643 | s7 = peg$c43; 1644 | peg$currPos++; 1645 | } else { 1646 | s7 = peg$FAILED; 1647 | if (peg$silentFails === 0) { peg$fail(peg$c44); } 1648 | } 1649 | if (s7 !== peg$FAILED) { 1650 | peg$savedPos = s0; 1651 | s1 = peg$c40(s1, s6); 1652 | s0 = s1; 1653 | } else { 1654 | peg$currPos = s0; 1655 | s0 = peg$FAILED; 1656 | } 1657 | } else { 1658 | peg$currPos = s0; 1659 | s0 = peg$FAILED; 1660 | } 1661 | } else { 1662 | peg$currPos = s0; 1663 | s0 = peg$FAILED; 1664 | } 1665 | } else { 1666 | peg$currPos = s0; 1667 | s0 = peg$FAILED; 1668 | } 1669 | } else { 1670 | peg$currPos = s0; 1671 | s0 = peg$FAILED; 1672 | } 1673 | } else { 1674 | peg$currPos = s0; 1675 | s0 = peg$FAILED; 1676 | } 1677 | } else { 1678 | peg$currPos = s0; 1679 | s0 = peg$FAILED; 1680 | } 1681 | } 1682 | 1683 | return s0; 1684 | } 1685 | 1686 | function peg$parseHTML_Attribute_Name() { 1687 | var s0, s1, s2; 1688 | 1689 | s0 = peg$currPos; 1690 | s1 = []; 1691 | if (peg$c45.test(input.charAt(peg$currPos))) { 1692 | s2 = input.charAt(peg$currPos); 1693 | peg$currPos++; 1694 | } else { 1695 | s2 = peg$FAILED; 1696 | if (peg$silentFails === 0) { peg$fail(peg$c46); } 1697 | } 1698 | if (s2 !== peg$FAILED) { 1699 | while (s2 !== peg$FAILED) { 1700 | s1.push(s2); 1701 | if (peg$c45.test(input.charAt(peg$currPos))) { 1702 | s2 = input.charAt(peg$currPos); 1703 | peg$currPos++; 1704 | } else { 1705 | s2 = peg$FAILED; 1706 | if (peg$silentFails === 0) { peg$fail(peg$c46); } 1707 | } 1708 | } 1709 | } else { 1710 | s1 = peg$FAILED; 1711 | } 1712 | if (s1 !== peg$FAILED) { 1713 | s0 = input.substring(s0, peg$currPos); 1714 | } else { 1715 | s0 = s1; 1716 | } 1717 | 1718 | return s0; 1719 | } 1720 | 1721 | function peg$parseASCII_AlphaNumeric() { 1722 | var s0; 1723 | 1724 | s0 = peg$parseASCII_Letter(); 1725 | if (s0 === peg$FAILED) { 1726 | s0 = peg$parseASCII_Digit(); 1727 | } 1728 | 1729 | return s0; 1730 | } 1731 | 1732 | function peg$parseASCII_Letter() { 1733 | var s0; 1734 | 1735 | if (peg$c47.test(input.charAt(peg$currPos))) { 1736 | s0 = input.charAt(peg$currPos); 1737 | peg$currPos++; 1738 | } else { 1739 | s0 = peg$FAILED; 1740 | if (peg$silentFails === 0) { peg$fail(peg$c48); } 1741 | } 1742 | 1743 | return s0; 1744 | } 1745 | 1746 | function peg$parseASCII_Digit() { 1747 | var s0; 1748 | 1749 | if (peg$c49.test(input.charAt(peg$currPos))) { 1750 | s0 = input.charAt(peg$currPos); 1751 | peg$currPos++; 1752 | } else { 1753 | s0 = peg$FAILED; 1754 | if (peg$silentFails === 0) { peg$fail(peg$c50); } 1755 | } 1756 | 1757 | return s0; 1758 | } 1759 | 1760 | function peg$parseNewline() { 1761 | var s0; 1762 | 1763 | if (peg$c51.test(input.charAt(peg$currPos))) { 1764 | s0 = input.charAt(peg$currPos); 1765 | peg$currPos++; 1766 | } else { 1767 | s0 = peg$FAILED; 1768 | if (peg$silentFails === 0) { peg$fail(peg$c52); } 1769 | } 1770 | 1771 | return s0; 1772 | } 1773 | 1774 | function peg$parse_() { 1775 | var s0; 1776 | 1777 | if (peg$c53.test(input.charAt(peg$currPos))) { 1778 | s0 = input.charAt(peg$currPos); 1779 | peg$currPos++; 1780 | } else { 1781 | s0 = peg$FAILED; 1782 | if (peg$silentFails === 0) { peg$fail(peg$c54); } 1783 | } 1784 | 1785 | return s0; 1786 | } 1787 | 1788 | function peg$parse__() { 1789 | var s0, s1; 1790 | 1791 | s0 = []; 1792 | s1 = peg$parse_(); 1793 | if (s1 !== peg$FAILED) { 1794 | while (s1 !== peg$FAILED) { 1795 | s0.push(s1); 1796 | s1 = peg$parse_(); 1797 | } 1798 | } else { 1799 | s0 = peg$FAILED; 1800 | } 1801 | 1802 | return s0; 1803 | } 1804 | 1805 | 1806 | function orJSON( text ) { 1807 | try { 1808 | return JSON.parse( text ); 1809 | } catch (e) { 1810 | return text; 1811 | } 1812 | } 1813 | 1814 | function orAsJSON( source ) { 1815 | return Object.keys( source ).reduce( function( o, key ) { 1816 | return Object.assign( o, { [ key ]: orJSON( source[ key ] ) } ); 1817 | }, {} ); 1818 | } 1819 | 1820 | 1821 | peg$result = peg$startRuleFunction(); 1822 | 1823 | if (peg$result !== peg$FAILED && peg$currPos === input.length) { 1824 | return peg$result; 1825 | } else { 1826 | if (peg$result !== peg$FAILED && peg$currPos < input.length) { 1827 | peg$fail(peg$endExpectation()); 1828 | } 1829 | 1830 | throw peg$buildStructuredError( 1831 | peg$maxFailExpected, 1832 | peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, 1833 | peg$maxFailPos < input.length 1834 | ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) 1835 | : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) 1836 | ); 1837 | } 1838 | } 1839 | 1840 | root.postParser = { 1841 | SyntaxError: peg$SyntaxError, 1842 | parse: peg$parse 1843 | }; 1844 | })(this); 1845 | -------------------------------------------------------------------------------- /explorer/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow: hidden; 3 | } 4 | 5 | .wppgInputPane { 6 | width: 95%; 7 | height: 100%; 8 | padding: 1em; 9 | font-family: monospace; 10 | font-size: 16px; 11 | } 12 | 13 | .wppgLayout { 14 | display: flex; 15 | flex-direction: row; 16 | font-family: monospace; 17 | font-size: 16px; 18 | } 19 | 20 | .wppgNoHighlight { 21 | color: rgb(208, 208, 208); 22 | } 23 | 24 | .wppgNoHighlight * { 25 | color: rgb(208, 208, 208); 26 | } 27 | 28 | .wppgOutputPane { 29 | height: 90%; 30 | overflow: scroll; 31 | padding: 1em; 32 | } 33 | 34 | .wppgParseBad { 35 | color: rgb(200, 0, 0); 36 | } 37 | 38 | .wppgParseGood { 39 | color: rgb(0, 128, 0); 40 | } 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wordpress-post-grammar", 3 | "version": "0.1.0", 4 | "description": "PEG.js grammar for WordPress posts including new theming designs", 5 | "main": "index.js", 6 | "scripts": { 7 | "postinstall": "pegjs -o ./post-parser.js ./src/post.pegjs", 8 | "build:css": "elm-css explorer/Stylesheets.elm -o explorer/", 9 | "build:explorer-parser": "pegjs --export-var postParser --format globals -o ./explorer/post-parser.js ./src/post.pegjs", 10 | "build:explorer-elm": "elm-make explorer/Explorer.elm --output explorer/explorer.js", 11 | "build:explorer": "npm run build:explorer-parser && npm run build:css && npm run build:explorer-elm", 12 | "start": "chokidar '**/*.elm' -c 'npm run build:explorer'", 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [ 16 | "WordPress", 17 | "Grammar", 18 | "PEGjs", 19 | "parser" 20 | ], 21 | "author": "Dennis Snell ", 22 | "license": "ISC", 23 | "devDependencies": { 24 | "elm-css": "^0.6.0", 25 | "pegjs": "0.10.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/post.pegjs: -------------------------------------------------------------------------------- 1 | { 2 | function orJSON( text ) { 3 | try { 4 | return JSON.parse( text ); 5 | } catch (e) { 6 | return text; 7 | } 8 | } 9 | 10 | function orAsJSON( source ) { 11 | return Object.keys( source ).reduce( function( o, key ) { 12 | return Object.assign( o, { [ key ]: orJSON( source[ key ] ) } ); 13 | }, {} ); 14 | } 15 | } 16 | 17 | Document 18 | = ts:Token* 19 | 20 | Token 21 | = WP_Block_Balanced 22 | / WP_Block_Start 23 | / WP_Block_End 24 | / HTML_Comment 25 | / HTML_Tag_Void 26 | / HTML_Tag_Balanced 27 | / HTML_Tag_Open 28 | / HTML_Tag_Close 29 | / ts:$(HTML_Text+) 30 | { return { 31 | type: 'Text', 32 | value: ts 33 | } } 34 | 35 | HTML_Text 36 | = [^<] 37 | 38 | WP_Block_Balanced 39 | = s:WP_Block_Start children:(!WP_Block_End t:Token { return t })+ e:WP_Block_End 40 | { return { 41 | type: 'WP_Block', 42 | blockType: s.blockType, 43 | attrs: orAsJSON( s.attrs ), 44 | rawContent: text(), 45 | children 46 | } } 47 | 48 | WP_Block_Start 49 | = "" 50 | { return { 51 | type: 'WP_Block_Start', 52 | blockType, 53 | attrs 54 | } } 55 | 56 | WP_Block_End 57 | = "" 58 | { return { 59 | type: 'WP_Block_End' 60 | } } 61 | 62 | WP_Block_Type 63 | = $(ASCII_Letter (ASCII_AlphaNumeric / "/" ASCII_AlphaNumeric)*) 64 | 65 | HTML_Comment 66 | = "" c:. { return c })* "-->" 67 | { return { 68 | type: "HTML_Comment", 69 | innerText: cs.join('') 70 | } } 71 | 72 | HTML_Tag_Void 73 | = t:HTML_Tag_Open 74 | & { return undefined !== { 75 | 'br': true, 76 | 'col': true, 77 | 'embed': true, 78 | 'hr': true, 79 | 'img': true, 80 | 'input': true 81 | }[ t.name.toLowerCase() ] } 82 | { return { 83 | type: 'HTML_Void_Tag', 84 | name: t.name, 85 | attrs: t.attrs 86 | } } 87 | 88 | HTML_Tag_Balanced 89 | = s:HTML_Tag_Open 90 | children:( 91 | HTML_Tag_Balanced 92 | / (!(ct:HTML_Tag_Close & { return s.name === ct.name } ) t:Token { return t }))* 93 | e:HTML_Tag_Close 94 | & { return s.name === e.name } 95 | { return { 96 | type: 'HTML_Tag', 97 | name: s.name, 98 | attrs: s.attrs, 99 | children 100 | } } 101 | 102 | HTML_Tag_Open 103 | = "<" name:HTML_Tag_Name attrs:HTML_Attribute_List _* ">" 104 | { return { 105 | type: 'HTML_Tag_Open', 106 | name, 107 | attrs 108 | } } 109 | 110 | HTML_Tag_Close 111 | = "" 112 | { return { 113 | type: 'HTML_Tag_Close', 114 | name 115 | } } 116 | 117 | HTML_Tag_Name 118 | = $(ASCII_Letter ASCII_AlphaNumeric*) 119 | 120 | HTML_Attribute_List 121 | = as:(_+ a:HTML_Attribute_Item { return a })* 122 | { return as.reduce( ( attrs, [ name, value ] ) => Object.assign( 123 | attrs, 124 | { [ name ]: value } 125 | ), {} ) } 126 | 127 | HTML_Attribute_Item 128 | = HTML_Attribute_Quoted 129 | / HTML_Attribute_Unquoted 130 | / HTML_Attribute_Empty 131 | 132 | HTML_Attribute_Empty 133 | = name:HTML_Attribute_Name 134 | { return [ name, true ] } 135 | 136 | HTML_Attribute_Unquoted 137 | = name:HTML_Attribute_Name _* "=" _* value:$([a-zA-Z0-9]+) 138 | { return [ name, value ] } 139 | 140 | HTML_Attribute_Quoted 141 | = name:HTML_Attribute_Name _* "=" _* '"' value:$((!'"' .)*) '"' 142 | { return [ name, value ] } 143 | / name:HTML_Attribute_Name _* "=" _* "'" value:$((!"'" .)*) "'" 144 | { return [ name, value ] } 145 | 146 | HTML_Attribute_Name 147 | = $([a-zA-Z0-9:.]+) 148 | 149 | ASCII_AlphaNumeric 150 | = ASCII_Letter 151 | / ASCII_Digit 152 | 153 | ASCII_Letter 154 | = [a-zA-Z] 155 | 156 | ASCII_Digit 157 | = [0-9] 158 | 159 | Newline 160 | = [\r\n] 161 | 162 | _ 163 | = [ \t] 164 | 165 | __ 166 | = _+ 167 | --------------------------------------------------------------------------------