Skip to content

Make MathML attributes ASCII case-insensitive #178

Closed

Description

@fred-wang

This is a follow-up of #22 ; we decided to follow HTML/CSS which treat things as ASCII case-insensitive. Concretely, ftp://ftp.unicode.org/Public/UNIDATA/CaseFolding.txt has this line:

017F; C; 0073; # LATIN SMALL LETTER LONG S

which means that falſe is case-insensitively equal to false. However, it is not ASCII case-insensitively equal to false (only a-z <-> A-Z equivalence are considered in that case).

Currently, the MathML Core spec just says "case-insensitive".

Note: for CSS colors, I reported w3c/csswg-drafts#4599

Activity

  1. added
    css / html5Issues related to CSS or HTML5 interoperability
    MathML CoreIssues affecting the MathML Core specification
    need resolutionIssues needing resolution at MathML Refresh CG meeting
    need testsIssues related to writing WPT tests
    on Dec 13, 2019
  2. fred-wang commented on Dec 16, 2019

    @fred-wang
    Author

    I did a quick check and for the MathML-specific definitions, I only see case-insensitive against strings with ASCII letters and dashes. So the only difference would be for "LATIN SMALL LETTER LONG S", "KELVIN SIGN" and maybe a few "LATIN SMALL LIGATURE" (e.g. double-STruck). Unlikely for "LATIN CAPITAL LETTER I WITH DOT ABOVE" if the Turkish rule is used. See w3c/csswg-drafts#4599 (comment)

  3. NSoiffer commented on Dec 16, 2019

    @NSoiffer
    Contributor

    That's a good catch. I'm pretty sure we all agree that we only mean ASCII case-insensitivity. I suggest we add the following to the spec, which is a slight rewording from the HTML spec:

    Many strings in the HTML and CSS syntax (e.g. the names of elements and their attributes) are case-insensitive, but only for ASCII upper alphas and ASCII lower alphas. For convenience, in this specification this is just referred to as "case-insensitive".

    I suggest this goes into Appendix G.1: Document Conventions.

  4. fred-wang commented on Dec 16, 2019

    @fred-wang
    Author

    I would prefer to be explicit everywhere and use "ASCII case-insensitive" with a link to https://infra.spec.whatwg.org/#ascii-case-insensitive ; this seems to be what the HTML and CSS specifications do (or how they would be fixed it e.g. w3c/csswg-drafts#4599 (comment)). I'm sure if we just keep case-insensitive as it is now, people will easily not read the appendix. We should also avoid duplicating definition from HTML5 as it was mentioned in another issue.

  5. fred-wang commented on Dec 17, 2019

    @fred-wang
    Author

    Consensus from 2019/12/16: Move to ASCII case-insensitiveness

  6. fred-wang commented on Dec 17, 2019

    @fred-wang
    Author

    These are the attributes, with the behavior changes that will require tests:

    • boolean attributes: Behavior change for falSe.
    • dir: No behavior change.
    • mathvariant: Behavior change for e.g. double-StrucK
    • display: Behavior change for blocK.
    • form: Behavior change for poStfix.
    • notation: Behavior change for e.g. updiagonalStriKe
    • frame: Behavior change for e.g. daShed

    Other attributes rely on CSS ( https://mathml-refresh.github.io/mathml-core/#types-for-mathml-attribute-values ) so nothing is changed here (although tests can always be added).

  7. davidcarlisle commented on Dec 17, 2019

    @davidcarlisle
    Collaborator

    If we want to keep the relax schema there are two choices either we could say in words that values should be ascii-lowercased before validation or we could make the schema do the case insensitive match.

    That would mean for example changing

    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"}?,
    

    to

    attribute mathvariant {xsd:string{pattern="[Nn][Oo][Rr][Mm][Aa][Ll]|[Bb][Oo][Ll][Dd]|[Ii][Tt][Aa][Ll][Ii][Cc]|[Bb][Oo][Ll][Dd]-[Ii][Tt][Aa][Ll][Ii][Cc]|[Dd][Oo][Uu][Bb][Ll][Ee]-[Ss][Tt][Rr][Uu][Cc][Kk]|[Bb][Oo][Ll][Dd]-[Ff][Rr][Aa][Kk][Tt][Uu][Rr]|[Ss][Cc][Rr][Ii][Pp][Tt]|[Bb][Oo][Ll][Dd]-[Ss][Cc][Rr][Ii][Pp][Tt]|[Ff][Rr][Aa][Kk][Tt][Uu][Rr]|[Ss][Aa][Nn][Ss]-[Ss][Ee][Rr][Ii][Ff]|[Bb][Oo][Ll][Dd]-[Ss][Aa][Nn][Ss]-[Ss][Ee][Rr][Ii][Ff]|[Ss][Aa][Nn][Ss]-[Ss][Ee][Rr][Ii][Ff]-[Ii][Tt][Aa][Ll][Ii][Cc]|[Ss][Aa][Nn][Ss]-[Ss][Ee][Rr][Ii][Ff]-[Bb][Oo][Ll][Dd]-[Ii][Tt][Aa][Ll][Ii][Cc]|[Mm][Oo][Nn][Oo][Ss][Pp][Aa][Cc][Ee]|[Ii][Nn][Ii][Tt][Ii][Aa][Ll]|[Tt][Aa][Ii][Ll][Ee][Dd]|[Ll][Oo][Oo][Pp][Ee][Dd]|[Ss][Tt][Rr][Ee][Tt][Cc][Hh][Ee][Dd]"}}?,
    

    which works but isn't very human readable or informative.

    Since we already need some pre-processing described in words to allow data-foo attributes (or onfoo attributes to be ignored, I'm tempted to suggest we keep the existing string match but could be persuaded otherwise....

  8. 23 remaining items

  9. davidcarlisle commented on Nov 22, 2024

    @davidcarlisle
    Collaborator

    I don't think we need to say this in so many places, just in the definition of the types such as boolean and length-percentage, we already specify the type of all attributes

  10. NSoiffer commented on Nov 22, 2024

    @NSoiffer
    Contributor

    We don't (currently) have a type "boolean", at least not in the main text. Types are defined here. I only see it defined for the schema.

    Take a look at the table attributes: there are a lot that take on string values and it seems that every one of them needs to say they are ASCII-case insensitive. Most elements don't have that many attributes, but most elements do have attribute values that take on string values that should be ASCII-case insensitive.

    Am I misunderstanding which should be ASCII-case insensitive?

  11. davidcarlisle commented on Nov 22, 2024

    @davidcarlisle
    Collaborator

    @NSoiffer sorry I shouldn't answer before coffee.

    I had in mind that there were some "custom enumerations" like mathvariant that didn't use a defined type, but I'd forgottem about all the table ones. Also we seem to mark all the booleans as "true" | "false" (copied over from MathML3) I think for those we should globally edit to reference a defined boolean type at the place you give.

    It might also be possible to define "enumeration" in that chapter 2 types list, defined as an ascii case-insensitive list and state there that all attributes given as a | list of possible strings are ascii case-insensitive.

  12. NSoiffer commented on Nov 25, 2024

    @NSoiffer
    Contributor

    With David's PR, the boolean values are now ASCII case-insensitive match. He claims (I haven't verified), that Full is now in-sync with Core wrt attribute value case sensitivity. The open question remains: do we want to make all the other "enumeration" types such as the table attrs mentioned above case sensitive or case insensitive?

    The easy path is to leave things as they are now, which is what V3 says in "2.1.5.3 Color Valued Attributes"

    Note that the color name keywords are not case-sensitive, unlike most keywords in MathML attribute values, for compatibility with CSS and HTML.

    That statement is not in a great place for people to find...

    MathML 4 is currently silent on case-sensitivity except for (now) boolean values and for concept names. Taking the easy compatible path is to add a line somewhere saying unless otherwise specified all attribute values are case-sensitive.

    The breaking change (which we sort have done with boolean values to be compatible with HTML), it to track down all the instances where they should change to be ASCII case-insensitive match, and make the changes there.

    Thoughts?

  13. dginev commented on Nov 25, 2024

    @dginev
    Member

    I think lengths could also be case-insensitive for CSS+HTML compatibility.

    • 1em; 1eM; 1EM; etc.
    • also auto and AUTO

    As David suggests the enumerable types are also good candidates, since normalized matching won't introduce any new side-effects. We could even try to generalize there, with a statement like "all matches on 'enumerated' attribute values are ascii case-insensitive" ? As long as we define that category clearly...

  14. davidcarlisle commented on Mar 15, 2025

    @davidcarlisle
    Collaborator

    This is a fairly old PR and I'm just reviewing the current state. Which is (I think)

    booleans link to a mathml definition of boolean https://w3c.github.io/mathml/#fund_attval which is ascii case insensitive

    colors and lengths defer to CSS definitions, which are ascii case insensitive

    So the remaining ones are mostly the custom enumerations on mtable which are not in core
    https://w3c.github.io/mathml/#presm_tabmat
    so things like rowalign="Top BOTTOM BaseLine"
    making them case insensitive complicates the polyfills a bit (just need to lowercase) and complicates the schema quite a bit (if we want to make these schema valid rather than just operationaly say systems should asct as if lowercasing)

    I don't really mind either way but wanted to get explicit group decision before doing anything

    in the schema if we want to make these valid

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

    would need to be something like

    verticalalign= xsd:string {
      pattern = '\s*([tT][oO][pP]|[bB][oO][tT][tT][oO][mM]|[cC][eE]....)\s*' 
    }
    

    which doesn't exactly make it more readable.

  15. self-assigned this
    on Apr 3, 2025
  16. dginev commented on Dec 10, 2025

    @dginev
    Member

    If schema readability is a concern, one idea is to chunk into intermediate rules to keep the higher level structure clean. Something like:

    verticalalign =
      top_i |
      bottom_i |
      center_i |
      baseline_i |
      axis_i
    
    top_i = xsd:string {
      pattern = '[tT][oO][pP]'
    }
    bottom_i = xsd:string {
      pattern = '[bB][oO][tT][tT][oO][mM]'
    }
    center_i = xsd:string { 
      pattern = '[cC][eE][nN][tT][eE][rR]'
    }
    baseline_i = xsd:string {
      pattern = '[bB][aA][sS][eE][lL][iI][nN][eE]'
    }
    axis_i = xsd:string {
      pattern = '[aA][xX][iI][sS]'
    }
    

    (FWIW, the copilot tools are quite good with auto-completing such patterns)

  17. NSoiffer commented on Dec 11, 2025

    @NSoiffer
    Contributor

    It would be odd to have some values case-insensitive and others not case-insensitive. I know that one can say "this is in core" and "this is not in core" and that's why, but I don't think that's a good reason.

  18. dginev commented on Dec 11, 2025

    @dginev
    Member

    Which values do you have in mind with "some values"? I think we agreed to make all attributes with enumerated values ASCII case-insensitive. Which others are candidates?

  19. NSoiffer commented on Dec 13, 2025

    @NSoiffer
    Contributor

    Just for the record, this was discussed in the meeting on 11 Dec and David agreed all enumerated values should be ASCII case-insensitive. As mentioned in a comment on the PR, are there any content MathML values that need to say this such as "type"?

  20. davidcarlisle commented on Dec 13, 2025

    @davidcarlisle
    Collaborator

    @NSoiffer I think this should only apply to presentation elements, making content mathml type attribute such as <cn type="real" case insensitive would be highly disruptive breaking existing implementations and mappings to OpenMath, for no clear benefit

  21. NSoiffer commented on Feb 19, 2026

    @NSoiffer
    Contributor

    Sounds reasonable. Can we close?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

MathML 4Issues affecting the MathML 4 specificationcss / html5Issues related to CSS or HTML5 interoperabilityneed specification updateIssues requiring specification changes

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions