![]() Pdx |
Table of Contents
1. OverviewPdx takes the basic syntax of Perl's Pod, adds much of the functionality of Sdf, and implements it in a maintainable set of python modules and objects. The goal is a simple markup language which:
2. Project ArchitectureThe dir tree is:
---the actual code---
Pdx/
__init__.py
Base.py
Docbook.py
Html.py
Latex.py
---scripts for the bin dir---
scripts/
pdx2docbook.py
pdx2html.py
pdx2latex.py
---documentation---
doc/
go
default_cfg.pdx settings for the documents
article_style.pdx tuned for this project
deshist.pdx design history (includes the perl Pdx notes)
devguide.pdx developer's guide
devguide_base.pdx general material about Base.py
devguide_html.pdx specific to Html.py
manual.pdx user's manual
---testing---
test/
all_tests.py pyunit master module
basic_tests.py the tests
go_test run the tests
go_doc build documentation
go_dist build distribution tarball
go_web install tarball on website
view_latex nn convert testnn's results for xdvi view
view_docbok nn convert testnn's results for xdvi view
testdata/
default_cfg.pdx default settings
article_style.pdx local stylesheet
dummy.pdx used for includes
dummy_html.pdx used for html includes
dummy_latex.pdx used for latex includes
dummy_docbook.pdx used for docbook includes
testnn.pdx tests (nn=01,02,...)
oraclenn.html,tex,sgml oracles or "known good" results (nn=01,02,...)
---stylesheets---
doc/styles/
default_cfg_.pdx generic defaults file
article_style.pdx generic stylesheet
docbook_article.pdx docbook "article"
html_article.pdx html web page, with sidebars and header/footer
latex_article.pdx "article"
latex_foils.pdx use foils.sty
latex_seminar.pdx use seminar.sty
Modules (per pydoc):
3. Testing3.1. Running tests
3.2. Adding testsIn test/testdata, copy test01.pdx and tweak as needed to exercise your new feature. Remember to change the cfg title = ... and desc = .... In basic_tests.py, add a method for your new test number, for each driver. Also add it to the list of "cases" in the suite definition. Run the go_test script. Since there is no oracle ("known good" output) the test will fail.
Bring up the resulting oracle (e.g., oracle11.html) in the driver-specific viewer and check it out. For Html, we can use a web browser. For latex, we need to run latex and view the dvi (using viewtex). To view the test11.tex file, run viewtex 11. If the test result is wrong debug your program and try again. When all is well, update the oracle by kill_html nn: kill_html 11This will remove the old oracle, and install your new one. Continue testing for all the drivers.
4. Module architectureBase.py does most of the work, calling the driver modules when needed for output. The driver classes inherit Base.Base. Each driver's __init__ can add more startup features, such as additional flags.
4.1. BaseThe __init__ method creates an object and loads various default values. The parse method reads and uses the input parameters, then opens and reads the file.
4.1.1. ParametersCommandline options are all in the long form ("--....."). Typically these are used to toggle switches on and off, e.g., whether or not to generate a table of contents. The internal data members for the switches end in _p, from the Lisp idiom for predicates. The input parameters with a leading underscore ("_") cannot be set or reset directly by the end user via =define or =cfg commands. The idea is that these are critical to the internal integrity of the system. In general, we set defaults, override these with command line parameters, and override these further with =cfg or =define commands. Individual drivers, or even individual methods can add additional data members. For example, when we are deciding whether or not to do a table of contents:
4.1.2. InputThe idea is to read into an array called self.lines, and then process this array twice (to resolve forward references). Reading from the array is controlled by self.morelines() and self.nextline(). Typically:
while self.morelines():
line=self.nextline()
(process the line)
self.morelines is checking self.ndx, the index of the array. If you need to backup, decrement that value:
self.ndx=self.ndx-1 self.nextline() increments ndx, gets the line, and does macro expansion on "@...@" terms when expand_p=1.
The raw array is modified by the do_include method. This reads an external file and splices the lines into the array, so the processing assumes they were there all along. In theory, we could get a loop of includes. There is not (yet) a check for this -- so be careful.
4.1.3. ErrorsWe give simple errors on the first pass, if we can safely continue processing, but don't do the second pass. We stop immediately if a fatal error is found:
self.err("this is bad, but we can go on")
self.fatal("we're dead right now")
4.1.4. PassesThe 2-pass loop in parse has to reset some data members (e.g., counters) for each pass. Of course, one thing it does is reset self.ndx to 0. Finally, we do the self.process_file. On the second pass, we worry about printing all the data we've collected. For one thing, we need to do a preamble and postamble around the basic content.
4.1.5. Processingself.process_file is a loop with a long series of regexp matches. If the match succeeds, the appropriate subroutine is called and the loop is "continued". The regular expression matches are roughly ordered by expected frequency. A possible improvement would be a generic pattern match on "^\s*=([a-z1-9_]+)", and then a lookup table for specific routines. Each do_ method handles as much as it can, but passes responsibility to driver_ functions as needed. This split is sure to change as new functions and new drivers are added.
4.2. HtmlHtml.pm is the initial driver for the system, and should be considered the template for other drivers. Considerations for developers include:
|
|
Creator: Harry George Updated/Created: 2002-06-24 |