#!/usr/bin/python # -*- coding: utf-8 -*- # lp4all: literate programming embedded in source code as wiki comments # Copyright (C) 2006 Jean-Marie Favreau, Frédéric Lehobey, David Mentré # and Thomas Petazzoni # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
It does the option parsing and perform the different phases of documentation generation.
import sys import fileparser import htmlbasicout import getopt import os import index import shutil import fs_tools from iface import Comment from label_dict import *
Default values for options
outdir = "." commenttag = 'w' project = 'Project' css = None
Display usage of Lp4all
def usage(): print "Usage: lp4all [-d outdir] [-t commenttag] [-p project] [-c css] filename1 [filename2 ...]" print " default outdir: '%s'" % outdir print " default commenttag: '%s'" % commenttag print " default project name: '%s'" % project if len(sys.argv) < 2: usage() sys.exit(1)
Parse all arguments using Python getopt
try: opts, args = getopt.getopt(sys.argv[1:], "d:t:hp:c:", ["help", "directory", "tag", "project", "css"]) except getopt.GetoptError: usage() sys.exit(1) for o, a in opts: if o in ("-h", "--help"): usage() sys.exit(0) elif o in ("-d", "--directory"): outdir = a elif o in ("-t", "--tag"): commenttag = a elif o in ("-p", "--project"): project = a elif o in ("-c", "--css"): css = a
Check that source-highlight is available in the PATH
sourceHighlightFound = False for path in os.getenv("PATH").split(':'): if os.path.exists(os.path.join(path, "source-highlight")): sourceHighlightFound = True break if not sourceHighlightFound: print "source-highlight not found, please install." sys.exit(1)
Various checks on given paths
if os.path.exists(outdir) and not os.path.isdir(outdir): print "output directory '%s' is not a directory" % outdir sys.exit(1) if css and not os.path.exists(css): print "CSS file '%s' not found" % css sys.exit(1)
Check that all files are really files and that they are given using relative paths
for file in args: if not os.path.isfile(file): print "only files are allowed, '%s' is not a file" % file sys.exit (1) if os.path.isabs(file): print "absolute filenames are not supported" sys.exit(1) fp = fileparser.FileParser(commenttag) ld = LabelDict.getSingleton()
First, split each file in blocks of comments and code (a list of
objects Code and Comment). Then, parse all blocks to build
the corresponding syntaxic tree (currently, it really does something
only for comment blocks). Finally, fill the label dictionnary with
the labels found in each comment block.
The result is file_blocks a list of tuples, where each tuple
links a filename to the list of blocks that composes the file.
file_blocks = {} for c, file in enumerate(args): file = os.path.normpath(file) print "Parsing code file %d/%d\r" % (c + 1, len(args)), blocks = fp.parse(file) for block in blocks: block.buildTree() labels = block.findLabels() for label in labels: ld.add(label, file, block.linestart, block.lineend) file_blocks[file] = blocks print
Build input dir tree. To do so, we build a list of all filenames in which each filename is itself a list of each path element or file.
inputdirs = fs_tools.getdirs('.', args)
parse each .lp4all files, add comments blocks in file_blocks if filename
is not index.lp4alland add founded labels to LabelDict.
lp4all_files = fs_tools.findLp4allFiles('.', inputdirs) for c, lp4all_file in enumerate(lp4all_files): print "Parsing lp4all file %d/%d\r" % (c + 1, len(lp4all_files)), lpfile = open(lp4all_file + ".lp4all") cmt = Comment(0, lp4all_file, 0, 1, lpfile.read()) cmt.buildTree() labels = cmt.findLabels() for label in labels: ld.add(label, lp4all_file, cmt.linestart, cmt.lineend) lpfile.close() if file_blocks.has_key(lp4all_file): file_blocks[lp4all_file].insert(0, cmt) else: file_blocks[lp4all_file] = [cmt] print
make all output directories
fs_tools.mkdirs(outdir, inputdirs)
Generate an HTML page for each directory. It allows to browse through the
different directories of the project, using inputdirs computed before.
index.build(outdir, project, '.', inputdirs, file_blocks)
Generate HTML for each .lp4all (except index.lp4all) and source file
c = 1 for file, blocks in file_blocks.iteritems(): print "Generating file %d/%d\r" % (c, len(file_blocks)), htmlbasicout.file(outdir, project, blocks, file) c += 1 print
Copy the CSS to the output directory. If a CSS is given as argument, use it direcetly. Otherwise, use the default CSS. In this case, we suppose that the default CSS is available in the same directory where the Lp4all main script is.
if css: shutil.copyfile(css, os.path.join(outdir, 'lp4all.css')) else: shutil.copyfile(os.path.join(os.path.dirname(sys.argv[0]), 'lp4all.css'), os.path.join(outdir, 'lp4all.css'))
lp4all main module