2016-02-11 03:22:23 +00:00
|
|
|
#! /usr/bin/python
|
2016-02-18 21:25:02 +00:00
|
|
|
# -*- coding: utf8 -*-
|
2016-02-11 03:22:23 +00:00
|
|
|
|
2016-02-24 05:16:44 +00:00
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
2016-02-22 20:32:35 +00:00
|
|
|
import os
|
2016-02-25 19:37:14 +00:00
|
|
|
import logging
|
2016-02-26 18:10:29 +00:00
|
|
|
import networkx as nx
|
2016-02-22 20:32:35 +00:00
|
|
|
|
2016-02-26 18:10:29 +00:00
|
|
|
from tldp.utils import which, firstfoundfile
|
2016-02-24 05:16:44 +00:00
|
|
|
from tldp.utils import arg_isexecutable, isexecutable
|
|
|
|
from tldp.utils import arg_isreadablefile, isreadablefile
|
|
|
|
|
2016-02-26 18:10:29 +00:00
|
|
|
from tldp.doctypes.common import BaseDoctype, SignatureChecker, depends
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
2016-02-11 03:22:23 +00:00
|
|
|
|
|
|
|
|
2016-02-22 20:32:35 +00:00
|
|
|
def docbookdsl_finder():
|
|
|
|
locations = [
|
2016-02-24 05:16:44 +00:00
|
|
|
'/usr/share/sgml/docbook/stylesheet/dsssl/modular/html/docbook.dsl',
|
|
|
|
'/usr/share/sgml/docbook/dsssl-stylesheets/html/docbook.dsl',
|
|
|
|
]
|
2016-02-22 20:32:35 +00:00
|
|
|
return firstfoundfile(locations)
|
|
|
|
|
|
|
|
|
|
|
|
def ldpdsl_finder():
|
|
|
|
locations = [
|
2016-02-24 05:16:44 +00:00
|
|
|
'/usr/share/sgml/docbook/stylesheet/dsssl/ldp/ldp.dsl',
|
|
|
|
]
|
2016-02-22 20:32:35 +00:00
|
|
|
return firstfoundfile(locations)
|
|
|
|
|
|
|
|
|
2016-02-24 05:16:44 +00:00
|
|
|
class DocbookSGML(BaseDoctype, SignatureChecker):
|
2016-02-17 21:49:33 +00:00
|
|
|
formatname = 'DocBook SGML 3.x/4.x'
|
2016-02-11 03:22:23 +00:00
|
|
|
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', ]
|
2016-02-12 20:43:45 +00:00
|
|
|
|
2016-02-24 05:16:44 +00:00
|
|
|
required = {'docbooksgml_jw': isexecutable,
|
|
|
|
'docbooksgml_openjade': isexecutable,
|
|
|
|
'docbooksgml_dblatex': isexecutable,
|
|
|
|
'docbooksgml_html2text': isexecutable,
|
|
|
|
'docbooksgml_collateindex': isexecutable,
|
|
|
|
'docbooksgml_ldpdsl': isreadablefile,
|
|
|
|
'docbooksgml_docbookdsl': isreadablefile,
|
|
|
|
}
|
2016-02-12 20:43:45 +00:00
|
|
|
|
2016-02-26 18:10:29 +00:00
|
|
|
graph = nx.DiGraph()
|
2016-02-24 05:59:47 +00:00
|
|
|
|
2016-02-26 18:10:29 +00:00
|
|
|
buildorder = ['buildall']
|
2016-02-24 05:59:47 +00:00
|
|
|
|
2016-02-26 18:10:29 +00:00
|
|
|
def chdir_output(self):
|
|
|
|
os.chdir(self.output.dirname)
|
2016-02-24 07:30:07 +00:00
|
|
|
return True
|
2016-02-11 03:22:23 +00:00
|
|
|
|
2016-02-26 18:10:29 +00:00
|
|
|
@depends(graph, chdir_output)
|
2016-02-27 06:18:02 +00:00
|
|
|
def copy_static_resources(self):
|
|
|
|
source = list()
|
|
|
|
for d in ('images', 'resources'):
|
|
|
|
fullpath = os.path.join(self.source.dirname, d)
|
|
|
|
fullpath = os.path.abspath(fullpath)
|
|
|
|
if os.path.isdir(fullpath):
|
|
|
|
source.append('"' + fullpath + '"')
|
|
|
|
if not source:
|
2016-03-02 06:58:37 +00:00
|
|
|
logger.debug("%s no images or resources to copy",
|
|
|
|
self.source.stem)
|
2016-02-27 06:18:02 +00:00
|
|
|
return True
|
|
|
|
s = 'rsync --archive --verbose %s ./' % (' '.join(source))
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, copy_static_resources)
|
2016-02-26 18:10:29 +00:00
|
|
|
def make_blank_indexsgml(self):
|
2016-02-27 02:15:27 +00:00
|
|
|
indexsgml = os.path.join(self.source.dirname, 'index.sgml')
|
|
|
|
self.indexsgml = os.path.isfile(indexsgml)
|
|
|
|
if self.indexsgml:
|
|
|
|
return True
|
2016-02-26 18:10:29 +00:00
|
|
|
'''generate an empty index.sgml file (in output dir)'''
|
|
|
|
s = '''"{config.docbooksgml_collateindex}" \\
|
|
|
|
-N \\
|
|
|
|
-o \\
|
|
|
|
"index.sgml"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, make_blank_indexsgml)
|
2016-02-27 03:04:51 +00:00
|
|
|
def move_blank_indexsgml_into_source(self):
|
|
|
|
'''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"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, move_blank_indexsgml_into_source)
|
2016-02-26 18:10:29 +00:00
|
|
|
def make_data_indexsgml(self):
|
|
|
|
'''collect document's index entries into a data file (HTML.index)'''
|
2016-02-27 02:15:27 +00:00
|
|
|
if self.indexsgml:
|
|
|
|
return True
|
2016-02-26 18:10:29 +00:00
|
|
|
s = '''"{config.docbooksgml_openjade}" \\
|
|
|
|
-t sgml \\
|
|
|
|
-V html-index \\
|
|
|
|
-d "{config.docbooksgml_docbookdsl}" \\
|
|
|
|
"{source.filename}"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, make_data_indexsgml)
|
|
|
|
def make_indexsgml(self):
|
|
|
|
'''generate the final document index file (index.sgml)'''
|
2016-02-27 02:15:27 +00:00
|
|
|
if self.indexsgml:
|
|
|
|
return True
|
2016-02-26 18:10:29 +00:00
|
|
|
s = '''"{config.docbooksgml_collateindex}" \\
|
|
|
|
-g \\
|
|
|
|
-t Index \\
|
|
|
|
-i doc-index \\
|
|
|
|
-o "index.sgml" \\
|
|
|
|
"HTML.index" \\
|
|
|
|
"{source.filename}"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, make_indexsgml)
|
|
|
|
def move_indexsgml_into_source(self):
|
|
|
|
'''move the generated index.sgml file into the source tree'''
|
2016-02-27 02:15:27 +00:00
|
|
|
if self.indexsgml:
|
|
|
|
return True
|
2016-02-26 18:10:29 +00:00
|
|
|
indexsgml = os.path.join(self.source.dirname, 'index.sgml')
|
|
|
|
s = '''mv \\
|
|
|
|
--verbose \\
|
2016-02-27 03:04:51 +00:00
|
|
|
--force \\
|
2016-02-26 18:10:29 +00:00
|
|
|
-- "index.sgml" "{source.dirname}/index.sgml"'''
|
|
|
|
moved = self.shellscript(s)
|
|
|
|
if moved:
|
|
|
|
logger.debug("%s created %s", self.source.stem, indexsgml)
|
2016-02-26 19:58:56 +00:00
|
|
|
self.removals.append(indexsgml)
|
2016-02-26 18:10:29 +00:00
|
|
|
return True
|
2016-02-27 02:15:27 +00:00
|
|
|
return False
|
2016-02-26 18:10:29 +00:00
|
|
|
|
|
|
|
@depends(graph, move_indexsgml_into_source)
|
|
|
|
def cleaned_indexsgml(self):
|
|
|
|
'''clean the junk from the output dir after building the index.sgml'''
|
|
|
|
# -- be super cautious before removing a bunch of files
|
|
|
|
cwd = os.getcwd()
|
|
|
|
if not os.path.samefile(cwd, self.output.dirname):
|
|
|
|
logger.error("%s (cowardly) refusing to clean directory %s", cwd)
|
|
|
|
logger.error("%s expected to find %s", self.output.dirname)
|
|
|
|
return False
|
2016-02-27 18:46:18 +00:00
|
|
|
s = '''find . -mindepth 1 -maxdepth 1 -not -type d -delete -print'''
|
2016-02-26 18:10:29 +00:00
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, cleaned_indexsgml)
|
|
|
|
def make_htmls(self):
|
|
|
|
'''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)
|
|
|
|
|
|
|
|
@depends(graph, make_htmls)
|
|
|
|
def make_name_htmls(self):
|
|
|
|
'''correct the single page HTML output name'''
|
|
|
|
s = 'mv -v --no-clobber -- "{output.name_html}" "{output.name_htmls}"'
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, make_name_htmls)
|
|
|
|
def make_name_txt(self):
|
|
|
|
'''create text output (from single-page HTML)'''
|
|
|
|
s = '''"{config.docbooksgml_html2text}" > "{output.name_txt}" \\
|
|
|
|
-style pretty \\
|
|
|
|
-nobs \\
|
|
|
|
"{output.name_htmls}"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
def make_pdf_with_jw(self):
|
2016-02-26 19:58:56 +00:00
|
|
|
'''use jw (openjade) to create a PDF'''
|
2016-02-26 18:10:29 +00:00
|
|
|
s = '''"{config.docbooksgml_jw}" \\
|
|
|
|
-f docbook \\
|
|
|
|
-b pdf \\
|
|
|
|
--output . \\
|
|
|
|
"{source.filename}"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
def make_pdf_with_dblatex(self):
|
2016-02-26 19:58:56 +00:00
|
|
|
'''use dblatex (fallback) to create a PDF'''
|
2016-02-26 18:10:29 +00:00
|
|
|
s = '''"{config.docbooksgml_dblatex}" \\
|
|
|
|
-F sgml \\
|
|
|
|
-t pdf \\
|
|
|
|
-o "{output.name_pdf}" \\
|
|
|
|
"{source.filename}"'''
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
|
|
|
@depends(graph, cleaned_indexsgml)
|
|
|
|
def make_name_pdf(self):
|
2016-02-26 19:22:00 +00:00
|
|
|
stem = self.source.stem
|
|
|
|
classname = self.__class__.__name__
|
|
|
|
logger.info("%s calling method %s.%s",
|
|
|
|
stem, classname, 'make_pdf_with_jw')
|
2016-02-26 18:10:29 +00:00
|
|
|
if self.make_pdf_with_jw():
|
2016-02-26 19:58:56 +00:00
|
|
|
return True
|
2016-02-26 19:22:00 +00:00
|
|
|
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')
|
2016-02-26 18:10:29 +00:00
|
|
|
return self.make_pdf_with_dblatex()
|
|
|
|
|
|
|
|
@depends(graph, make_name_htmls)
|
|
|
|
def make_html(self):
|
2016-02-26 19:58:56 +00:00
|
|
|
'''create chunked HTML outputs'''
|
2016-02-26 18:10:29 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
@depends(graph, make_html)
|
|
|
|
def make_name_html(self):
|
|
|
|
'''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)
|
|
|
|
|
|
|
|
@depends(graph, make_name_html)
|
|
|
|
def make_name_indexhtml(self):
|
|
|
|
'''create final index.html symlink'''
|
|
|
|
s = 'ln -svr -- "{output.name_html}" "{output.name_indexhtml}"'
|
|
|
|
return self.shellscript(s)
|
|
|
|
|
2016-02-27 17:45:32 +00:00
|
|
|
@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,
|
2016-02-25 18:35:46 +00:00
|
|
|
default=docbookdsl_finder(),
|
|
|
|
help='full path to html/docbook.dsl [%(default)s]')
|
2016-02-27 17:45:32 +00:00
|
|
|
g.add_argument('--docbooksgml-ldpdsl', type=arg_isreadablefile,
|
2016-02-25 18:35:46 +00:00
|
|
|
default=ldpdsl_finder(),
|
|
|
|
help='full path to ldp/ldp.dsl [%(default)s]')
|
2016-02-27 17:45:32 +00:00
|
|
|
g.add_argument('--docbooksgml-jw', type=arg_isexecutable,
|
2016-02-25 18:35:46 +00:00
|
|
|
default=which('jw'),
|
|
|
|
help='full path to jw [%(default)s]')
|
2016-02-27 17:45:32 +00:00
|
|
|
g.add_argument('--docbooksgml-html2text', type=arg_isexecutable,
|
2016-02-25 18:35:46 +00:00
|
|
|
default=which('html2text'),
|
|
|
|
help='full path to html2text [%(default)s]')
|
2016-02-27 17:45:32 +00:00
|
|
|
g.add_argument('--docbooksgml-openjade', type=arg_isexecutable,
|
2016-02-25 18:35:46 +00:00
|
|
|
default=which('openjade'),
|
|
|
|
help='full path to openjade [%(default)s]')
|
2016-02-27 17:45:32 +00:00
|
|
|
g.add_argument('--docbooksgml-dblatex', type=arg_isexecutable,
|
2016-02-25 18:35:46 +00:00
|
|
|
default=which('dblatex'),
|
|
|
|
help='full path to dblatex [%(default)s]')
|
2016-02-27 17:45:32 +00:00
|
|
|
g.add_argument('--docbooksgml-collateindex', type=arg_isexecutable,
|
|
|
|
default=which('collateindex.pl'),
|
2016-02-25 18:35:46 +00:00
|
|
|
help='full path to collateindex [%(default)s]')
|
|
|
|
|
2016-02-11 03:22:23 +00:00
|
|
|
#
|
|
|
|
# -- end of file
|