sdocp('attribute-parser.js.sdoc', 'Perl object attribute parser | Spencer Tipping\nLicensed under the terms of the MIT source code license\n\nvar parse_attributes = caterwaul.clone(\'std seq continuation parser\')(function (s) {\n  return model,\n\n  where*[parse_attributes(s)     = l*[namespace             = peg[[c(/[\\s\\n]+/, 1)] % c(/meta::(\\w+)/, 7) >> fn[xs][xs[1][1]]],\n                                      string                = peg[c(\'\\\'\') % (c(/[^\\\\\']/, 1) / (c(/\\\\(.)/, 2) >> fn[xs][xs[1]]))[0] % c(\'\\\'\') >> fn[xs][xs[1].join(\'\')]],\n                                      here_document         = peg[c(\'<<\') % string >> fn[xs][xs[1]]],\n\n                                      invocation_common     = peg[namespace % c(\'(\') % string % c(/,\\s*/, 1) >> fn[xs][{namespace: xs[0], attribute: xs[2]}]],\n\n                                      short_form_invocation = peg[invocation_common % string % c(\');\\n\') >> fn[xs][xs[0] /se[_.value = xs[1]]]],\n\n                                      long_form_invocation  = l*[beginning            = peg[invocation_common % here_document % c(\');\\n\') >> fn[xs][xs[0] /se[_.marker = xs[1]]]],\n                                                                 ending(end)          = peg[(reject(c(end)) % (c(/[^\\n]+/, 1) / c(\'\\n\')))[0] % c(end) >> fn[xs][seq[~xs[0] *[_[1]]].join(\'\')]],\n                                                                 parse_heredoc(input) = l*[begin = beginning(input),\n                                                                                           end   = begin.result && ending(\'\\n#{begin.result.marker}\\n\')(begin)] in\n                                                                                        end /se[_.result = begin.result /se[_.value = end.result], when[begin.result]]] in\n                                                              parse_heredoc,\n\n                                      attribute             = peg[short_form_invocation / long_form_invocation],\n                                      attributes            = peg[attribute[0]],\n\n                                      unescape(s)           = s.replace(/&lt;/gi, \'<\').replace(/&gt;/gi, \'>\').replace(/&amp;/gi, \'&\'),\n                                      trim_bootstrap(s)     = s.replace(/^(?:(?!\\nmeta::\\w+\\()(?:.|\\n))*\\n/, \'\')] in\n\n                                   attributes(trim_bootstrap(unescape(s))),\n\n         separate_namespaces(xs) = l[namespace_object = seq[~xs *[[_.namespace, true]]].object()] in seq[sk[namespace_object] *[[_, seq[~xs %x[x.namespace === _]]]]].object(),\n\n         parsed                  = parse_attributes(s),\n         model                   = l[partitioned = separate_namespaces(parsed)] in seq[sp[partitioned] *~[[_[0], !(_[1] *[[_.attribute, _.value]])]]].object()]});\n');
