Markup spec

MediaWiki markup spec project:

Goals

 * Produce a specification of MediaWiki's markup format that is sufficiently complete and consistent that multiple compatible parser implementations can be built from it.
 * Spec may or may not use EBNF etc. Might have to just use lots of words. ;)
 * Define a data model for a parse tree
 * The data model should be representable in XML, though an official XML schema for such a representation may or may not be defined.
 * Round-trip conversion between source code and the data model must be possible. There may be a many-to-one relationship between source code and parse trees, but the canonical transformation from parse tree to source code should always parse back to the same parse tree.
 * A parser built from this spec will replace MediaWiki's current parser in the future.

Compatibility

 * In general, the spec will strive to avoid deviating from present behavior where it is reasonable and well-defined, and will seek to avoid adding new behaviour without considering whether it may break already existent pages.
 * Where the current parser's behavior is undefined or obviously buggy, the spec may define new behavior which is different.

Difficulties

 * Some of the syntax is kind of hairy. Bleah!
 * Language-sensitive and otherwise customizable keywords.
 * Extensions...
 * Integrated HTML and HTML-like tags.
 * Lots of scary context-sensitivity (see e.g. MediaWiki lexer).

Resources

 * Raid Magnus's wiki2xml work for some starting points; examine how his parser works (and how it differs from the main one) and the intermediate XML format he uses
 * http://www.mediawiki.org/wiki/User:HappyDog/WikiText_parsing - some observations based on 1.3.10 by HappyDog
 * meta:Help:Editing - it's a start
 * An attempt to describe the markup in BNF form: Markup spec/BNF
 * http://jamwiki.org/wiki/en/StartingPoints Aims to have Mediawiki compatible syntax see http://svn.sourceforge.net/viewvc/jamwiki/wiki/trunk/src/lex/ for an attempt to write a parser.

= The Markup Language =

The MediaWiki markup language (commonly referred to within the MediaWiki community as wikitext, though this usage is ambiguous within the larger wiki community) uses sometimes paired non-textual ASCII characters to indicate to the parser how the editor wishes an item or section of text to be displayed. The parser translates these tokens into (X)HTML as closely as semantically possible.

v1.6 markup tokens
The markup tokens fall into two broad categories: unary tokens (like : or * used at the beginning of a line), which stand alone, and binary tokens (like those for italic or boldface) which must be used in matched pairs. Unary tokens may only be preceded by comments or whitespace; otherwise, they will not be interpreted.

Start of line only

 * blank line: paragraph break (HTML &lt;p&gt;)
 * Horizontal line:  (4 or more hyphens), specified in /BNF/Article
 * Pre-formatted text: (space)
 * Lists
 * Bulleted: *
 * Numbered: #
 * Indent with no marking: :
 * Definition list: ;
 * Notes:
 * These may be combined at the start of the line to create nested lists, e.g. *** to give a bulleted list three levels deep, or **# to have a numbered list within two-levels of bulleted list nesting.
 * Redirects: #redirect or #REDIRECT (followed by wikilink)
 * The whole quagmire that is table formatting:  {| ... |}  with in between  |- |+ || | ! ! .

Can be used anywhere

 * "Magic words", e.g.  ,    (see m:Help:Magic words)
 * Signatures:
 *   Replaced with your username
 *  ~  Replaced with your username and the date
 *   Replaced with the date.
 * Notes:
 * These tags are replaced at the point the edit is saved.
 * Magic links: ISBN ..., RFC ..., PMID ... (see /BNF/Magic links/)

Binary
The ellipses (...) are used to indicate where the content goes and are not part of the markup.

Beginning of a line

 * Equals signs are used for headings (must be at start of line)
 * 1st level heading:  = ... = 
 * 2nd level heading:  == ... == 
 * 3rd level heading:  === ... === 
 * 4th level heading:  ==== ... ==== 
 * 5th level heading:  ===== ... ===== 
 * 6th level heading:  ====== ... ====== 
 * Specified in /BNF/Article

Anywhere

 * Square brackets are used for links:
 * Internal/interwiki link + language links + category links + images:  ...   (see also Namespaces below)
 * vertical bars separate optional parameters, which are:
 * link: first parameter: display text (also defaulted using "pipe trick") (also trailing concatenated text included in display, e.g. s for plural)
 * image: many parameters; see w:Wikipedia:Extended image syntax
 * category: first parameter: sort order in category list
 * link contents have to be parsed for whether they're dates if $wgUseDynamicDates is on
 * External link:  [ ... ] 
 * space separates optional first parameter, which is display text
 * undecorated URLs are also recognized and hotlinked
 * Specified in /BNF/Links
 * Apostrophes are used for formatting:
 * Italic:   ...  
 * Bold:   ...  
 * Bold + Italic:   ...  
 * Note that improper nesting of bold and italics is currently permitted.
 * Curly braces are used for transclusion:
 * Include template:   (see also Namespaces below)
 * Unlimited number of optional pipe-delimited parameters, each of which may optionally start with a parameter name preceding an equals sign
 * Include template parameter:  
 * Optionally including a pipe followed by the parameter default
 * Interpolate built-in variable:   (see m:Help:Variable)
 * Various HTML style tags:
 * &lt;nowiki&gt; do not interpret wiki markup, do allow newline in list and indent elements (but still flow text, still allow SGML entities)
 * &lt;pre&gt; do not interpret wiki markup, do not flow text (but still allow SGML entities)
 * &lt;math&gt; if $wgUseTeX is set
 * &lt;html&gt; if $wgRawHtml is set
 * &lt;gallery&gt;</tt>
 * &lt;onlyinclude&gt;</tt> &lt;noinclude&gt;</tt> &lt;includeonly&gt;</tt>
 * Parser extension tags, like &lt;ref&gt;</tt> (using Cite.php)
 * Plus most 'non-dangerous' HTML tags: 'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's', 'strike', 'strong', 'tt', 'var', 'div', 'center', 'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre', 'ruby', 'rt', 'rb' , 'rp', 'p', 'span', 'u', 'br', 'hr', 'li', 'dt', 'dd', 'td', 'th', 'tr'
 * &lt;!-- ... --&gt; HTML-style comments
 * SGML entities: &amp;...;</tt>

Namespaces
In wikilinks and template inclusions, colons set off namespaces and other modifiers:
 * proper namespaces: <TT>Talk:</TT>, <TT>User:</TT>, project, etc.
 * "special" namespaces: <TT>Image:</TT>, <TT>Category:</TT>, <TT>Template:</TT>
 * pseudo-namespaces: Special:</tt>, Media:</tt>
 * lone/leading :</tt>
 * lone :</tt> forces main namespace
 * leading :</tt> allows link to image page rather than inline image, or similarly to category or template page
 * interwiki links:
 * same project, different language: code of two or more letters
 * different project, same language: w:</tt> for Wikipedia, wikt:</tt> for Wiktionary, m:</tt> for Meta, etc. -- see m:Help:Interwiki_linking for more information (especially when using in templates; transwiki transclusion, iw_trans)
 * <tt>subst:</tt> force one-time template substitution upon edit, rather than dynamic expansion on each view
 * <tt>int:</tt>, <tt>msg:</tt>, <tt>msgnw:</tt>, <tt>raw:</tt> -- see m:Help:Magic words
 * <tt>MediaWiki:</tt> magically access mediawiki formatting and boilerplate text (e.g. MediaWiki:copyrightwarning)
 * Colon functions: <tt>UC:</tt>, <tt>LC:</tt>, etc. (see m:Help:Colon function)
 * Parser functions: <tt>#expr:</tt>, <tt>#if:</tt>, <tt>#switch:</tt>, etc. (see ParserFunctions)
 * other extensions?

Several combinations of the above are possible, e.g. m:Help:Variable -- help namespace within Meta project.

From MetaWiki
The following text was at Wikitext Metasyntax and needs to be merged in here.

Wikitext = DocTypeArticle | DocTypeRedirect ;

Document structure
Redirect

DocTypeRedirect = "#REDIRECT " PageName [ "" { NewLine } CatsAndInterwikis ;

Article

DocTypeArticle = [ DocOptions ] Paragraph { NewLine NewLine Paragraph } { Section } [ DocClose ] ; Paragraph = ( InlineText { InlineText } | BlockText ) ; Section = Heading { NewLine NewLine Paragraph } ;

Metadocument elements
DocOptions = [ "" NewLine | "" NewLine ] [ "" NewLine ] ; DocClose = CatsAndInterwikis | NewLine { NewLine }, "__END__" ; CatsAndInterwikis = { Newline, Category | Newline , InterWiki } ;

String Types
Fundamental strings

WikiMarkupCharacters = "|" | "[" | "]" | "*" | "#" | ":" | ";" | "<" | ">" | "=" | "'" | "{" | "}" ;

UnicodeCharacter = ? all supported Unicode characters ? - Whitespaces ; UnicodeWiki = UnicodeCharacter - WikiMarkupCharacters ; PlainText = UnicodeWiki | "  " { "|" | "[" | "]" | "<" | ">" | "{" | "}" } "   "          | UnicodeWiki { " " } ( "*" | "#" | ":" | ";" ) | UnicodeWiki [ " " ] "=" [ " " ] UnicodeWiki | UnicodeWiki "'" | " '" UnicodeWiki ; WhiteSpaces = " " | NewLine | ? carriage return ? | ? line feed ? | ? tab ? | ? variants of spaces ? ; NewLine = ? carriage return and line feed ? ;

Article strings

Line = PlainText { PlainText } { " " { " " } PlainText { PlainText } } ; Text = Line { Line } { NewLine { NewLine } Line { Line } } ;

Titles

PageName = TitleCharacter, { [ " " ] TitleCharacter } ; PageNameLink = TitleCharacter, { [ " " | "_" ] TitleCharacter } ; SectionTitle = ( SectionLinkCharacter - "=" ) { [ " " ] ( SectionLinkCharacter - "=" ) } ; SectionLink = SectionLinkCharacter { [ "_" ] SectionLinkCharacter } ; LinkTitle = { UnicodeCharacter { " " } } ( UnicodeCharacter - "]" ) ;

TitleCharacter = UnicodeCharacter - BadTitleCharacters ; BadTitleCharacters = "[" | "]" | "{" | "}" | "<" | ">" | "_" | "|" | "#" ; SectionLinkCharacter = UnicodeCharacter - BadSectionLinkCharacters ; BadSectionLinkCharacters = "[" | "]" | "|" ;

Document element declaration
AnyText = InlineText | BlockText ; InlineText = Line | InlineTextNormal | InlineTextExtra | EitherText ; InlineTextNormal = Line | Bold | Italic | BoldItalic ; InlineTextExtra = Line | InternalLink | ExternalLink | InlineHTML ; BlockText = Text | Image | Media | Table | Heading | Separator | Gallery | List | BlockHTML | EitherText ; EitherText = Extension | Template | NoWiki | Parameter | Comment ;

Basic Markup
Define markups

Inline elements
Bold = "" { InlineTextExtra } "" ; Italic = "" { InlineTextExtra } "" ; BoldItalic = "" { InlineTextExtra } "" ;

InternalLink = "" [ LinkTitle ] ] "" ; ExternalLink = "[" URL [ " " LinkTitle ] "]" | URL ;

Block elements
Images

Image = "" ; ImageExtension = "jpg" | "jpeg" | "png" | "svg" | "gif" | "bmp" ; ThumbImageParameter = "thumb" | "frame" | "enframed" | "thumbnail" ; SizeImageParameter = PositiveNumber "px" ; AlignImageParameter = "left" | "center" | "centre" | "right" ;

Media

Media = "", "Media:" , PageName "." MediaExtension "" ; MediaExtension = "ogg" | "wav" ;

Tables

Table = "{|" [ " " TableParameters ] NewLine TableFirstRow "|}" ; TableFirstRow = TableColumnLine NewLine | TableColumnMultiLine | TableRow ; TableRow = "|-" [ CSS ] NewLine TableColumn [ TableRow ] ; TableColumn = TableColumnLine | TableColumnMultiLine ; TableColumnLine = "|" InlineText [ "|" TableColumnLine ] ; TableColumnMultiLine = "|" [ TableCellParameters "|" ] AnyText NewLine [ TableColumnMultiLine ] ; TableParameters = CSS | ? HTML table attributes ? ; TableCellParameter = CSS | ? HTML cell attributes ? ;

Headings

Heading = Level1 | Level2 | Level3 | Level4 | Level5 | Level6 ; Level1 = NewLine "=" SectionTitle "=" NewLine ; Level2 = NewLine "==" SectionTitle "==" NewLine ; Level3 = NewLine "===" SectionTitle "===" NewLine ; Level4 = NewLine "====" SectionTitle "====" NewLine ; Level5 = NewLine "=====" SectionTitle "=====" NewLine ; Level6 = NewLine "======" SectionTitle "======" NewLine ;

Separator

Separator = NewLine "" NewLine ;

Gallery

Gallery = "" ;

Lists (see |Talk)

List = ListPoint [ " " ] InlineText [ NewLine List ] ; ListPoint = StarPoint | HashPoint | Indent ; StarPoint = "*" [ ListPoint ] ; HashPoint = "#" [ ListPoint ] ; Indent = ":" [ ListPoint ] ;

Either
Template = "" ; Extension = "<" ? extension ? ">" AnyText "</" ? extension ? ">" ; NoWiki = " " | "  " ( InlineText | BlockText ) "   " ; Parameter = "" ; Comment = "" | "" ;

ParameterName = ? uppercase, lowercase, numbers, no spaces, some special chars ? ;

Allowed HTML
InlineHTML = BoldHTML | ItalicHTML | UnderlineHTML | Superscript | Subscript | Strikethrough | " " | Small | Big | Code | Span ; BlockHTML = Pre | Blockquote | TableHTML | Div | HeaderHTML ;

See also m:Help:Magic words.