From 140d836e9cd54fb67b969fd82ef7ed19ba574d40 Mon Sep 17 00:00:00 2001 From: Luca Falavigna Date: Sat, 26 Apr 2014 15:11:58 +0200 Subject: Imported Upstream version 2.3.1 --- src/engine/SCons/Tool/docbook/__init__.py | 877 ++++++++++++++++++++++++++++++ 1 file changed, 877 insertions(+) create mode 100644 src/engine/SCons/Tool/docbook/__init__.py (limited to 'src/engine/SCons/Tool/docbook/__init__.py') diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py new file mode 100644 index 0000000..72ea175 --- /dev/null +++ b/src/engine/SCons/Tool/docbook/__init__.py @@ -0,0 +1,877 @@ + +"""SCons.Tool.docbook + +Tool-specific initialization for Docbook. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001-7,2010 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import os +import glob +import re + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Script +import SCons.Tool +import SCons.Util + +# Get full path to this script +scriptpath = os.path.dirname(os.path.realpath(__file__)) + +# Local folder for the collection of DocBook XSLs +db_xsl_folder = 'docbook-xsl-1.76.1' + +# Do we have libxml2/libxslt/lxml? +has_libxml2 = True +has_lxml = True +try: + import libxml2 + import libxslt +except: + has_libxml2 = False +try: + import lxml +except: + has_lxml = False + +# Set this to True, to prefer xsltproc over libxml2 and lxml +prefer_xsltproc = False + +# Regexs for parsing Docbook XML sources of MAN pages +re_manvolnum = re.compile("([^<]*)") +re_refname = re.compile("([^<]*)") + +# +# Helper functions +# +def __extend_targets_sources(target, source): + """ Prepare the lists of target and source files. """ + if not SCons.Util.is_List(target): + target = [target] + if not source: + source = target[:] + elif not SCons.Util.is_List(source): + source = [source] + if len(target) < len(source): + target.extend(source[len(target):]) + + return target, source + +def __init_xsl_stylesheet(kw, env, user_xsl_var, default_path): + if kw.get('DOCBOOK_XSL','') == '': + xsl_style = kw.get('xsl', env.subst(user_xsl_var)) + if xsl_style == '': + path_args = [scriptpath, db_xsl_folder] + default_path + xsl_style = os.path.join(*path_args) + kw['DOCBOOK_XSL'] = xsl_style + +def __select_builder(lxml_builder, libxml2_builder, cmdline_builder): + """ Selects a builder, based on which Python modules are present. """ + if prefer_xsltproc: + return cmdline_builder + + if not has_libxml2: + # At the moment we prefer libxml2 over lxml, the latter can lead + # to conflicts when installed together with libxml2. + if has_lxml: + return lxml_builder + else: + return cmdline_builder + + return libxml2_builder + +def __ensure_suffix(t, suffix): + """ Ensure that the target t has the given suffix. """ + tpath = str(t) + if not tpath.endswith(suffix): + return tpath+suffix + + return t + +def __ensure_suffix_stem(t, suffix): + """ Ensure that the target t has the given suffix, and return the file's stem. """ + tpath = str(t) + if not tpath.endswith(suffix): + stem = tpath + tpath += suffix + + return tpath, stem + else: + stem, ext = os.path.splitext(tpath) + + return t, stem + +def __get_xml_text(root): + """ Return the text for the given root node (xml.dom.minidom). """ + txt = "" + for e in root.childNodes: + if (e.nodeType == e.TEXT_NODE): + txt += e.data + return txt + +def __create_output_dir(base_dir): + """ Ensure that the output directory base_dir exists. """ + root, tail = os.path.split(base_dir) + dir = None + if tail: + if base_dir.endswith('/'): + dir = base_dir + else: + dir = root + else: + if base_dir.endswith('/'): + dir = base_dir + + if dir and not os.path.isdir(dir): + os.makedirs(dir) + + +# +# Supported command line tools and their call "signature" +# +xsltproc_com = {'xsltproc' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -o $TARGET $DOCBOOK_XSL $SOURCE', + 'saxon' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -o $TARGET $DOCBOOK_XSL $SOURCE $DOCBOOK_XSLTPROCPARAMS', + 'saxon-xslt' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -o $TARGET $DOCBOOK_XSL $SOURCE $DOCBOOK_XSLTPROCPARAMS', + 'xalan' : '$DOCBOOK_XSLTPROC $DOCBOOK_XSLTPROCFLAGS -q -out $TARGET -xsl $DOCBOOK_XSL -in $SOURCE'} +xmllint_com = {'xmllint' : '$DOCBOOK_XMLLINT $DOCBOOK_XMLLINTFLAGS --xinclude $SOURCE > $TARGET'} +fop_com = {'fop' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -fo $SOURCE -pdf $TARGET', + 'xep' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -valid -fo $SOURCE -pdf $TARGET', + 'jw' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -f docbook -b pdf $SOURCE -o $TARGET'} + +def __detect_cl_tool(env, chainkey, cdict): + """ + Helper function, picks a command line tool from the list + and initializes its environment variables. + """ + if env.get(chainkey,'') == '': + clpath = '' + for cltool in cdict: + clpath = env.WhereIs(cltool) + if clpath: + env[chainkey] = clpath + if not env[chainkey + 'COM']: + env[chainkey + 'COM'] = cdict[cltool] + +def _detect(env): + """ + Detect all the command line tools that we might need for creating + the requested output formats. + """ + global prefer_xsltproc + + if env.get('DOCBOOK_PREFER_XSLTPROC',''): + prefer_xsltproc = True + + if ((not has_libxml2 and not has_lxml) or (prefer_xsltproc)): + # Try to find the XSLT processors + __detect_cl_tool(env, 'DOCBOOK_XSLTPROC', xsltproc_com) + __detect_cl_tool(env, 'DOCBOOK_XMLLINT', xmllint_com) + + __detect_cl_tool(env, 'DOCBOOK_FOP', fop_com) + +# +# Scanners +# +include_re = re.compile('fileref\\s*=\\s*["|\']([^\\n]*)["|\']') +sentity_re = re.compile('') + +def __xml_scan(node, env, path, arg): + """ Simple XML file scanner, detecting local images and XIncludes as implicit dependencies. """ + # Does the node exist yet? + if not os.path.isfile(str(node)): + return [] + + if env.get('DOCBOOK_SCANENT',''): + # Use simple pattern matching for system entities..., no support + # for recursion yet. + contents = node.get_text_contents() + return sentity_re.findall(contents) + + xsl_file = os.path.join(scriptpath,'utils','xmldepend.xsl') + if not has_libxml2 or prefer_xsltproc: + if has_lxml and not prefer_xsltproc: + + from lxml import etree + + xsl_tree = etree.parse(xsl_file) + doc = etree.parse(str(node)) + result = doc.xslt(xsl_tree) + + depfiles = [x.strip() for x in str(result).splitlines() if x.strip() != "" and not x.startswith(" 1: + env.Clean(outfiles[0], outfiles[1:]) + + + return result + +def DocbookSlidesPdf(env, target, source=None, *args, **kw): + """ + A pseudo-Builder, providing a Docbook toolchain for PDF slides output. + """ + # Init list of targets/sources + target, source = __extend_targets_sources(target, source) + + # Init XSL stylesheet + __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_SLIDESPDF', ['slides','fo','plain.xsl']) + + # Setup builder + __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder) + + # Create targets + result = [] + for t,s in zip(target,source): + t, stem = __ensure_suffix_stem(t, '.pdf') + xsl = __builder.__call__(env, stem+'.fo', s, **kw) + env.Depends(xsl, kw['DOCBOOK_XSL']) + result.extend(xsl) + result.extend(__fop_builder.__call__(env, t, xsl, **kw)) + + return result + +def DocbookSlidesHtml(env, target, source=None, *args, **kw): + """ + A pseudo-Builder, providing a Docbook toolchain for HTML slides output. + """ + # Init list of targets/sources + if not SCons.Util.is_List(target): + target = [target] + if not source: + source = target + target = ['index.html'] + elif not SCons.Util.is_List(source): + source = [source] + + # Init XSL stylesheet + __init_xsl_stylesheet(kw, env, '$DOCBOOK_DEFAULT_XSL_SLIDESHTML', ['slides','html','plain.xsl']) + + # Setup builder + __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder) + + # Detect base dir + base_dir = kw.get('base_dir', '') + if base_dir: + __create_output_dir(base_dir) + + # Create targets + result = [] + r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + env.Depends(r, kw['DOCBOOK_XSL']) + result.extend(r) + # Add supporting files for cleanup + env.Clean(r, [os.path.join(base_dir, 'toc.html')] + + glob.glob(os.path.join(base_dir, 'foil*.html'))) + + return result + +def DocbookXInclude(env, target, source, *args, **kw): + """ + A pseudo-Builder, for resolving XIncludes in a separate processing step. + """ + # Init list of targets/sources + target, source = __extend_targets_sources(target, source) + + # Setup builder + __builder = __select_builder(__xinclude_lxml_builder,__xinclude_libxml2_builder,__xmllint_builder) + + # Create targets + result = [] + for t,s in zip(target,source): + result.extend(__builder.__call__(env, t, s, **kw)) + + return result + +def DocbookXslt(env, target, source=None, *args, **kw): + """ + A pseudo-Builder, applying a simple XSL transformation to the input file. + """ + # Init list of targets/sources + target, source = __extend_targets_sources(target, source) + + # Init XSL stylesheet + kw['DOCBOOK_XSL'] = kw.get('xsl', 'transform.xsl') + + # Setup builder + __builder = __select_builder(__lxml_builder, __libxml2_builder, __xsltproc_builder) + + # Create targets + result = [] + for t,s in zip(target,source): + r = __builder.__call__(env, t, s, **kw) + env.Depends(r, kw['DOCBOOK_XSL']) + result.extend(r) + + return result + + +def generate(env): + """Add Builders and construction variables for docbook to an Environment.""" + + env.SetDefault( + # Default names for customized XSL stylesheets + DOCBOOK_DEFAULT_XSL_EPUB = '', + DOCBOOK_DEFAULT_XSL_HTML = '', + DOCBOOK_DEFAULT_XSL_HTMLCHUNKED = '', + DOCBOOK_DEFAULT_XSL_HTMLHELP = '', + DOCBOOK_DEFAULT_XSL_PDF = '', + DOCBOOK_DEFAULT_XSL_MAN = '', + DOCBOOK_DEFAULT_XSL_SLIDESPDF = '', + DOCBOOK_DEFAULT_XSL_SLIDESHTML = '', + + # Paths to the detected executables + DOCBOOK_XSLTPROC = '', + DOCBOOK_XMLLINT = '', + DOCBOOK_FOP = '', + + # Additional flags for the text processors + DOCBOOK_XSLTPROCFLAGS = SCons.Util.CLVar(''), + DOCBOOK_XMLLINTFLAGS = SCons.Util.CLVar(''), + DOCBOOK_FOPFLAGS = SCons.Util.CLVar(''), + DOCBOOK_XSLTPROCPARAMS = SCons.Util.CLVar(''), + + # Default command lines for the detected executables + DOCBOOK_XSLTPROCCOM = xsltproc_com['xsltproc'], + DOCBOOK_XMLLINTCOM = xmllint_com['xmllint'], + DOCBOOK_FOPCOM = fop_com['fop'], + + # Screen output for the text processors + DOCBOOK_XSLTPROCCOMSTR = None, + DOCBOOK_XMLLINTCOMSTR = None, + DOCBOOK_FOPCOMSTR = None, + + ) + _detect(env) + + try: + env.AddMethod(DocbookEpub, "DocbookEpub") + env.AddMethod(DocbookHtml, "DocbookHtml") + env.AddMethod(DocbookHtmlChunked, "DocbookHtmlChunked") + env.AddMethod(DocbookHtmlhelp, "DocbookHtmlhelp") + env.AddMethod(DocbookPdf, "DocbookPdf") + env.AddMethod(DocbookMan, "DocbookMan") + env.AddMethod(DocbookSlidesPdf, "DocbookSlidesPdf") + env.AddMethod(DocbookSlidesHtml, "DocbookSlidesHtml") + env.AddMethod(DocbookXInclude, "DocbookXInclude") + env.AddMethod(DocbookXslt, "DocbookXslt") + except AttributeError: + # Looks like we use a pre-0.98 version of SCons... + from SCons.Script.SConscript import SConsEnvironment + SConsEnvironment.DocbookEpub = DocbookEpub + SConsEnvironment.DocbookHtml = DocbookHtml + SConsEnvironment.DocbookHtmlChunked = DocbookHtmlChunked + SConsEnvironment.DocbookHtmlhelp = DocbookHtmlhelp + SConsEnvironment.DocbookPdf = DocbookPdf + SConsEnvironment.DocbookMan = DocbookMan + SConsEnvironment.DocbookSlidesPdf = DocbookSlidesPdf + SConsEnvironment.DocbookSlidesHtml = DocbookSlidesHtml + SConsEnvironment.DocbookXInclude = DocbookXInclude + SConsEnvironment.DocbookXslt = DocbookXslt + + +def exists(env): + return 1 -- cgit v1.2.3