MediaWiki:Gadget-ParserPlayground-PegParser.pegjs
/* Produces output more or less compatible with FakeParser; plug it into FP's output and see */
start
= e:block* { return {type: 'page', content: e } }
anything
= a:[A-Za-z0-9,._ -]+ { return a.join() } / [^\n]
space
= s:[ ]+ { return s.join(); }
newline
= [\n]
block
= h / br / para
h = h1 / h2 / h3 / h4 / h5 / h6
h1 = '=' c:heading_text '=' newline {
return { type: 'h', level: 1, text: c }
}
h2 = '==' c:heading_text '==' newline {
return { type: 'h', level: 2, text: c }
}
h3 = '===' c:heading_text '===' newline {
return { type: 'h', level: 3, text: c }
}
h4 = '====' c:heading_text '====' newline {
return { type: 'h', level: 4, text: c }
}
h5 = '=====' c:heading_text '=====' newline {
return { type: 'h', level: 5, text: c }
}
h6 = '======' c:heading_text '======' newline {
return { type: 'h', level: 6, text: c }
}
heading_marker
= '=' '='*
heading_text
= h:( !heading_marker x:(anything) { return x } )* { return h.join(); }
br
= newline { return {type: 'br'} }
para
= c:inline newline { return {type: 'para', content: c } }
inline
= c:inline_element+ { var out = []; var text = ; for (var i = 0; i < c.length; i++) { if (typeof c[i] == 'string') { text += c[i]; } else { if (text.length) { out.push({ type: 'text', text: text }); text = ; } out.push(c[i]); } } if (text.length) { out.push({ type: 'text', text: text }); } return out;
}
inline_element
= ref / extlink / template / link / italic / anything
inline_text_run
= c:[^\n]+ { return c.join(); }
extlink
= "[" target:url space text:extlink_text "]" { return { type: 'extlink', target: target, text: text }
}
// = "[" target:url text:extlink_text "]" { return { type: 'extlink', target: target, text: text } }
url
= proto:"http:" rest:([^ \]]+) { return proto + rest.join(); }
extlink_text
= c:[^\]]+ { return c.join(); }
template
= "Template:" target:link target params:("" { var obj = { type: 'template', target: target }; if (params && params.length) { obj.params = params; } return obj;
}
template_param
= name:template_param_name "=" c:template_param_text { return { name: name, contents: c };
} / c:template_param_text {
return { contents: c };
}
template_param_name
= h:( !"}}" x:([^=|]) { return x } )* { return h.join(); }
template_param_text
= h:( !"}}" x:([^|]) { return x } )* { return h.join(); }
link
= "" link_text)* "" { var obj = { type: 'link', target: target }; if (text && text.length) { obj.text = text[0][1]; // ehhhh } return obj;
}
link_target
= h:( !"]]" x:([^|]) { return x } )* { return h.join(); }
link_text
= h:( !"]]" x:(anything) { return x } )* { return h.join(); }
italic
= italic_marker c:italic_text italic_marker { return { type: 'i', text: c }
}
italic_marker
= ""
italic_text
= h:( !italic_marker x:(anything) { return x } )+ { return h.join(); }
ref = ref_full / ref_empty
ref_full
= params:ref_start ">" content:ref_content+ close:ref_end { return { type: 'ext', name: 'ref', params: params, content: content, close: close }
}
ref_empty
= params:ref_start "/>" { return { type: 'ext', name: 'ref', params: params }
}
ref_start
= "<ref" params:ext_param* space* { var obj = {}; for (var i = 0; i < params.length; i++) { obj[params[i][0]] = params[i][1]; } return obj;
}
ref_end
= all:("</ref" space* ">") { return all.join();
}
ref_content
= !ref_end a:inline_element { return a;
}
ext_param
= space* name:ext_param_name "=" val:ext_param_val { return [name, val];
}
ext_param_name
= name:[a-zA-Z0-9-]+ { return name.join();
}
ext_param_val
= t:[0-9A-Za-z]+ { return t.join() } / "'" t:[^'>]+ "'" { return t.join() } / '"' t:[^">]+ '"' { return t.join() }