Initial import to Tizen
[profile/ivi/python-twisted.git] / twisted / lore / scripts / lore.py
1 # Copyright (c) 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, reflect
11 from twisted import plugin as plugin
12
13 class IProcessor(Interface):
14     """
15     """
16
17     name = Attribute("The user-facing name of this processor")
18
19     moduleName = Attribute(
20         "The fully qualified Python name of the object defining "
21         "this processor.  This object (typically a module) should "
22         "have a C{factory} attribute with C{generate_<output>} methods.")
23
24
25 class Options(usage.Options):
26
27     longdesc = "lore converts documentation formats."
28
29     optFlags = [["plain", 'p', "Report filenames without progress bar"],
30                 ["null", 'n', "Do not report filenames"],
31                 ["number", 'N', "Add chapter/section numbers to section headings"],
32 ]
33
34     optParameters = [
35                      ["input", "i", 'lore'],
36                      ["inputext", "e", ".xhtml", "The extension that your Lore input files have"],
37                      ["docsdir", "d", None],
38                      ["linkrel", "l", ''],
39                      ["output", "o", 'html'],
40                      ["index", "x", None, "The base filename you want to give your index file"],
41                      ["book", "b", None, "The book file to generate a book from"],
42                      ["prefixurl", None, "", "The prefix to stick on to relative links; only useful when processing directories"],
43                     ]
44
45     compData = usage.Completions(
46         extraActions=[usage.CompleteFiles(descr="files", repeat=True)])
47
48     def __init__(self, *args, **kw):
49         usage.Options.__init__(self, *args, **kw)
50         self.config = {}
51
52     def opt_config(self, s):
53         if '=' in s:
54             k, v = s.split('=', 1)
55             self.config[k] = v
56         else:
57             self.config[s] = 1
58
59     def parseArgs(self, *files):
60         self['files'] = files
61
62
63 def getProcessor(input, output, config):
64     plugins = plugin.getPlugins(IProcessor)
65     for plug in plugins:
66         if plug.name == input:
67             module = reflect.namedModule(plug.moduleName)
68             break
69     else:
70         # try treating it as a module name
71         try:
72             module = reflect.namedModule(input)
73         except ImportError:
74             print '%s: no such input: %s' % (sys.argv[0], input)
75             return
76     try:
77         return process.getProcessor(module, output, config)
78     except process.NoProcessorError, e:
79         print "%s: %s" % (sys.argv[0], e)
80
81
82 def getWalker(df, opt):
83     klass = process.Walker
84     if opt['plain']:
85         klass = process.PlainReportingWalker
86     if opt['null']:
87         klass = process.NullReportingWalker
88     return klass(df, opt['inputext'], opt['linkrel'])
89
90
91 def runGivenOptions(opt):
92     """Do everything but parse the options; useful for testing.
93     Returns a descriptive string if there's an error."""
94
95     book = None
96     if opt['book']:
97         book = htmlbook.Book(opt['book'])
98
99     df = getProcessor(opt['input'], opt['output'], opt.config)
100     if not df:
101         return 'getProcessor() failed'
102
103     walker = getWalker(df, opt)
104
105     if opt['files']:
106         for filename in opt['files']:
107             walker.walked.append(('', filename))
108     elif book:
109         for filename in book.getFiles():
110             walker.walked.append(('', filename))
111     else:
112         walker.walkdir(opt['docsdir'] or '.', opt['prefixurl'])
113
114     if opt['index']:
115         indexFilename = opt['index']
116     elif book:
117         indexFilename = book.getIndexFilename()
118     else:
119         indexFilename = None
120
121     if indexFilename:
122         indexer.setIndexFilename("%s.%s" % (indexFilename, opt['output']))
123     else:
124         indexer.setIndexFilename(None)
125
126     ## TODO: get numberSections from book, if any
127     numberer.setNumberSections(opt['number'])
128
129     walker.generate()
130
131     if walker.failures:
132         for (file, errors) in walker.failures:
133             for error in errors:
134                 print "%s:%s" % (file, error)
135         return 'Walker failures'
136
137
138 def run():
139     opt = Options()
140     try:
141         opt.parseOptions()
142     except usage.UsageError, errortext:
143         print '%s: %s' % (sys.argv[0], errortext)
144         print '%s: Try --help for usage details.' % sys.argv[0]
145         sys.exit(1)
146
147     result = runGivenOptions(opt)
148     if result:
149         print result
150         sys.exit(1)
151
152
153 if __name__ == '__main__':
154     run()
155