## 5.4.2 Interactions with packages

This section is useful for packages authors. The HTML5 Renderer allows packages to interact with the rendering process in several ways through packages resources. Each such resource is wrapped in an object whose class inherits from PackageResource located in the module plasTeX.PackageResource. Those objects are typically attached to the document during package loading using the document addPackageResource method inside the ProcessOptions function.

### Extra input files

The following example shows how a package can register templates overriding regular renderer templates, as well as extra CSS and javascript files. The following function should be part of a python package, say ‘mypkg.py’ which imports Path from pathlib. Next to this file, there should be a folder ‘mypkg’ containing files ‘test.css’ and ‘test.js’, and a ‘templates’ subfolder.

    def ProcessOptions(options, document):
        css = PackageCss(
            renderers='html5',
            path=Path(__file__).parent/'mypkg'/'test.css')
        js = PackageJs(
            renderers='html5',
            path=Path(__file__).parent/'mypkg'/'test.js')
        tpl = PackageTemplateDir(
            renderers='html5',
            path=Path(__file__).parent/'mypkg'/'templates')

        document.addPackageResource([css, js, tpl])

When rendering any document containing `\usepackage{mypkg}`, the HTML5 renderer will

- copy ‘mypkg/test.css’ to the ‘styles’ subdirectory of the output directory and call it from the default html layout

- copy ‘mypkg/test.js’ to the ‘js’ subdirectory of the output directory and call it from the default html layout

- load any template contained in ‘mypkg/templates’, overiding the renderer default templates if needed.

If you want to copy a CSS or Javascript file to the output directory but without linking to it from the default html layout, you can use the keyword argument `copy_only=True`. The `renderer` argument can also be a list of renderers, and its default value is `html5`.

### Extra output files and filters

The HTML5 Renderer allows packages to produce extra output files and define filters that are applied to any output file.

In order to create new output files, any package can register a callback function taking a document as input a returning a list of created file names. As an example, let us write a package which adds some document statistics to an extra output file ‘stats.html’ (we will not try to produce valid html below, only illustrate our point). The package module only needs to contain the following.

    import os

    def ProcessOptions(options, document):
        def makeStats(document):
            nbChap = len(document.getElementsByTagName('chapter'))
            nbSec = len(document.getElementsByTagName('section'))
            with open('stats.html', 'w') as outfile:
                outfile.write("%d chapters and %d sections" % (nbChap, nbSec))
            return ['stats.html']
        cb = PackagePreCleanupCB(
            renderers='html5',
            data=makeStats)
        document.addPackageResource(cb)

As suggested by the key name, those pre-cleanup callbacks are called before the renderer cleanup method.

Packages can also register filters to be applied during the cleanup process. Those filters are functions that take a document and a string to filter and return the filtered string (using the document object to provide context if needed). They will be called on the content of each rendered file, after all files have been rendered. Registration is analogous to pre-cleanup callbacks but replacing PackagePreCleanupCB by PackageProcessFileContent.