htmldeps.py
Expand CSS and javascript dependency links in HTML
This module supports clean separation of markup, presentation, and behavior in
HTML. It looks for special dependency comments atop CSS and javascript files
and within <style>
or <script>
tags of the form:
/* :depends module1, module2 */
The comma separated list following the :depends
string indicates CSS or
javascript modules that need to be linked into the markup just before each
<style>
or <script>
tag enclosing a dependency comment.
After processing, the HTML will contain all the required links to CSS or javascript modules listed in the markup, along with any of their dependencies.
When a CSS or javascript module file requires other modules to be loaded first, it should provide a dependency comment toward the beginning the source code. CSS modules may only depend upon other CSS modules, and javascript modules may depend only on other javascript modules. There may only be one dependency comment in any module file, and the comment should be somewhere in the first five lines of the source code.
Module names correspond to filenames without an extension, e.g.
<style>/*:depends site*/</style>
depends on a file named site.css
. Module
names must only consist of the ASCII characters matching the regular
expression [a-zA-Z0-9_-]
.
Moudle files are located by looking in the current working directory and then
via whatever paths have been optionally specified in the $HTMLDEPS
environment variable (formatted just like the ubiquitous $PATH
variable).
In addition, the list of paths to search may also be adjusted via the config
object.
Within the original HTML, the :depends
string must only appear in comments
inside of <script>
or <style>
tags. When a tag contains a dependency
comment, is must not contain any other CSS or javascript expressions: the
comment and its enclosing tag will be removed from the HTML output and
replaced with links to external files. The same module will not be included
more than once in the HTML output.
Attributes in the original <script>
or <style>
tags will be written into
the transformed HTML. For example:
<style media="print">/* :depends print */</style>
Might render something like this:
<link rel="stylesheet" href="print.css" media="print">
(For XHTML, <link rel="stylesheet" href="print.css" media="print" />
)
All HTML, CSS, and javascript files must be encoded in utf-8.
This module may also be invoked directly from the command line by passing it to
the python interpreter. Run the script with --help
to see the available
command flags:
python htmldeps.py --help
Python 3 or later
import htmldeps
htmldeps.write('test.html')
config
This object holds configuration data to properly process HTML passed into
link()
. It has the following attributes:
config.search_path
A list
of directories which will be searched to find 'css'
and 'js'
modules.
These lists are structured and used much like sys.path
. By default, they are empty or set to the contents of the $HTMLDEPS
environment variable split into separate items according to os.pathsep
.
Pathnames may be added or removed from the list as needed. The value of os.getcwd()
will be searched before the directories named in the list.
config.link_prefixes
A dict
with two keys, 'css'
and 'js'
, each indexing a str
(default: ''
) indicating an optional URL value to prepend to any generated links of the given filetype. For example, if:
link_prefixes['js'] == '/js/'
Then HTML input containing:
<script>/* :depends site */</script>
Will be converted to something like:
<script src="/js/site.js"></script>
Be sure to include a trailing '/'
in any directory prefixes.
config.flatten
Set to False
by default, but if True
, any chain of generated links should be flattened into one bearing the name of the last link in the sequence. For example:
<script>/* depends a, b */</script>
Would normally be transformed into:
<script src="a.js"></script><script src="b.js"></script>
But if flatten
were True
the output would just be:
<script src="b.js"></script>
The content of "b.js"
would be that of module a
concatenated with b
. Use this option to reduce http requests and boost the performance of your page.
link(html)
Inserts the appropriate CSS and javascript links into an HTML string. The html
parameter may be a str
or a file handle in 'rt'
mode.
Returns a two-item tuple (html, links)
. The first item is a new HTML string containing links to all the CSS and javascript modules listed in dependency comments. The second item is a dict
which maps the URL of each CSS or javascript link to its corresponding text content.
It's up to the caller to write the text content into the appropriate file locations on the web server. For example, if links
were:
{ '/css/site.css' : 'body {color:red;}' }
Then the caller would typically write a file named site.css
in the css
directory (under the web server’s document root) containing the 'body {color:red;}'
string.
write(*html_filenames, output_directory='build', verbose=False)
Convenience function. Iterates over html_filenames
and applies link()
to the HTML in each file. All HTML, CSS, and javascript output will be written into output_directory
. Typically, it’s best to set the working directory to wherever the CSS or javascript files required by the HTML reside (or set the $HTMLDEPS
environment variable appropriately).
If verbose
, describe which files are written via standard error.
If this function doesn’t give you the file output you want, it’s better to just call link()
directly.