initial commit

This commit is contained in:
Martin A. Brown 2016-02-10 19:22:23 -08:00
commit 701657e54b
17 changed files with 460 additions and 0 deletions

31
README.rst Normal file
View File

@ -0,0 +1,31 @@
tldp - tools for publishing from TLDP sources
=============================================
TLDP = The Linux Documentation Project.
These are a set of scripts that process committed documents in the
TLDP document source repository to an output tree of choice.
Installation
------------
You can install, upgrade, uninstall tldp tools with these commands::
$ pip install tldp
$ pip install --upgrade tldp
$ pip uninstall tldp
There's also a package for Debian/Ubuntu, but it's not always the
latest version.
Example usages:
---------------
FIXME: Missing examples.
Links
-----
* `Output documentation tree (sample) <http://www.tldp.org/>`_
* `Source tree on GitHub <https://github.com/tLDP/LDP>`_

33
setup.py Normal file
View File

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
import os
from setuptools import setup, find_packages
with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as r_file:
readme = r_file.read()
setup(
name='tldp',
version='0.1',
license='GNU',
author='Martin A. Brown',
author_email='martin@linux-ip.net',
description='tools for processing all TLDP source documents',
long_description=readme,
packages=find_packages(),
test_suite='tests',
install_requires=[
'six>=1.7',
],
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Libraries :: Python Modules'
],
)

0
tldp/__init__.py Normal file
View File

View File

@ -0,0 +1,7 @@
from .text import Text
from .rst import RestructuredText
from .markdown import Markdown
from .linuxdoc import Linuxdoc
from .docbooksgml import DocbookSGML
from .docbook4xml import Docbook4XML
from .docbook5xml import Docbook5XML

27
tldp/doctypes/common.py Normal file
View File

@ -0,0 +1,27 @@
#! /usr/bin/python
from __future__ import print_function
import string
from ..utils import logger
class SignatureChecker(object):
@classmethod
def signatureLocation(cls, name, fin):
fin.seek(0)
buf = fin.read(1024)
for sig in cls.signatures:
try:
sindex = string.index(buf.lower(), sig.lower())
logger.debug("In file %s, signature %s found at %s; doctype %s found",
name, sig, sindex, cls)
return sindex
except ValueError:
logger.debug("In file %s, signature %s not found for document type %s",
name, sig, cls.__name__)
return None
#
# -- end of file

View File

@ -0,0 +1,17 @@
#! /usr/bin/python
from ..utils import logger
from .common import SignatureChecker
class Docbook4XML(SignatureChecker):
extensions = ['.xml']
signatures = ['-//OASIS//DTD DocBook XML V4.1.2//EN',
'-//OASIS//DTD DocBook XML V4.2//EN',
'-//OASIS//DTD DocBook XML V4.2//EN',
'-//OASIS//DTD DocBook XML V4.4//EN',
'-//OASIS//DTD DocBook XML V4.5//EN', ]
#
# -- end of file

View File

@ -0,0 +1,13 @@
#! /usr/bin/python
from ..utils import logger
from .common import SignatureChecker
class Docbook5XML(SignatureChecker):
extensions = ['.xml']
signatures = ['-//OASIS//DTD DocBook V5.0/EN',
'http://docbook.org/ns/docbook', ]
#
# -- end of file

View File

@ -0,0 +1,15 @@
#! /usr/bin/python
from ..utils import logger
from .common import SignatureChecker
class DocbookSGML(SignatureChecker):
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', ]
#
# -- end of file

24
tldp/doctypes/linuxdoc.py Normal file
View File

@ -0,0 +1,24 @@
#! /usr/bin/python
from ..utils import logger
from .common import SignatureChecker
class Linuxdoc(SignatureChecker):
extensions = ['.sgml']
signatures = ['<!doctype linuxdoc system', ]
def create_txt(self):
pass
def create_pdf(self):
pass
def create_html(self):
pass
def create_htmls(self):
pass
#
# -- end of file

11
tldp/doctypes/markdown.py Normal file
View File

@ -0,0 +1,11 @@
#! /usr/bin/python
from ..utils import logger
class Markdown(object):
extensions = ['.md']
signatures = []
#
# -- end of file

11
tldp/doctypes/rst.py Normal file
View File

@ -0,0 +1,11 @@
#! /usr/bin/python
from ..utils import logger
class RestructuredText(object):
extensions = ['.rst']
signatures = []
#
# -- end of file

11
tldp/doctypes/text.py Normal file
View File

@ -0,0 +1,11 @@
#! /usr/bin/python
from ..utils import logger
class Text(object):
extensions = ['.txt']
signatures = []
#
# -- end of file

86
tldp/guess.py Normal file
View File

@ -0,0 +1,86 @@
#! /usr/bin/python
from __future__ import print_function
import os
import inspect
from . import doctypes
from .utils import logger
def makefh(thing):
if isinstance(thing, file):
f = thing
elif isinstance(thing, str) and os.path.isfile(thing):
f = open(thing)
else:
raise TypeError("Cannot make file from type %s of %r" %
(type(thing), thing,))
return f
def listDoctypes():
knowndoctypes = list()
for name, member in inspect.getmembers(doctypes, inspect.isclass):
logger.info("Located class %s (%r).", name, member)
knowndoctypes.append(member)
logger.info("Capable of handling %s document classes.", len(knowndoctypes))
return knowndoctypes
def guess(thing):
try:
fin = makefh(thing)
except TypeError:
return None
_, ext = os.path.splitext(fin.name)
possible = [t for t in knowndoctypes if ext in t.extensions]
if not possible:
return None
if len(possible) == 1:
doctype = possible.pop()
return doctype
# -- for this extension, multiple document types, probably SGML, XML
#
logger.info("Extension is %s for %s; multiple possible document types.",
ext, fin.name)
for doctype in possible:
logger.debug("Extension is %s for %s; %s.", ext, fin.name, doctype)
guesses = list()
for doctype in possible:
sindex = doctype.signatureLocation(fin.name, fin)
if sindex is not None:
guesses.append((sindex, doctype))
if not guesses:
logger.info("Extension is %s for %s; but no matching signature found.",
ext, fin.name)
return None
if len(guesses) == 1:
_, doctype = guesses.pop()
return doctype
# -- OK, this is unusual; we still found multiple document type
# signatures. Seems rare but unlikely, so we should choose the
# first signature in the file as the more likely document type.
#
guesses.sort()
logger.info("Multiple guesses for file %s", fin.name)
for sindex, doctype in guesses:
logger.info("Could be %s (file position %s)", doctype, sindex)
logger.info("Going to guess that it is %s", doctype)
_, doctype = guesses.pop()
return doctype
knowndoctypes = listDoctypes()
knownextensions = set()
for x in knowndoctypes:
knownextensions.update(x.extensions)
#
# -- end of file

20
tldp/outputs.py Normal file
View File

@ -0,0 +1,20 @@
#! /usr/bin/python
import os
import sys
import logging
def getLogger(opts):
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
logger = logging.getLogger()
return logger
class SourceDocument(object):
def __init__(self, filename):
self.filename = fname
self.stem =
def
# -- end of file

20
tldp/processors.py Normal file
View File

@ -0,0 +1,20 @@
#! /usr/bin/python
import os
import sys
import logging
def getLogger(opts):
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
logger = logging.getLogger()
return logger
class SourceDocument(object):
def __init__(self, filename):
self.filename = fname
self.stem =
def
# -- end of file

118
tldp/sources.py Normal file
View File

@ -0,0 +1,118 @@
#! /usr/bin/python
from __future__ import print_function
import os
import sys
import logging
from .utils import logger
from .guess import knownextensions
# class SourceTree(object):
#
# def __init__(self, root, config):
# pass
class SourceDir(object):
def __repr__(self):
return self.dirname
def __init__(self, dirname):
self.dirname = os.path.abspath(dirname)
self.docs = list()
if not os.path.exists(dirname):
raise OSError("[Errno 2] No such file or directory: " + dirname)
logger.info("Time to go for an enumeration stroll in %s", dirname)
self.enumerateDocuments()
def enumerateDocuments(self):
for fname in os.listdir(self.dirname):
possible = os.path.join(self.dirname, fname)
if os.path.isfile(possible):
self.docs.append(SourceDocument(possible))
elif os.path.isdir(fname):
stem = os.path.basename(fname)
for ext in knownextensions:
possible = os.path.join(self.dirname, fname, stem + ext)
if os.path.isfile(possible):
self.docs.append(SourceDocument(possible))
logger.info("Discovered %s documents in %s",
len(self.docs), self.dirname)
class SourceDocument(object):
def __repr__(self):
return self.filename
def __init__(self, filename):
# -- canonicalize the pathname we are given.
self.filename = os.path.abspath(filename)
if not os.path.exists(self.filename):
raise OSError("Missing source document: " + self.filename)
self.dirname, self.basename = os.path.split(self.filename)
self.stem, self.ext = os.path.splitext(self.basename)
self.stat = os.stat(self.filename)
self.doctype = None
self.resources = False # -- assume no ./images/, ./resources/
self.singlefile = True # -- assume only one file
parentdir = os.path.basename(self.dirname)
if parentdir == self.stem:
self.singlefile = False
for rdir in ('resources', 'images'):
if os.path.exists(os.path.join(self.dirname, rdir)):
self.resources = True
def doctype(self):
if self.doctype is None:
self.doctype = guess(self.filename)
return self.doctype
class OutputDocument(object):
formats = {'pdf': '.pdf',
'txt': '.txt',
'html': '.html',
'htmls': '-single.html', }
def __init__(self, filename):
pass
@property
def txt(self):
return os.path.join(self.dirname, self.stem, '.txt')
class OutputDir(object):
def __init__(self, dirname):
self.dirname = os.path.abspath(dirname)
self.parent = os.path.dirname(dirname)
self.stem = os.path.basename(dirname)
self.members = list()
def mkdir(self):
if not os.path.exists(self.parent):
raise OSError("Missing parent directory: " + self.parent)
os.mkdir(self.dirname)
return os.path.exists(self.dirname)
@property
def members(self):
return os.path.exists(self.dirname)
@property
def exists(self):
return os.path.exists(self.dirname)
@property
def isComplete(self):
return all(self.pdf, self.html, self.htmls, self.txt)
# -- end of file

16
tldp/utils.py Normal file
View File

@ -0,0 +1,16 @@
#! /usr/bin/python
import sys
import logging
def getLogger(**opts):
level = opts.get('level', logging.INFO)
logging.basicConfig(stream=sys.stderr, level=level)
logger = logging.getLogger()
return logger
logger = getLogger()
#
# -- end of file