Peter Ward avatar Peter Ward committed b4e7d65

add prettify script for pc^2

Comments (0)

Files changed (1)

content/university/pc2-prettify.rst

+Prettify script for PC^2
+########################
+:date: 2012-11-17 17:23
+:tags: pc2, progcomp, acm, icpc, script, xslt
+
+When I was doing programming competitions at uni, I wrote this script, which
+takes the default HTML output from PC^2 and add some colour to it to indicate
+passed / failed problems. Since it was written / enhanced on the day of the
+competition, there’s definitely some hacky code in there, but I’m publishing it
+so future generations can steal it for their own nefarious purposes.
+
+This code is released into the `public domain`_.
+
+.. _`public domain`: http://creativecommons.org/licenses/CC0/1.0/
+
+.. code-block:: python
+
+    # prettify.py
+
+    import re
+    import string
+    import sys
+
+    from lxml import html, etree
+
+    doc = etree.parse(open('prettify.xsl', 'rU'))
+    xslt = etree.XSLT(doc)
+
+    doc = html.parse(sys.stdin)
+
+    passed = re.compile('^[0-9]*/[1-9][0-9]*$')
+    failed = re.compile('^.*[1-9]/[-0]*$')
+
+    for node in doc.xpath('//td'):
+        text = node.text or ''
+        if passed.match(text):
+            node.attrib['class'] = 'passed'
+        elif failed.match(text):
+            node.attrib['class'] = 'failed'
+
+    problems = dict(zip(string.uppercase, [
+        'An Industrial Spy',
+        'Simple Polygon',
+        'High Score',
+        'Rankings',
+        'Wormholes',
+        'Fractal',
+        'Rewards for Math!',
+        'Divisible Subsequences',
+    ]))
+
+    for node in doc.xpath('//th/strong/u'):
+        node.text = problems.get(node.text, node.text)
+
+    doc = xslt(doc)
+
+    #body = doc.xpath('//html/body')
+    #d = etree.Element('div')
+    #d.attrib['class'] = 'timer'
+    #
+    #import sys
+    #from datetime import datetime
+    #n = datetime.now()
+    #t = datetime(2011, 9, 3, 17, 0, 0, 0)
+    #print>>sys.stderr, n - t
+
+    print html.tostring(doc)
+
+.. code-block:: xml
+
+    <!-- prettify.xsl -->
+
+    <xsl:stylesheet version="1.0"
+        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+        <xsl:variable name="stage" select="0" />
+
+        <xsl:output method="xml" indent="yes"
+            doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
+            doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />
+
+        <!-- Document structure -->
+        <xsl:template match="/">
+            <html>
+                <xsl:apply-templates select="/html/head" />
+                <xsl:apply-templates select="/html/body" />
+            </html>
+        </xsl:template>
+
+        <!-- Head for styling, etc. -->
+        <xsl:template match="/html/head">
+            <head>
+                <xsl:copy-of select="/html/head/node()" />
+                <script type="text/javascript" src="http://cornify.com/js/cornify.js"></script>
+                <!--<meta http-equiv="refresh" content="5" />-->
+                <link href="http://fonts.googleapis.com/css?family=Questrial"
+                    rel="stylesheet" type="text/css" />
+                <style type="text/css">
+                    html, body { margin: 0; padding: 0; }
+                    a { color: #729fcf; }
+                    body {
+                        font-family: 'Questrial', sans-serif;
+                        color: #eeeeec;
+                        background: #2e3436;
+                    }
+                    table { font-size: 20pt; }
+                    .passed, .failed { font-weight: bold; }
+                    .passed {
+                        background: #8ae234;
+                        color: black;
+                    }
+                    .failed {
+                        background: #ef2929;
+                        color: white;
+                    }
+
+                    h1 { text-align: center; margin: 0; }
+
+                    thead th { font-size: 12pt; }
+                    th.team-name {
+                        font-weight: normal;
+                        text-align: left;
+                    }
+
+                    th:nth-child(2) { width: 50px; }
+                    td:nth-child(4) { width: 3.5em; }
+                    td:nth-child(12) { width: 3.5em; }
+                </style>
+            </head>
+        </xsl:template>
+
+        <!-- Body -->
+        <xsl:template match="/html/body/table[1]">
+            <table id="scoreboard">
+                <thead>
+                    <tr>
+                    <xsl:for-each select="tr[1]/th">
+                        <th scope="col"><xsl:value-of select="strong/u" /></th>
+                    </xsl:for-each>
+                    </tr>
+                </thead>
+                <tbody>
+                    <xsl:for-each select="tr[position() > 2]">
+                        <tr>
+                            <!-- Rank -->
+                            <td class="rank"><xsl:value-of select="td[1]" /></td>
+                            <!-- Name -->
+                            <th class="team-name" scope="row"><xsl:value-of select="td[2]" /></th>
+                            <xsl:copy-of select="td[position() > 2]" />
+                        </tr>
+                    </xsl:for-each>
+                </tbody>
+            </table>
+        </xsl:template>
+
+        <xsl:template match="/html/body">
+            <xsl:if test="$stage >= 1">
+                <h1>Competition is over! Congratulations to all!!!</h1>
+            </xsl:if>
+            <xsl:apply-templates select="table[1]" />
+            <p>Prettify script by Peter Ward</p>
+            <xsl:if test="$stage >= 2">
+            <script type="text/javascript">
+                <![CDATA[
+                var count = 0;
+                var delay = 10000;
+                function magical() {
+                    cornify_add();
+                    count++;
+                    if (count > 60) {
+                        var child = null;
+                        var nodes = document.body.children;
+                        for (var i = 0; i < nodes.length; i++) {
+                            if (nodes[i].tagName == "DIV") {
+                                child = nodes[i];
+                                break;
+                            }
+                        }
+                        document.body.removeChild(child);
+                    }
+                    window.setTimeout(magical, delay * (Math.random() / 2.0 + 0.75));
+                    if (delay > 10)
+                        delay *= 0.9;
+                }
+                window.onload = magical;
+                ]]>
+            </script>
+            </xsl:if>
+        </xsl:template>
+    </xsl:stylesheet>
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.