tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mathvariant-transforms.py (8671B)


      1 #!/usr/bin/env python3
      2 
      3 from lxml import etree
      4 from utils.misc import downloadWithProgressBar, UnicodeXMLURL
      5 from utils import mathfont
      6 
      7 # Retrieve the unicode.xml file if necessary.
      8 unicodeXML = downloadWithProgressBar(UnicodeXMLURL)
      9 
     10 # Extract the mathvariants transformation.
     11 xsltTransform = etree.XSLT(etree.XML('''\
     12 <xsl:stylesheet version="1.0"
     13                       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     14  <xsl:strip-space elements="*"/>
     15  <xsl:template match="charlist">
     16    <root><xsl:apply-templates select="character"/></root>
     17  </xsl:template>
     18  <xsl:template match="character">
     19    <xsl:if test="surrogate">
     20      <entry>
     21        <xsl:attribute name="mathvariant">
     22            <xsl:value-of select="surrogate/@mathvariant"/>
     23        </xsl:attribute>
     24        <xsl:attribute name="baseChar">
     25          <xsl:value-of select="surrogate/@ref"/>
     26        </xsl:attribute>
     27        <xsl:attribute name="transformedChar">
     28          <xsl:choose>
     29            <xsl:when test="bmp">
     30              <xsl:value-of select="bmp/@ref"/>
     31            </xsl:when>
     32            <xsl:otherwise>
     33               <xsl:value-of select="@id"/>
     34            </xsl:otherwise>
     35          </xsl:choose>
     36        </xsl:attribute>
     37      </entry>
     38    </xsl:if>
     39  </xsl:template>
     40 </xsl:stylesheet>'''))
     41 
     42 # Put the mathvariant transforms into a Python structure.
     43 mathvariantTransforms = {}
     44 root = xsltTransform(etree.parse(unicodeXML)).getroot()
     45 
     46 
     47 def parseCodePoint(aHexaString):
     48    return int("0x%s" % aHexaString[1:], 16)
     49 
     50 
     51 for entry in root:
     52    mathvariant = entry.get("mathvariant")
     53    baseChar = parseCodePoint(entry.get("baseChar"))
     54    transformedChar = parseCodePoint(entry.get("transformedChar"))
     55    if mathvariant not in mathvariantTransforms:
     56        mathvariantTransforms[mathvariant] = {}
     57    mathvariantTransforms[mathvariant][baseChar] = transformedChar
     58 
     59 # There is no "isolated" mathvariant.
     60 del mathvariantTransforms["isolated"]
     61 
     62 # Automatic mathvariant uses the same transform as italic.
     63 # It is handled specially (see below).
     64 mathvariantTransforms["auto"] = mathvariantTransforms["italic"]
     65 
     66 # Create a WOFF font for each mathvariant.
     67 for mathvariant in mathvariantTransforms:
     68    if mathvariant == "auto":
     69        continue
     70    font = mathfont.create("mathvariant-%s" % mathvariant,
     71                           "Copyright (c) 2016 MathML Association")
     72    for baseChar in mathvariantTransforms[mathvariant]:
     73        if baseChar not in font:
     74            mathfont.createGlyphFromValue(font, baseChar)
     75        transformedChar = mathvariantTransforms[mathvariant][baseChar]
     76        mathfont.createGlyphFromValue(font, transformedChar)
     77    mathfont.save(font)
     78 
     79 # Common function to generate test for MathML mathvariant / CSS text-transform.
     80 
     81 
     82 def generateTestFor(mathvariant, mathml):
     83    assert mathml or mathvariant == "auto", "These tests have been removed!"
     84    print("Generating tests for %s..." % mathvariant, end="")
     85    if mathml:
     86        reftest = open(
     87            "../relations/css-styling/mathvariant-%s.html" % mathvariant, "w")
     88        reftestReference = open(
     89            "../relations/css-styling/mathvariant-%s-ref.html" % mathvariant, "w")
     90    else:
     91        reftest = open(
     92            "../../css/css-text/text-transform/math/text-transform-math-%s-001.html" % mathvariant, "w")
     93        reftestReference = open(
     94            "../../css/css-text/text-transform/math/text-transform-math-%s-001-ref.html" % mathvariant, "w")
     95    source = '\
     96 <!DOCTYPE html>\n\
     97 <html>\n\
     98 <head>\n\
     99 <meta charset="utf-8"/>\n\
    100 <title>%s</title>\n'
    101    if mathml:
    102        reftest.write(source % ("mathvariant %s" % mathvariant))
    103        reftestReference.write(
    104            source % ("mathvariant %s (reference)" % mathvariant))
    105    else:
    106        reftest.write(source % ("text-transform math-%s" % mathvariant))
    107        reftestReference.write(
    108            source % ("text-transform math-%s (reference)" % mathvariant))
    109    if mathvariant == "auto":
    110        mathAssert = "Verify that a single-char <mi> is equivalent to an <mi> with the transformed italic unicode character."
    111        mapping = "italic"
    112    else:
    113        mathAssert = "Verify that a single-char <mtext> with a %s mathvariant is equivalent to an <mtext> with the transformed unicode character." % mathvariant
    114        mapping = mathvariant
    115    if mathml:
    116        source = '\
    117 <link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">\n\
    118 <link rel="help" href="https://w3c.github.io/mathml-core/#the-mathvariant-attribute">\n\
    119 <link rel="help" href="https://w3c.github.io/mathml-core/#math-auto-transform">\n\
    120 <link rel="help" href="https://w3c.github.io/mathml-core/#%s-mappings">\n\
    121 <link rel="match" href="mathvariant-%s-ref.html"/>\n\
    122 <meta name="assert" content="%s">\n'
    123        reftest.write(source % (mapping, mathvariant, mathAssert))
    124    else:
    125        source = '\
    126 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3745"/>\n\
    127 <link rel="help" href="https://w3c.github.io/mathml-core/#math-auto-transform">\n\
    128 <link rel="help" href="https://w3c.github.io/mathml-core/#%s-mappings">\n\
    129 <link rel="match" href="text-transform-math-%s-001-ref.html"/>\n\
    130 <meta name="assert" content="Verify that a character with \'text-transform: math-%s\' renders the same as the transformed unicode character.">\n'
    131        reftest.write(source % (mapping, mathvariant, mathvariant))
    132    WOFFfont = "mathvariant-%s.woff" % mapping
    133    source = '\
    134 <style>\n\
    135  @font-face {\n\
    136    font-family: TestFont;\n\
    137    src: url("/fonts/math/%s");\n\
    138  }\n\
    139  body > span {\n\
    140    padding: 10px;\n\
    141  }\n\
    142  span > span {\n\
    143    font-family: monospace;\n\
    144    font-size: 10px;\n\
    145  }\n\
    146  .testfont {\n\
    147    font-family: TestFont;\n\
    148    font-size: 10px;\n\
    149  }\n\
    150 </style>\n\
    151 <body>\n\
    152  <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. -->\n\
    153  <p>Test passes if all the equalities below are true.</p>\n' % WOFFfont
    154    if mathml:
    155        reftest.write(source)
    156        reftestReference.write(source)
    157    else:
    158        reftest.write(source)
    159        reftestReference.write(source)
    160    charIndex = 0
    161    for baseChar in mathvariantTransforms[mathvariant]:
    162        transformedChar = mathvariantTransforms[mathvariant][baseChar]
    163        if mathvariant == "auto":
    164            tokenTag = '<mi>&#x%0X;</mi>' % baseChar
    165            tokenTagRef = '<mi>&#x%0X;</mi>' % transformedChar
    166        else:
    167            tokenTag = '<mtext mathvariant="%s">&#x%0X;</mtext>' % (
    168                mathvariant, baseChar)
    169            tokenTagRef = '<mtext>&#x%0X;</mtext>' % transformedChar
    170        if mathml:
    171            reftest.write('  <span><math class="testfont">%s</math>=<span>%05X</span></span>' %
    172                          (tokenTag, transformedChar))
    173            reftestReference.write(
    174                '  <span><math class="testfont">%s</math>=<span>%05X</span></span>' % (tokenTagRef, transformedChar))
    175        else:
    176            reftest.write('  <span><span class="testfont" style="text-transform: math-%s">&#x%0X;</span>=<span>%05X</span></span>' %
    177                          (mathvariant, baseChar, transformedChar))
    178            reftestReference.write(
    179                '  <span><span class="testfont">&#x%0X;</span>=<span>%05X</span></span>' % (transformedChar, transformedChar))
    180        charIndex += 1
    181        if charIndex % 10 == 0:
    182            reftest.write('<br/>')
    183            reftestReference.write('<br/>')
    184        reftest.write('\n')
    185        reftestReference.write('\n')
    186    source = '</body>\n</html>\n'
    187    reftest.write(source)
    188    reftestReference.write(source)
    189    reftest.close()
    190    reftestReference.close()
    191    print(" done.")
    192 
    193 
    194 # Generate css/css-text/text-transform/math/text-transform-math-auto-001.html
    195 generateTestFor(mathvariant="auto", mathml=False)
    196 generateTestFor(mathvariant="auto", mathml=True)
    197 
    198 # Generate italic_mapping.js file used by selection tests.
    199 print("Generating italic_mapping.js...", end="")
    200 italic_mapping = open("../../css/css-text/text-transform/math/italic-mapping.js", "w")
    201 italic_mapping.write("// Generated by mathml/tools/mathvariant.py; DO NOT EDIT.\n");
    202 italic_mapping.write("let italic_mapping = {\n");
    203 for baseChar in mathvariantTransforms["italic"]:
    204    transformedChar = mathvariantTransforms[mathvariant][baseChar]
    205    italic_mapping.write("  0x%0X: 0x%0X,\n" % (baseChar, transformedChar));
    206 italic_mapping.write("}\n");
    207 italic_mapping.close()
    208 print(" done.")
    209 
    210 # Other mathvariant tests can be generated by the following command. They are
    211 # still use internally by browsers implementing full mathvariant support.
    212 # See https://github.com/w3c/mathml-core/issues/182
    213 # for mathvariant in mathvariantTransforms:
    214 #    generateTestFor(mathvariant, mathml=True)