OLD | NEW |
| (Empty) |
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
2 # See LICENSE for details. | |
3 | |
4 import sys | |
5 | |
6 from zope.interface import Interface, Attribute | |
7 | |
8 from twisted.lore import process, indexer, numberer, htmlbook | |
9 | |
10 from twisted.python import usage, plugin as oldplugin, reflect | |
11 from twisted import plugin as newplugin | |
12 | |
13 class IProcessor(Interface): | |
14 """ | |
15 """ | |
16 | |
17 factory = Attribute( | |
18 "") | |
19 | |
20 class Options(usage.Options): | |
21 | |
22 optFlags = [["plain", 'p', "Report filenames without progress bar"], | |
23 ["null", 'n', "Do not report filenames"], | |
24 ["number", 'N', "Add chapter/section numbers to section headings
"], | |
25 ] | |
26 | |
27 optParameters = [ | |
28 ["input", "i", 'lore'], | |
29 ["inputext", "e", ".xhtml", "The extension that your Lore i
nput files have"], | |
30 ["docsdir", "d", None], | |
31 ["linkrel", "l", ''], | |
32 ["output", "o", 'html'], | |
33 ["index", "x", None, "The base filename you want to give yo
ur index file"], | |
34 ["book", "b", None, "The book file to generate a book from"
], | |
35 ["prefixurl", None, "", "The prefix to stick on to relative
links; only useful when processing directories"], | |
36 ] | |
37 | |
38 #zsh_altArgDescr = {"foo":"use this description for foo instead"} | |
39 #zsh_multiUse = ["foo", "bar"] | |
40 #zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")] | |
41 #zsh_actions = {"foo":'_files -g "*.foo"', "bar":"(one two three)"} | |
42 #zsh_actionDescr = {"logfile":"log file name", "random":"random seed"} | |
43 zsh_extras = ["*:files:_files"] | |
44 | |
45 def __init__(self, *args, **kw): | |
46 usage.Options.__init__(self, *args, **kw) | |
47 self.config = {} | |
48 | |
49 def opt_config(self, s): | |
50 if '=' in s: | |
51 k, v = s.split('=', 1) | |
52 self.config[k] = v | |
53 else: | |
54 self.config[s] = 1 | |
55 | |
56 def parseArgs(self, *files): | |
57 self['files'] = files | |
58 | |
59 | |
60 def getProcessor(input, output, config): | |
61 plugins = oldplugin._getPlugIns("lore") | |
62 for plug in plugins: | |
63 if plug.tapname == input: | |
64 module = plug.load() | |
65 break | |
66 else: | |
67 plugins = newplugin.getPlugins(IProcessor) | |
68 for plug in plugins: | |
69 if plug.name == input: | |
70 module = reflect.namedModule(plug.moduleName) | |
71 break | |
72 else: | |
73 # try treating it as a module name | |
74 try: | |
75 module = reflect.namedModule(input) | |
76 except ImportError: | |
77 print '%s: no such input: %s' % (sys.argv[0], input) | |
78 return | |
79 try: | |
80 return process.getProcessor(module, output, config) | |
81 except process.NoProcessorError, e: | |
82 print "%s: %s" % (sys.argv[0], e) | |
83 | |
84 | |
85 def getWalker(df, opt): | |
86 klass = process.Walker | |
87 if opt['plain']: | |
88 klass = process.PlainReportingWalker | |
89 if opt['null']: | |
90 klass = process.NullReportingWalker | |
91 return klass(df, opt['inputext'], opt['linkrel']) | |
92 | |
93 | |
94 def runGivenOptions(opt): | |
95 """Do everything but parse the options; useful for testing. | |
96 Returns a descriptive string if there's an error.""" | |
97 | |
98 book = None | |
99 if opt['book']: | |
100 book = htmlbook.Book(opt['book']) | |
101 | |
102 df = getProcessor(opt['input'], opt['output'], opt.config) | |
103 if not df: | |
104 return 'getProcessor() failed' | |
105 | |
106 walker = getWalker(df, opt) | |
107 | |
108 if opt['files']: | |
109 for filename in opt['files']: | |
110 walker.walked.append(('', filename)) | |
111 elif book: | |
112 for filename in book.getFiles(): | |
113 walker.walked.append(('', filename)) | |
114 else: | |
115 walker.walkdir(opt['docsdir'] or '.', opt['prefixurl']) | |
116 | |
117 if opt['index']: | |
118 indexFilename = opt['index'] | |
119 elif book: | |
120 indexFilename = book.getIndexFilename() | |
121 else: | |
122 indexFilename = None | |
123 | |
124 if indexFilename: | |
125 indexer.setIndexFilename("%s.%s" % (indexFilename, opt['output'])) | |
126 else: | |
127 indexer.setIndexFilename(None) | |
128 | |
129 ## TODO: get numberSections from book, if any | |
130 numberer.setNumberSections(opt['number']) | |
131 | |
132 walker.generate() | |
133 | |
134 if walker.failures: | |
135 for (file, errors) in walker.failures: | |
136 for error in errors: | |
137 print "%s:%s" % (file, error) | |
138 return 'Walker failures' | |
139 | |
140 | |
141 def run(): | |
142 opt = Options() | |
143 try: | |
144 opt.parseOptions() | |
145 except usage.UsageError, errortext: | |
146 print '%s: %s' % (sys.argv[0], errortext) | |
147 print '%s: Try --help for usage details.' % sys.argv[0] | |
148 sys.exit(1) | |
149 | |
150 result = runGivenOptions(opt) | |
151 if result: | |
152 print result | |
153 sys.exit(1) | |
154 | |
155 | |
156 if __name__ == '__main__': | |
157 run() | |
158 | |
OLD | NEW |