Tutorial time: creating Happy HTML
Imagine you want HTML5, but not … normal HTML5. You want … happy HTML5.
In this context, "happyhtml" means an HTML build process that wants you to be happy. It already knows what options you want. It knows that you pretty much always turn on draft output. It knows that you always use your own CSS file. And most importantly, it knows that your HTML5 output should smile.
To do this, we need to set up a plugin.
This plugin will do a few relatively simple things:
- Declare a new transform type, "happyhtml", and give the plugin an ID like
org.metadita.happyhtml
- Provide the Ant code to run that build: set your default parameters, then do The Usual.
- Provide some XSL processing to cheer up your output.
- Bundle your CSS file.
org.metadita.happyhtml
file organization
org.metadita.happyhtml\plugin.xml
org.metadita.happyhtml\happybuild.xml
org.metadita.happyhtml\css\myBrand.css
org.metadita.happyhtml\xsl\happyStyle.xsl
The plugin.xml file
This file is pretty straightforward, because in the end my plugin is pretty straightforward. It declares the "happyhtml" transform type, and then declares the Ant file that will define the build:
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="org.metadita.happyhtml">
<require plugin="org.dita.html5"/>
<transtype name="happyhtml" extends="html5" desc="HappyHTML"/>
<feature extension="dita.conductor.target.relative" file="happybuild.xml"/>
</plugin>
For a longer description of these extensions points (as well as the doc for every other extension point), see the DITA-OT developer documentation.
Setting up the "transform type"
To create a transform type of "happyhtml", we need to define an Ant target named
dita2happyhtml
. To meet our objectives, this should first call a new target to
initialize default parameters, and then call the normal HTML5 process. (For background, there's an
additional topic in the documentation that explains the dita2happyhtml
naming convention.)
To keep this (relatively) simple, I'll only set a few default parameters: turn on draft output, provide the default CSS and copy it, and set up the XSL I want to run. I could of course set a default for every HTML5 parameter, but that seems … excessive.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:dita="http://dita-ot.sourceforge.net" name="dita2happyhtml">
<!-- Define "happyhtml": first set params in an initialization step, then call dita2html5 -->
<target name="dita2happyhtml" depends="happyhtml.init, dita2html5"/>
<!-- Remember: ${dita.plugin.org.metadita.happyhtml.dir} is a generated variable
that makes use of this plugin's ID to find its directory. -->
<target name="happyhtml.init">
<property name="args.draft" value="yes"/>
<property name="args.css" value="${dita.plugin.org.metadita.happyhtml.dir}/css/myBrand.css"/>
<property name="args.copycss" value="yes"/>
<property name="args.xsl" value="${dita.plugin.org.metadita.happyhtml.dir}/xsl/happyStyle.xsl"/>
</target>
</project>
@depends
attribute to initialize defaults and then run dita2html5
, is that any of my
defaults can still be set to other values with the command line.Creating a happy style
Now, I need a style override that (as promised) makes my HTML happy. So … what could possibly do that?
Obviously, emojis. So, I've set up my override to replace every space in a title with the ☺ character.
And because this is (obviously) a bit tongue in cheek, I've also replaced every space in a list item with 😜.
Of course, it also needs to import all of the normal HTML5 processing rules. So the complete
override is an <xsl:import>
to pull in normal processing, followed by an
override for text anywhere in a title, and finally an override for non-empty text anywhere in a list
item:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:import href="plugin:org.dita.html5:xsl/dita2html5.xsl"/>
<xsl:template match="*[contains(@class,' topic/title ')]//text()">
<xsl:value-of select="translate(.,' ','☺')"/>
</xsl:template>
<xsl:template match="*[contains(@class,' topic/li ')]//text()[normalize-space()]">
<xsl:value-of select="translate(.,' ','😜')"/>
</xsl:template>
</xsl:stylesheet>
Adding a cascading bit o' style
I expect that while many might want to customize their HTML with an XSLT override, CSS overrides
are more common. So I've created a simple myBrand.css that becomes a part of
every build; I don't have to remember it, because the happyhtml
transform type
references the standard copy in the plugin, and ensures it's copied with the output.
My CSS in this sample doesn't do much beyond setting a default font. And while I can't say I've ever found Comic Sans funny, it … seems strangely appropriate here.
body { color: black;
background-color: white;
font-family: "Comic Sans MS", Arial, Helvetica, sans-serif;
font-size: 90%; }
What's left
With these four files – plugin.xml, an Ant file, XSLT, and CSS – I have a very happy plugin. All that's left is to place it in the DITA-OT plugin directory and install it. To do that, I need to place the org.metadita.happyhtml directory under DITA-OT/plugins/ to create DITA-OT/plugins/org.metadita.happyhtml.
To install, after placing the plugin in that location, run this command from the DITA-OT base directory:
bin/dita -install
bin/dita -install=http://metadita.org/toolkit/org.metadita.happyhtml.zip
Now, to try it out on some sample files, run:
bin/dita -i docsrc/samples/hierarchy.ditamap -f happyhtml -o out
This will build the age-old garage samples to the new happyhtml format. Open up out/tasks/changingtheoil.html, and you should be … very happy.
Conclusions and next steps
I suspect that this exact plugin doesn't quite meet your needs. But realistically, your needs probably differ from most other companies, so why not create your own "myHTML" transform type?
Begin by either following the steps above, or just downloading the "happyhtml" transform and start hacking:
- You'll probably want to rename the plugin to something that fits your environment. Remember to change the plugin ID in plugin.xml to match.
- If you're building with the command line today and always setting the same options – replace my
args.draft
example with the value(s) you need. - If you want your own CSS - that's even easier, just replace the myBrand.css
file and update the
args.css
parameter. Remember to change the directory variable to match your new plugin ID. - If you want to dig into XSLT to override styles, you've already got a sample set up to start
with. If not, just delete the
args.xsl
line from the Ant build.
And with that … happy building!
[EDIT 8 February 2017] Up next...
If you enjoyed making Happy HTML, you might also enjoy "Moody HTML for variable content". In that follow-up tutorial we use a plugin to create a new command line parameter and then use it to generate HTML with a wide variety of selectable moods. Enjoy!