ArkML/Codec implementations

From ARK Wiki
Jump to navigation Jump to search

Converting to HTML

Converting to HTML makes it easy to display ArkML on HTML based renderers, such as an embedded Webkit or MozEmbed.

XSLT 1.0

XSLT is a universal XML transformation language, and should be used in all programming environments in favor of language specific procedural transformations.

No XSLT 2.0 features are required for this transformation.

Note: XSLT only operates on XML. You must first convert the SGML to XML - which is generally a simple process. For command line environments see the "osx" utility.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes"/>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="RichColor">
    <span>
      <xsl:apply-templates select="@* | node()"/>
    </span>
  </xsl:template>
  <xsl:template match="RichColor/@Color">
    <xsl:attribute name="style">
      <xsl:value-of select="concat(
        'color: rgba(',
        round(substring-before(., ',') * 255),
        ', ',
        round(substring-before(substring-after(., ','), ',') * 255),
        ', ',
        round(substring-before(substring-after(substring-after(., ','), ','), ',') * 255),
        ', ',
        substring-after(substring-after(substring-after(., ','), ','), ',') * 1,
        ');'
      )"/>
    </xsl:attribute>
  </xsl:template>
  <xsl:template match="text()" name="br">
    <xsl:param name="str" select="."/>
    <xsl:choose>
      <xsl:when test="not(contains($str, '&#xA;'))">
        <xsl:copy-of select="$str"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="substring-before($str, '&#xA;')"/>
        <br />
        <xsl:call-template name="br">
          <xsl:with-param name="str" select="substring-after($str, '&#xA;')"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Python 3 using LXML and BeautifulSoup

You will need two PyPI packages: lxml and beautifulsoup4.

First we need to create the XSLT transformer to avoid creating it every time we parse ArkML. "xsltstr" is a string (or bytes) that contain the XSLT code above.

from lxml import etree
transform = etree.XSLT(etree.fromstring(xsltstr))

Now we parse the ArkML data. "arkmlstr" is a string (or bytes) containing the input ArkML data. The input must be wrapped in span elements as XSLT only operates on XML documents (APIs that let you apply XSLT transformations on XML fragments secretly add a nothing document around the fragment, but in python this is done explicitly). The output ("htmlspan") will be an LXML object containing an HTML span element. This code usually does parse SGML by automatically choosing any available SGML parser installed in the Python installation.

from lxml.html import soupparser
htmlspan = transform(soupparser.fromstring(b"<span>" + arkmlstr.replace(b'&', b'&#x26;') + b"</span>", features="xml")[0])

And then you can convert it back to a bytes / string:

print(b''.join([etree.tostring(c) for c in htmlspan.getroot().iterdescendants()]))