python-tldp/tldp/doctypes/docbooksgml.py

251 lines
9.8 KiB
Python

#! /usr/bin/python
# -*- coding: utf8 -*-
#
# Copyright (c) 2016 Linux Documentation Project
from __future__ import absolute_import, division, print_function
from __future__ import unicode_literals
import os
import logging
from tldp.utils import which, firstfoundfile
from tldp.utils import arg_isexecutable, isexecutable
from tldp.utils import arg_isreadablefile, isreadablefile
from tldp.doctypes.common import BaseDoctype, SignatureChecker, depends
logger = logging.getLogger(__name__)
def docbookdsl_finder():
locations = [
'/usr/share/sgml/docbook/stylesheet/dsssl/modular/html/docbook.dsl',
'/usr/share/sgml/docbook/dsssl-stylesheets/html/docbook.dsl',
]
return firstfoundfile(locations)
def ldpdsl_finder():
locations = [
'/usr/share/sgml/docbook/stylesheet/dsssl/ldp/ldp.dsl',
]
return firstfoundfile(locations)
class DocbookSGML(BaseDoctype, SignatureChecker):
formatname = 'DocBook SGML 3.x/4.x'
extensions = ['.sgml']
signatures = ['-//Davenport//DTD DocBook V3.0//EN',
'-//OASIS//DTD DocBook V3.1//EN',
'-//OASIS//DTD DocBook V4.1//EN',
'-//OASIS//DTD DocBook V4.2//EN', ]
required = {'docbooksgml_jw': isexecutable,
'docbooksgml_openjade': isexecutable,
'docbooksgml_dblatex': isexecutable,
'docbooksgml_html2text': isexecutable,
'docbooksgml_collateindex': isexecutable,
'docbooksgml_ldpdsl': isreadablefile,
'docbooksgml_docbookdsl': isreadablefile,
}
def make_blank_indexsgml(self, **kwargs):
indexsgml = os.path.join(self.source.dirname, 'index.sgml')
self.indexsgml = os.path.isfile(indexsgml)
if self.indexsgml:
return True
'''generate an empty index.sgml file (in output dir)'''
s = '''"{config.docbooksgml_collateindex}" \\
-N \\
-o \\
"index.sgml"'''
return self.shellscript(s, **kwargs)
@depends(make_blank_indexsgml)
def move_blank_indexsgml_into_source(self, **kwargs):
'''move a blank index.sgml file into the source tree'''
if self.indexsgml:
return True
s = '''mv \\
--no-clobber \\
--verbose \\
-- "index.sgml" "{source.dirname}/index.sgml"'''
indexsgml = os.path.join(self.source.dirname, 'index.sgml')
if not self.config.script:
self.removals.add(indexsgml)
return self.shellscript(s, **kwargs)
@depends(move_blank_indexsgml_into_source)
def make_data_indexsgml(self, **kwargs):
'''collect document's index entries into a data file (HTML.index)'''
if self.indexsgml:
return True
s = '''"{config.docbooksgml_openjade}" \\
-t sgml \\
-V html-index \\
-d "{config.docbooksgml_docbookdsl}" \\
"{source.filename}"'''
return self.shellscript(s, **kwargs)
@depends(make_data_indexsgml)
def make_indexsgml(self, **kwargs):
'''generate the final document index file (index.sgml)'''
if self.indexsgml:
return True
s = '''"{config.docbooksgml_collateindex}" \\
-g \\
-t Index \\
-i doc-index \\
-o "index.sgml" \\
"HTML.index" \\
"{source.filename}"'''
return self.shellscript(s, **kwargs)
@depends(make_indexsgml)
def move_indexsgml_into_source(self, **kwargs):
'''move the generated index.sgml file into the source tree'''
if self.indexsgml:
return True
indexsgml = os.path.join(self.source.dirname, 'index.sgml')
s = '''mv \\
--verbose \\
--force \\
-- "index.sgml" "{source.dirname}/index.sgml"'''
logger.debug("%s creating %s", self.source.stem, indexsgml)
if not self.config.script:
self.removals.add(indexsgml)
return self.shellscript(s, **kwargs)
@depends(move_indexsgml_into_source)
def cleaned_indexsgml(self, **kwargs):
'''clean the junk from the output dir after building the index.sgml'''
# -- be super cautious before removing a bunch of files
if not self.config.script:
cwd = os.getcwd()
if not os.path.samefile(cwd, self.output.dirname):
logger.error("%s (cowardly) refusing to clean directory %s",
self.source.stem, cwd)
logger.error("%s expected to find %s",
self.source.stem, self.output.dirname)
return False
preserve = os.path.basename(self.output.MD5SUMS)
s = '''find . -mindepth 1 -maxdepth 1 -not -type d -not -name {} -delete -print'''
s = s.format(preserve)
return self.shellscript(s, **kwargs)
@depends(cleaned_indexsgml)
def make_htmls(self, **kwargs):
'''create a single page HTML output (with incorrect name)'''
s = '''"{config.docbooksgml_jw}" \\
-f docbook \\
-b html \\
--dsl "{config.docbooksgml_ldpdsl}#html" \\
-V nochunks \\
-V '%callout-graphics-path%=images/callouts/' \\
-V '%stock-graphics-extension%=.png' \\
--output . \\
"{source.filename}"'''
return self.shellscript(s, **kwargs)
@depends(make_htmls)
def make_name_htmls(self, **kwargs):
'''correct the single page HTML output name'''
s = 'mv -v --no-clobber -- "{output.name_html}" "{output.name_htmls}"'
return self.shellscript(s, **kwargs)
@depends(make_name_htmls)
def make_name_txt(self, **kwargs):
'''create text output (from single-page HTML)'''
s = '''"{config.docbooksgml_html2text}" > "{output.name_txt}" \\
-style pretty \\
-nobs \\
"{output.name_htmls}"'''
return self.shellscript(s, **kwargs)
def make_pdf_with_jw(self, **kwargs):
'''use jw (openjade) to create a PDF'''
s = '''"{config.docbooksgml_jw}" \\
-f docbook \\
-b pdf \\
--output . \\
"{source.filename}"'''
return self.shellscript(s, **kwargs)
def make_pdf_with_dblatex(self, **kwargs):
'''use dblatex (fallback) to create a PDF'''
s = '''"{config.docbooksgml_dblatex}" \\
-F sgml \\
-t pdf \\
-o "{output.name_pdf}" \\
"{source.filename}"'''
return self.shellscript(s, **kwargs)
@depends(cleaned_indexsgml)
def make_name_pdf(self, **kwargs):
stem = self.source.stem
classname = self.__class__.__name__
logger.info("%s calling method %s.%s",
stem, classname, 'make_pdf_with_jw')
if self.make_pdf_with_jw(**kwargs):
return True
logger.error("%s jw failed creating PDF, falling back to dblatex...",
stem)
logger.info("%s calling method %s.%s",
stem, classname, 'make_pdf_with_dblatex')
return self.make_pdf_with_dblatex(**kwargs)
@depends(make_name_htmls)
def make_html(self, **kwargs):
'''create chunked HTML outputs'''
s = '''"{config.docbooksgml_jw}" \\
-f docbook \\
-b html \\
--dsl "{config.docbooksgml_ldpdsl}#html" \\
-V '%callout-graphics-path%=images/callouts/' \\
-V '%stock-graphics-extension%=.png' \\
--output . \\
"{source.filename}"'''
return self.shellscript(s, **kwargs)
@depends(make_html)
def make_name_html(self, **kwargs):
'''rename openjade's index.html to LDP standard name STEM.html'''
s = 'mv -v --no-clobber -- "{output.name_indexhtml}" "{output.name_html}"'
return self.shellscript(s, **kwargs)
@depends(make_name_html)
def make_name_indexhtml(self, **kwargs):
'''create final index.html symlink'''
s = 'ln -svr -- "{output.name_html}" "{output.name_indexhtml}"'
return self.shellscript(s, **kwargs)
@classmethod
def argparse(cls, p):
descrip = 'executables and data files for %s' % (cls.formatname,)
g = p.add_argument_group(title=cls.__name__, description=descrip)
g.add_argument('--docbooksgml-docbookdsl', type=arg_isreadablefile,
default=docbookdsl_finder(),
help='full path to html/docbook.dsl [%(default)s]')
g.add_argument('--docbooksgml-ldpdsl', type=arg_isreadablefile,
default=ldpdsl_finder(),
help='full path to ldp/ldp.dsl [%(default)s]')
g.add_argument('--docbooksgml-jw', type=arg_isexecutable,
default=which('jw'),
help='full path to jw [%(default)s]')
g.add_argument('--docbooksgml-html2text', type=arg_isexecutable,
default=which('html2text'),
help='full path to html2text [%(default)s]')
g.add_argument('--docbooksgml-openjade', type=arg_isexecutable,
default=which('openjade'),
help='full path to openjade [%(default)s]')
g.add_argument('--docbooksgml-dblatex', type=arg_isexecutable,
default=which('dblatex'),
help='full path to dblatex [%(default)s]')
g.add_argument('--docbooksgml-collateindex', type=arg_isexecutable,
default=which('collateindex.pl'),
help='full path to collateindex [%(default)s]')
#
# -- end of file