We must hold the CodeBlock lock when calling StructureStubInfo::reset
[WebKit-https.git] / LayoutTests / imported / w3c / web-platform-tests / mathml / tools / mathvariant-transforms.py
1 #!/usr/bin/python
2
3 from __future__ import print_function
4 from lxml import etree
5 from utils.misc import downloadWithProgressBar, UnicodeXMLURL
6 from utils import mathfont
7
8 # Retrieve the unicode.xml file if necessary.
9 unicodeXML = downloadWithProgressBar(UnicodeXMLURL)
10
11 # Extract the mathvariants transformation.
12 xsltTransform = etree.XSLT(etree.XML('''\
13 <xsl:stylesheet version="1.0"
14                        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
15   <xsl:strip-space elements="*"/>
16   <xsl:template match="charlist">
17     <root><xsl:apply-templates select="character"/></root>
18   </xsl:template>
19   <xsl:template match="character">
20     <xsl:if test="surrogate">
21       <entry>
22         <xsl:attribute name="mathvariant">
23             <xsl:value-of select="surrogate/@mathvariant"/>
24         </xsl:attribute>
25         <xsl:attribute name="baseChar">
26           <xsl:value-of select="surrogate/@ref"/>
27         </xsl:attribute>
28         <xsl:attribute name="transformedChar">
29           <xsl:choose>
30             <xsl:when test="bmp">
31               <xsl:value-of select="bmp/@ref"/>
32             </xsl:when>
33             <xsl:otherwise>
34                <xsl:value-of select="@id"/>
35             </xsl:otherwise>
36           </xsl:choose>
37         </xsl:attribute>
38       </entry>
39     </xsl:if>
40   </xsl:template>
41 </xsl:stylesheet>'''))
42
43 # Put the mathvariant transforms into a Python structure.
44 mathvariantTransforms = {}
45 root = xsltTransform(etree.parse(unicodeXML)).getroot()
46 def parseCodePoint(aHexaString):
47     return int("0x%s" % aHexaString[1:], 16)
48 for entry in root:
49     mathvariant = entry.get("mathvariant")
50     baseChar = parseCodePoint(entry.get("baseChar"))
51     transformedChar = parseCodePoint(entry.get("transformedChar"))
52     if mathvariant not in mathvariantTransforms:
53         mathvariantTransforms[mathvariant] = {}
54     mathvariantTransforms[mathvariant][baseChar] = transformedChar
55
56 # There is no "isolated" mathvariant.
57 del mathvariantTransforms["isolated"]
58
59 # Automatic mathvariant uses the same transform as italic.
60 # It is handled specially (see below).
61 mathvariantTransforms["auto"] = mathvariantTransforms["italic"]
62
63 # Create a WOFF font for each mathvariant.
64 for mathvariant in mathvariantTransforms:
65     if mathvariant == "auto":
66         continue
67     font = mathfont.create("mathvariant-%s" % mathvariant)
68     for baseChar in mathvariantTransforms[mathvariant]:
69         if baseChar not in font:
70             mathfont.createGlyphFromValue(font, baseChar)
71         transformedChar = mathvariantTransforms[mathvariant][baseChar]
72         mathfont.createGlyphFromValue(font, transformedChar)
73     mathfont.save(font)
74
75 # Create a MathML and CSS test for each mathvariant.
76 for mathvariant in mathvariantTransforms:
77     print("Generating tests for %s..." % mathvariant, end="")
78     reftest = open("../relations/css-styling/mathvariant-%s.html" % mathvariant, "w")
79     reftestReference = open("../relations/css-styling/mathvariant-%s-ref.html" % mathvariant, "w")
80     CSSreftest = open("../../css/css-text/text-transform/math/text-transform-math-%s-001.tentative.html" % mathvariant, "w")
81     CSSreftestReference = open("../../css/css-text/text-transform/math/text-transform-math-%s-001.tentative-ref.html" % mathvariant, "w")
82     source = '\
83 <!DOCTYPE html>\n\
84 <html>\n\
85 <head>\n\
86 <meta charset="utf-8"/>\n\
87 <title>%s</title>\n'
88     reftest.write(source % ("mathvariant %s" % mathvariant))
89     reftestReference.write(source % ("mathvariant %s (reference)" % mathvariant))
90     CSSreftest.write(source % ("text-transform math-%s" % mathvariant))
91     CSSreftestReference.write(source % ("text-transform math-%s (reference)" % mathvariant))
92     if mathvariant == "auto":
93         mathAssert = "Verify that a single-char <mi> is equivalent to an <mi> with the transformed italic unicode character."
94         mapping = "italic"
95     else:
96         mathAssert = "Verify that a single-char <mtext> with a %s mathvariant is equivalent to an <mtext> with the transformed unicode character." % mathvariant
97         mapping = mathvariant
98     source ='\
99 <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#css-styling">\n\
100 <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#the-mathvariant-attribute">\n\
101 <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values">\n\
102 <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#%s-mappings">\n\
103 <link rel="match" href="mathvariant-%s-ref.html"/>\n\
104 <meta name="assert" content="%s">\n'
105     reftest.write(source % (mapping, mathvariant, mathAssert))
106     source = '\
107 <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/3745"/>\n\
108 <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#new-text-transform-values">\n\
109 <link rel="help" href="https://mathml-refresh.github.io/mathml-core/#%s-mappings">\n\
110 <link rel="match" href="text-transform-math-%s-001.tentative-ref.html"/>\n\
111 <meta name="assert" content="Verify that a character with \'text-transform: math-%s\' renders the same as the transformed unicode character.">\n'
112     CSSreftest.write(source % (mapping, mathvariant, mathvariant))
113     WOFFfont = "mathvariant-%s.woff" % mapping
114     source = '\
115 <style>\n\
116   @font-face {\n\
117     font-family: TestFont;\n\
118     src: url("/fonts/math/%s");\n\
119   }\n\
120   body > span {\n\
121     padding: 10px;\n\
122   }\n\
123   span > span {\n\
124     font-family: monospace;\n\
125     font-size: 10px;\n\
126   }\n\
127   .testfont {\n\
128     font-family: TestFont;\n\
129     font-size: 10px;\n\
130   }\n\
131 </style>\n\
132 <body>\n\
133   <!-- Generated by mathml/tools/mathvariant.py; DO NOT EDIT. -->\n\
134   <p>Test passes if all the equalities below are true.</p>\n' % WOFFfont
135     reftest.write(source)
136     reftestReference.write(source)
137     CSSreftest.write(source)
138     CSSreftestReference.write(source)
139     charIndex = 0
140     for baseChar in mathvariantTransforms[mathvariant]:
141         transformedChar = mathvariantTransforms[mathvariant][baseChar]
142         if mathvariant == "auto":
143             tokenTag = '<mi>&#x%0X;</mi>' % baseChar
144             tokenTagRef = '<mi>&#x%0X;</mi>' % transformedChar
145         else:
146             tokenTag = '<mtext mathvariant="%s">&#x%0X;</mtext>' % (mathvariant, baseChar)
147             tokenTagRef = '<mtext>&#x%0X;</mtext>' % transformedChar
148         reftest.write('  <span><math class="testfont">%s</math>=<span>%05X</span></span>' % (tokenTag, transformedChar))
149         reftestReference.write('  <span><math class="testfont">%s</math>=<span>%05X</span></span>' % (tokenTagRef, transformedChar))
150         CSSreftest.write('  <span><span class="testfont" style="text-transform: math-%s">&#x%0X;</span>=<span>%05X</span></span>' % (mathvariant, baseChar, transformedChar))
151         CSSreftestReference.write('  <span><span class="testfont">&#x%0X;</span>=<span>%05X</span></span>' % (transformedChar, transformedChar))
152         charIndex += 1
153         if charIndex % 10 == 0:
154             reftest.write('<br/>')
155             reftestReference.write('<br/>')
156             CSSreftest.write('<br/>')
157             CSSreftestReference.write('<br/>')
158         reftest.write('\n')
159         reftestReference.write('\n')
160         CSSreftest.write('\n')
161         CSSreftestReference.write('\n')
162     source = '</body>\n</html>\n'
163     reftest.write(source)
164     reftestReference.write(source)
165     CSSreftest.write(source)
166     CSSreftestReference.write(source)
167     reftest.close()
168     reftestReference.close()
169     CSSreftest.close()
170     CSSreftestReference.close()
171     print(" done.")