mirror of https://github.com/tLDP/python-tldp
initial commit
This commit is contained in:
commit
701657e54b
|
@ -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>`_
|
||||
|
|
@ -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,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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,11 @@
|
|||
#! /usr/bin/python
|
||||
|
||||
from ..utils import logger
|
||||
|
||||
|
||||
class Markdown(object):
|
||||
extensions = ['.md']
|
||||
signatures = []
|
||||
|
||||
#
|
||||
# -- end of file
|
|
@ -0,0 +1,11 @@
|
|||
#! /usr/bin/python
|
||||
|
||||
from ..utils import logger
|
||||
|
||||
|
||||
class RestructuredText(object):
|
||||
extensions = ['.rst']
|
||||
signatures = []
|
||||
|
||||
#
|
||||
# -- end of file
|
|
@ -0,0 +1,11 @@
|
|||
#! /usr/bin/python
|
||||
|
||||
from ..utils import logger
|
||||
|
||||
|
||||
class Text(object):
|
||||
extensions = ['.txt']
|
||||
signatures = []
|
||||
|
||||
#
|
||||
# -- end of 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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue