
#     This is the Mathematical Markup Language (MathML) 3.0, an XML
#     application for describing mathematical notation and capturing
#     both its structure and content.
#
#     With additional changes for integration into the validator.nu
#     service.
#
#     Copyright 1998-2010 W3C (MIT, ERCIM, Keio)
#     Copyright 2012 Mozilla Foundation
# 
#     Use and distribution of this code are permitted under the terms
#     W3C Software Notice and License
#     http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231

default namespace m = "http://www.w3.org/1998/Math/MathML"

MathExpression |= PresentationExpression

ImpliedMrow = MathExpression*

TableRowExpression = mtr|mlabeledtr

TableCellExpression = mtd

MstackExpression = MathExpression|mscarries|msline|msrow|msgroup

MsrowExpression = MathExpression|none

MultiScriptExpression = (MathExpression|none),(MathExpression|none)

mpadded-length = xsd:string {
  pattern = '\s*([\+\-]?[0-9]*(\.[0-9]*)?\s*((%?\s*(height|depth|width)?)|e[mx]|in|cm|mm|p[xtc]|((negative)?((very){0,2}thi(n|ck)|medium)mathspace))?)\s*' }

linestyle = "none" | "solid" | "dashed"

verticalalign =
      "top" |
      "bottom" |
      "center" |
      "baseline" |
      "axis"

columnalignstyle = "left" | "center" | "right"

notationstyle =
     "longdiv" |
     "actuarial" |
     "radical" |
     "box" |
     "roundedbox" |
     "circle" |
     "left" |
     "right" |
     "top" |
     "bottom" |
     "updiagonalstrike" |
     "downdiagonalstrike" |
     "verticalstrike" |
     "horizontalstrike" |
     "madruwb"

idref = text
unsigned-integer = xsd:unsignedLong
integer = xsd:integer
number = xsd:decimal

character = xsd:string {
  pattern = '\s*\S\s*'}

color =  xsd:string {
  pattern = '\s*((#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?)|[aA][qQ][uU][aA]|[bB][lL][aA][cC][kK]|[bB][lL][uU][eE]|[fF][uU][cC][hH][sS][iI][aA]|[gG][rR][aA][yY]|[gG][rR][eE][eE][nN]|[lL][iI][mM][eE]|[mM][aA][rR][oO][oO][nN]|[nN][aA][vV][yY]|[oO][lL][iI][vV][eE]|[pP][uU][rR][pP][lL][eE]|[rR][eE][dD]|[sS][iI][lL][vV][eE][rR]|[tT][eE][aA][lL]|[wW][hH][iI][tT][eE]|[yY][eE][lL][lL][oO][wW])\s*'}


group-alignment = "left" | "center" | "right" | "decimalpoint"
group-alignment-list = list {group-alignment+}
group-alignment-list-list = xsd:string {
  pattern = '(\s*\{\s*(left|center|right|decimalpoint)(\s+(left|center|right|decimalpoint))*\})*\s*' }
positive-integer = xsd:positiveInteger


TokenExpression = mi|mn|mo|mtext|mspace|ms

token.content = mglyph|malignmark|text

mi = element mi {mi.attributes, token.content*}
mi.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt


mn = element mn {mn.attributes, token.content*}
mn.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt


mo = element mo {mo.attributes, token.content*}
mo.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt,
  attribute form {"prefix" | "infix" | "postfix"}?,
  attribute fence {"true" | "false"}?,
  attribute separator {"true" | "false"}?,
  attribute lspace {length}?,
  attribute rspace {length}?,
  attribute stretchy {"true" | "false"}?,
  attribute symmetric {"true" | "false"}?,
  attribute maxsize {length | "infinity"}?,
  attribute minsize {length}?,
  attribute largeop {"true" | "false"}?,
  attribute movablelimits {"true" | "false"}?,
  attribute accent {"true" | "false"}?,
  attribute linebreak {"auto" | "newline" | "nobreak" | "goodbreak" | "badbreak"}?,
  attribute lineleading {length}?,
  attribute linebreakstyle {"before" | "after" | "duplicate" | "infixlinebreakstyle"}?,
  attribute linebreakmultchar {text}?,
  attribute indentalign {"left" | "center" | "right" | "auto" | "id"}?,
  attribute indentshift {length}?,
  attribute indenttarget {idref}?,
  attribute indentalignfirst {"left" | "center" | "right" | "auto" | "id" | "indentalign"}?,
  attribute indentshiftfirst {length | "indentshift"}?,
  attribute indentalignlast {"left" | "center" | "right" | "auto" | "id" | "indentalign"}?,
  attribute indentshiftlast {length | "indentshift"}?


# changed mtext content model to use mtext.content instead of generic
# token.content, because we want to handle mtext differently than other
# MathML "token elements" -- mike
mtext = element mtext { mtext.attributes, mtext.content* }
mtext.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt

mtext.content = mglyph | malignmark | text

mspace = element mspace {mspace.attributes, empty}
mspace.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt,
  attribute width {length}?,
  attribute height {length}?,
  attribute depth {length}?,
  attribute linebreak {"auto" | "newline" | "nobreak" | "goodbreak" | "badbreak" | "indentingnewline"}?,
  attribute indentalign {"left" | "center" | "right" | "auto" | "id"}?,
  attribute indentshift {length}?,
  attribute indenttarget {idref}?,
  attribute indentalignfirst {"left" | "center" | "right" | "auto" | "id" | "indentalign"}?,
  attribute indentshiftfirst {length | "indentshift"}?,
  attribute indentalignlast {"left" | "center" | "right" | "auto" | "id" | "indentalign"}?,
  attribute indentshiftlast {length | "indentshift"}?


ms = element ms {ms.attributes, token.content*}
ms.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt,
  attribute lquote {text}?,
  attribute rquote {text}?


mglyph = element mglyph {mglyph.attributes,mglyph.deprecatedattributes,empty}
mglyph.attributes = 
  CommonAtt,  CommonPresAtt,
  attribute src {xsd:anyURI}?,
  attribute width {length}?,
  attribute height {length}?,
  attribute valign {length}?,
  attribute alt {text}?
mglyph.deprecatedattributes =
  attribute index {integer}?,
  attribute mathvariant {"normal" | "bold" | "italic" | "bold-italic" | "double-struck" | "bold-fraktur" | "script" | "bold-script" | "fraktur" | "sans-serif" | "bold-sans-serif" | "sans-serif-italic" | "sans-serif-bold-italic" | "monospace" | "initial" | "tailed" | "looped" | "stretched"}?,
  attribute mathsize {"small" | "normal" | "big" | length}?,
  DeprecatedTokenAtt

msline = element msline {msline.attributes,empty}
msline.attributes = 
  CommonAtt,  CommonPresAtt,
  attribute position {integer}?,
  attribute length {unsigned-integer}?,
  attribute leftoverhang {length}?,
  attribute rightoverhang {length}?,
  attribute mslinethickness {length | "thin" | "medium" | "thick"}?

none = element none {none.attributes,empty}
none.attributes = 
  CommonAtt,
  CommonPresAtt

mprescripts = element mprescripts {mprescripts.attributes,empty}
mprescripts.attributes = 
  CommonAtt,
  CommonPresAtt


CommonPresAtt = 
  attribute mathcolor {color}?,
  attribute mathbackground {color | "transparent"}?

TokenAtt = 
  attribute mathvariant {"normal" | "bold" | "italic" | "bold-italic" | "double-struck" | "bold-fraktur" | "script" | "bold-script" | "fraktur" | "sans-serif" | "bold-sans-serif" | "sans-serif-italic" | "sans-serif-bold-italic" | "monospace" | "initial" | "tailed" | "looped" | "stretched"}?,
  attribute mathsize {"small" | "normal" | "big" | length}?,
  attribute dir {"ltr" | "rtl"}?,
  DeprecatedTokenAtt

DeprecatedTokenAtt = 
  attribute fontfamily {text}?,
  attribute fontweight {"normal" | "bold"}?,
  attribute fontstyle {"normal" | "italic"}?,
  attribute fontsize {length}?,
  attribute color {color}?,
  attribute background {color | "transparent"}?

MalignExpression = maligngroup|malignmark

malignmark = element malignmark {malignmark.attributes, empty}
malignmark.attributes = 
  CommonAtt, CommonPresAtt,
  attribute edge {"left" | "right"}?


maligngroup = element maligngroup {maligngroup.attributes, empty}
maligngroup.attributes = 
  CommonAtt, CommonPresAtt,
  attribute groupalign {"left" | "center" | "right" | "decimalpoint"}?


PresentationExpression = TokenExpression|MalignExpression|
                         mrow|mfrac|msqrt|mroot|mstyle|merror|mpadded|mphantom|
                         mfenced|menclose|msub|msup|msubsup|munder|mover|munderover|
                         mmultiscripts|mtable|mstack|mlongdiv|maction



mrow = element mrow {mrow.attributes, MathExpression*}
mrow.attributes = 
  CommonAtt, CommonPresAtt,
  attribute dir {"ltr" | "rtl"}?


mfrac = element mfrac {mfrac.attributes, MathExpression, MathExpression}
mfrac.attributes = 
  CommonAtt, CommonPresAtt,
  attribute linethickness {length | "thin" | "medium" | "thick"}?,
  attribute numalign {"left" | "center" | "right"}?,
  attribute denomalign {"left" | "center" | "right"}?,
  attribute bevelled {"true" | "false"}?


msqrt = element msqrt {msqrt.attributes, ImpliedMrow}
msqrt.attributes = 
  CommonAtt, CommonPresAtt


mroot = element mroot {mroot.attributes, MathExpression, MathExpression}
mroot.attributes = 
  CommonAtt, CommonPresAtt


mstyle = element mstyle {mstyle.attributes, ImpliedMrow}
mstyle.attributes = 
  CommonAtt, CommonPresAtt,
  mstyle.specificattributes,
  mstyle.generalattributes,
  mstyle.deprecatedattributes

mstyle.specificattributes =
  attribute scriptlevel {integer}?,
  attribute displaystyle {"true" | "false"}?,
  attribute scriptsizemultiplier {number}?,
  attribute scriptminsize {length}?,
  attribute infixlinebreakstyle {"before" | "after" | "duplicate"}?,
  attribute decimalpoint {character}?

mstyle.generalattributes =
  attribute accent {"true" | "false"}?,
  attribute accentunder {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?,
  attribute alignmentscope {list {("true" | "false") +}}?,
  attribute bevelled {"true" | "false"}?,
  attribute charalign {"left" | "center" | "right"}?,
  attribute charspacing {length | "loose" | "medium" | "tight"}?,
  attribute close {text}?,
  attribute columnalign {list {columnalignstyle+} }?,
  attribute columnlines {list {linestyle +}}?,
  attribute columnspacing {list {(length) +}}?,
  attribute columnspan {positive-integer}?,
  attribute columnwidth {list {("auto" | length | "fit") +}}?,
  attribute crossout {list {("none" | "updiagonalstrike" | "downdiagonalstrike" | "verticalstrike" | "horizontalstrike")*}}?,
  attribute denomalign {"left" | "center" | "right"}?,
  attribute depth {length}?,
  attribute dir {"ltr" | "rtl"}?,
  attribute edge {"left" | "right"}?,
  attribute equalcolumns {"true" | "false"}?,
  attribute equalrows {"true" | "false"}?,
  attribute fence {"true" | "false"}?,
  attribute form {"prefix" | "infix" | "postfix"}?,
  attribute frame {linestyle}?,
  attribute framespacing {list {length, length}}?,
  attribute groupalign {group-alignment-list-list}?,
  attribute height {length}?,
  attribute indentalign {"left" | "center" | "right" | "auto" | "id"}?,
  attribute indentalignfirst {"left" | "center" | "right" | "auto" | "id" | "indentalign"}?,
  attribute indentalignlast {"left" | "center" | "right" | "auto" | "id" | "indentalign"}?,
  attribute indentshift {length}?,
  attribute indentshiftfirst {length | "indentshift"}?,
  attribute indentshiftlast {length | "indentshift"}?,
  attribute indenttarget {idref}?,
  attribute largeop {"true" | "false"}?,
  attribute leftoverhang {length}?,
  attribute length {unsigned-integer}?,
  attribute linebreak {"auto" | "newline" | "nobreak" | "goodbreak" | "badbreak"}?,
  attribute linebreakmultchar {text}?,
  attribute linebreakstyle {"before" | "after" | "duplicate" | "infixlinebreakstyle"}?,
  attribute lineleading {length}?,
  attribute linethickness {length | "thin" | "medium" | "thick"}?,
  attribute location {"w" | "nw" | "n" | "ne" | "e" | "se" | "s" | "sw"}?,
  attribute longdivstyle {"lefttop" | "stackedrightright" | "mediumstackedrightright" | "shortstackedrightright" | "righttop" | "left/\right" | "left)(right" | ":right=right" | "stackedleftleft" | "stackedleftlinetop"}?,
  attribute lquote {text}?,
  attribute lspace {length}?,
  attribute mathsize {"small" | "normal" | "big" | length}?,
  attribute mathvariant {"normal" | "bold" | "italic" | "bold-italic" | "double-struck" | "bold-fraktur" | "script" | "bold-script" | "fraktur" | "sans-serif" | "bold-sans-serif" | "sans-serif-italic" | "sans-serif-bold-italic" | "monospace" | "initial" | "tailed" | "looped" | "stretched"}?,
  attribute maxsize {length | "infinity"}?,
  attribute minlabelspacing {length}?,
  attribute minsize {length}?,
  attribute movablelimits {"true" | "false"}?,
  attribute mslinethickness {length | "thin" | "medium" | "thick"}?,
  attribute notation {text}?,
  attribute numalign {"left" | "center" | "right"}?,
  attribute open {text}?,
  attribute position {integer}?,
  attribute rightoverhang {length}?,
  attribute rowalign {list {verticalalign+} }?,
  attribute rowlines {list {linestyle +}}?,
  attribute rowspacing {list {(length) +}}?,
  attribute rowspan {positive-integer}?,
  attribute rquote {text}?,
  attribute rspace {length}?,
  attribute selection {positive-integer}?,
  attribute separator {"true" | "false"}?,
  attribute separators {text}?,
  attribute shift {integer}?,
  attribute side {"left" | "right" | "leftoverlap" | "rightoverlap"}?,
  attribute stackalign {"left" | "center" | "right" | "decimalpoint"}?,
  attribute stretchy {"true" | "false"}?,
  attribute subscriptshift {length}?,
  attribute superscriptshift {length}?,
  attribute symmetric {"true" | "false"}?,
  attribute valign {length}?,
  attribute width {length}?

mstyle.deprecatedattributes =
  DeprecatedTokenAtt,
  attribute veryverythinmathspace {length}?,
  attribute verythinmathspace {length}?,
  attribute thinmathspace {length}?,
  attribute mediummathspace {length}?,
  attribute thickmathspace {length}?,
  attribute verythickmathspace {length}?,
  attribute veryverythickmathspace {length}?

math.attributes &= CommonPresAtt
math.attributes &= mstyle.specificattributes
math.attributes &= mstyle.generalattributes




merror = element merror {merror.attributes, ImpliedMrow}
merror.attributes = 
  CommonAtt, CommonPresAtt


mpadded = element mpadded {mpadded.attributes, ImpliedMrow}
mpadded.attributes = 
  CommonAtt, CommonPresAtt,
  attribute height {mpadded-length}?,
  attribute depth {mpadded-length}?,
  attribute width {mpadded-length}?,
  attribute lspace {mpadded-length}?,
  attribute voffset {mpadded-length}?


mphantom = element mphantom {mphantom.attributes, ImpliedMrow}
mphantom.attributes = 
  CommonAtt, CommonPresAtt


mfenced = element mfenced {mfenced.attributes, MathExpression*}
mfenced.attributes = 
  CommonAtt, CommonPresAtt,
  attribute open {text}?,
  attribute close {text}?,
  attribute separators {text}?


menclose = element menclose {menclose.attributes, ImpliedMrow}
menclose.attributes = 
  CommonAtt, CommonPresAtt,
  attribute notation {text}?


msub = element msub {msub.attributes, MathExpression, MathExpression}
msub.attributes = 
  CommonAtt, CommonPresAtt,
  attribute subscriptshift {length}?


msup = element msup {msup.attributes, MathExpression, MathExpression}
msup.attributes = 
  CommonAtt, CommonPresAtt,
  attribute superscriptshift {length}?


msubsup = element msubsup {msubsup.attributes, MathExpression, MathExpression, MathExpression}
msubsup.attributes = 
  CommonAtt, CommonPresAtt,
  attribute subscriptshift {length}?,
  attribute superscriptshift {length}?


munder = element munder {munder.attributes, MathExpression, MathExpression}
munder.attributes = 
  CommonAtt, CommonPresAtt,
  attribute accentunder {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?


mover = element mover {mover.attributes, MathExpression, MathExpression}
mover.attributes = 
  CommonAtt, CommonPresAtt,
  attribute accent {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?


munderover = element munderover {munderover.attributes, MathExpression, MathExpression, MathExpression}
munderover.attributes = 
  CommonAtt, CommonPresAtt,
  attribute accent {"true" | "false"}?,
  attribute accentunder {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?


mmultiscripts = element mmultiscripts {mmultiscripts.attributes, MathExpression,MultiScriptExpression*,(mprescripts,MultiScriptExpression*)?}
mmultiscripts.attributes = 
  msubsup.attributes


mtable = element mtable {mtable.attributes, TableRowExpression*}
mtable.attributes = 
  CommonAtt, CommonPresAtt,
  attribute align {xsd:string {
    pattern ='\s*(top|bottom|center|baseline|axis)(\s+-?[0-9]+)?\s*'}}?,
  attribute rowalign {list {verticalalign+} }?,
  attribute columnalign {list {columnalignstyle+} }?,
  attribute groupalign {group-alignment-list-list}?,
  attribute alignmentscope {list {("true" | "false") +}}?,
  attribute columnwidth {list {("auto" | length | "fit") +}}?,
  attribute width {"auto" | length}?,
  attribute rowspacing {list {(length) +}}?,
  attribute columnspacing {list {(length) +}}?,
  attribute rowlines {list {linestyle +}}?,
  attribute columnlines {list {linestyle +}}?,
  attribute frame {linestyle}?,
  attribute framespacing {list {length, length}}?,
  attribute equalrows {"true" | "false"}?,
  attribute equalcolumns {"true" | "false"}?,
  attribute displaystyle {"true" | "false"}?,
  attribute side {"left" | "right" | "leftoverlap" | "rightoverlap"}?,
  attribute minlabelspacing {length}?


mlabeledtr = element mlabeledtr {mlabeledtr.attributes, TableCellExpression+}
mlabeledtr.attributes = 
  mtr.attributes


mtr = element mtr {mtr.attributes, TableCellExpression*}
mtr.attributes = 
  CommonAtt, CommonPresAtt,
  attribute rowalign {"top" | "bottom" | "center" | "baseline" | "axis"}?,
  attribute columnalign {list {columnalignstyle+} }?,
  attribute groupalign {group-alignment-list-list}?


mtd = element mtd {mtd.attributes, ImpliedMrow}
mtd.attributes = 
  CommonAtt, CommonPresAtt,
  attribute rowspan {positive-integer}?,
  attribute columnspan {positive-integer}?,
  attribute rowalign {"top" | "bottom" | "center" | "baseline" | "axis"}?,
  attribute columnalign {columnalignstyle}?,
  attribute groupalign {group-alignment-list}?


mstack = element mstack {mstack.attributes, MstackExpression*}
mstack.attributes = 
  CommonAtt, CommonPresAtt,
  attribute align {xsd:string {
    pattern ='\s*(top|bottom|center|baseline|axis)(\s+-?[0-9]+)?\s*'}}?,
  attribute stackalign {"left" | "center" | "right" | "decimalpoint"}?,
  attribute charalign {"left" | "center" | "right"}?,
  attribute charspacing {length | "loose" | "medium" | "tight"}?


mlongdiv = element mlongdiv {mlongdiv.attributes, MstackExpression,MstackExpression,MstackExpression+}
mlongdiv.attributes = 
  msgroup.attributes,
  attribute longdivstyle {"lefttop" | "stackedrightright" | "mediumstackedrightright" | "shortstackedrightright" | "righttop" | "left/\right" | "left)(right" | ":right=right" | "stackedleftleft" | "stackedleftlinetop"}?


msgroup = element msgroup {msgroup.attributes, MstackExpression*}
msgroup.attributes = 
  CommonAtt, CommonPresAtt,
  attribute position {integer}?,
  attribute shift {integer}?


msrow = element msrow {msrow.attributes, MsrowExpression*}
msrow.attributes = 
  CommonAtt, CommonPresAtt,
  attribute position {integer}?


mscarries = element mscarries {mscarries.attributes, (MsrowExpression|mscarry)*}
mscarries.attributes = 
  CommonAtt, CommonPresAtt,
  attribute position {integer}?,
  attribute location {"w" | "nw" | "n" | "ne" | "e" | "se" | "s" | "sw"}?,
  attribute crossout {list {("none" | "updiagonalstrike" | "downdiagonalstrike" | "verticalstrike" | "horizontalstrike")*}}?,
  attribute scriptsizemultiplier {number}?


mscarry = element mscarry {mscarry.attributes, MsrowExpression*}
mscarry.attributes = 
  CommonAtt, CommonPresAtt,
  attribute location {"w" | "nw" | "n" | "ne" | "e" | "se" | "s" | "sw"}?,
  attribute crossout {list {("none" | "updiagonalstrike" | "downdiagonalstrike" | "verticalstrike" | "horizontalstrike")*}}?


maction = element maction {maction.attributes, MathExpression+}
maction.attributes = 
  CommonAtt, CommonPresAtt,
  attribute actiontype {text},
  attribute selection {positive-integer}?
