PageRenderTime 49ms CodeModel.GetById 13ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/config/makerestdoc.py

https://bitbucket.org/pypy/pypy/
Python | 227 lines | 220 code | 7 blank | 0 comment | 5 complexity | 48b451e2ff641ce9c5383a910aeacc9d MD5 | raw file
  1import py
  2from pypy.tool.rest.rst import Rest, Paragraph, Strong, ListItem, Title, Link
  3from pypy.tool.rest.rst import Directive, Text
  4
  5from rpython.config.config import ChoiceOption, BoolOption, StrOption, IntOption
  6from rpython.config.config import FloatOption, OptionDescription, Option, Config
  7from rpython.config.config import ArbitraryOption, DEFAULT_OPTION_NAME
  8from rpython.config.config import _getnegation
  9
 10configdocdir = py.path.local(__file__).dirpath().dirpath().join("doc", "config")
 11
 12def get_fullpath(opt, path):
 13    if path:
 14        return "%s.%s" % (path, opt._name)
 15    else:
 16        return opt._name
 17
 18
 19def get_cmdline(cmdline, fullpath):
 20    if cmdline is DEFAULT_OPTION_NAME:
 21        return '--%s' % (fullpath.replace('.', '-'),)
 22    else:
 23        return cmdline
 24
 25
 26class __extend__(Option):
 27    def make_rest_doc(self, path=""):
 28        fullpath = get_fullpath(self, path)
 29        result = Rest(
 30            Title(fullpath, abovechar="=", belowchar="="),
 31            ListItem(Strong("name:"), self._name),
 32            ListItem(Strong("description:"), self.doc))
 33        if self.cmdline is not None:
 34            cmdline = get_cmdline(self.cmdline, fullpath)
 35            result.add(ListItem(Strong("command-line:"), cmdline))
 36        return result
 37
 38class __extend__(ChoiceOption):
 39    def make_rest_doc(self, path=""):
 40        content = super(ChoiceOption, self).make_rest_doc(path)
 41        content.add(ListItem(Strong("option type:"), "choice option"))
 42        content.add(ListItem(Strong("possible values:"),
 43                             *[ListItem(str(val)) for val in self.values]))
 44        if self.default is not None:
 45            content.add(ListItem(Strong("default:"), str(self.default)))
 46
 47        requirements = []
 48
 49        for val in self.values:
 50            if val not in self._requires:
 51                continue
 52            req = self._requires[val]
 53            requirements.append(ListItem("value '%s' requires:" % (val, ),
 54                *[ListItem(Link(opt, opt + ".html"),
 55                           "to be set to '%s'" % (rval, ))
 56                      for (opt, rval) in req]))
 57        if requirements:
 58            content.add(ListItem(Strong("requirements:"), *requirements))
 59        return content
 60
 61class __extend__(BoolOption):
 62    def make_rest_doc(self, path=""):
 63        content = super(BoolOption, self).make_rest_doc(path)
 64        fullpath = get_fullpath(self, path)
 65        if self.negation and self.cmdline is not None:
 66            if self.cmdline is DEFAULT_OPTION_NAME:
 67                cmdline = '--%s' % (fullpath.replace('.', '-'),)
 68            else:
 69                cmdline = self.cmdline
 70            neg_cmdline = ["--" + _getnegation(argname.lstrip("-"))
 71                               for argname in cmdline.split()
 72                                   if argname.startswith("--")][0]
 73            content.add(ListItem(Strong("command-line for negation:"),
 74                                 neg_cmdline))
 75        content.add(ListItem(Strong("option type:"), "boolean option"))
 76        if self.default is not None:
 77            content.add(ListItem(Strong("default:"), str(self.default)))
 78        if self._requires is not None:
 79            requirements = [ListItem(Link(opt, opt + ".html"),
 80                               "must be set to '%s'" % (rval, ))
 81                                for (opt, rval) in self._requires]
 82            if requirements:
 83                content.add(ListItem(Strong("requirements:"), *requirements))
 84        if self._suggests is not None:
 85            suggestions = [ListItem(Link(opt, opt + ".html"),
 86                              "should be set to '%s'" % (rval, ))
 87                               for (opt, rval) in self._suggests]
 88            if suggestions:
 89                content.add(ListItem(Strong("suggestions:"), *suggestions))
 90        return content
 91
 92class __extend__(IntOption):
 93    def make_rest_doc(self, path=""):
 94        content = super(IntOption, self).make_rest_doc(path)
 95        content.add(ListItem(Strong("option type:"), "integer option"))
 96        if self.default is not None:
 97            content.add(ListItem(Strong("default:"), str(self.default)))
 98        return content
 99
100class __extend__(FloatOption):
101    def make_rest_doc(self, path=""):
102        content = super(FloatOption, self).make_rest_doc(path)
103        content.add(ListItem(Strong("option type:"), "float option"))
104        if self.default is not None:
105            content.add(ListItem(Strong("default:"), str(self.default)))
106        return content
107
108class __extend__(StrOption):
109    def make_rest_doc(self, path=""):
110        content = super(StrOption, self).make_rest_doc(path)
111        content.add(ListItem(Strong("option type:"), "string option"))
112        if self.default is not None:
113            content.add(ListItem(Strong("default:"), str(self.default)))
114        return content
115
116class __extend__(ArbitraryOption):
117    def make_rest_doc(self, path=""):
118        content = super(ArbitraryOption, self).make_rest_doc(path)
119        content.add(ListItem(Strong("option type:"),
120                             "arbitrary option (mostly internal)"))
121        if self.default is not None:
122            content.add(ListItem(Strong("default:"), str(self.default)))
123        elif self.defaultfactory is not None:
124            content.add(ListItem(Strong("factory for the default value:"),
125                                 str(self.defaultfactory)))
126        return content
127
128class __extend__(OptionDescription):
129    def make_rest_doc(self, path=""):
130        fullpath = get_fullpath(self, path)
131        content = Rest(
132            Title(fullpath, abovechar="=", belowchar="="))
133        toctree = []
134        for child in self._children:
135            subpath = fullpath + "." + child._name
136            toctree.append(subpath)
137        content.add(Directive("toctree", *toctree, **{'maxdepth': 4}))
138        content.join(
139            ListItem(Strong("name:"), self._name),
140            ListItem(Strong("description:"), self.doc))
141        return content
142
143
144def _get_section_header(cmdline, fullpath, subdescr):
145    # XXX:  pypy specific hack
146    txtfile = configdocdir.join(fullpath + ".txt")
147    if not txtfile.check():
148        print txtfile, "not found"
149        return ""
150    content = txtfile.read()
151    if ".. internal" in content:
152        return "Internal Options"
153    return ""
154
155def make_cmdline_overview(descr, title=True):
156    content = Rest()
157    if title:
158        content.add(
159            Title("Overview of Command Line Options for '%s'" % (descr._name, ),
160                  abovechar="=", belowchar="="))
161    cmdlines = []
162    config = Config(descr)
163    for path in config.getpaths(include_groups=False):
164        subconf, step = config._cfgimpl_get_home_by_path(path)
165        fullpath = (descr._name + "." + path)
166        subdescr = getattr(subconf._cfgimpl_descr, step)
167        cmdline = get_cmdline(subdescr.cmdline, fullpath)
168        if cmdline is not None:
169            header = _get_section_header(cmdline, fullpath, subdescr)
170            cmdlines.append((header, cmdline, fullpath, subdescr))
171    cmdlines.sort(key=lambda x: (x[0], x[1].strip("-")))
172    currheader = ""
173    curr = content
174    for header, cmdline, fullpath, subdescr in cmdlines:
175        if header != currheader:
176            content.add(Title(header, abovechar="", belowchar="="))
177            curr = content.add(Paragraph())
178            currheader = header
179        curr.add(ListItem(Link(cmdline + ":", fullpath + ".html"),
180                          Text(subdescr.doc)))
181    return content
182
183
184def register_config_role(docdir):
185    """ register a :config: ReST link role for use in documentation. """
186    try:
187        from docutils.parsers.rst import directives, states, roles
188        from pypy.tool.rest.directive import register_linkrole
189    except ImportError:
190        return
191    # enable :config: link role
192    def config_role(name, rawtext, text, lineno, inliner, options={},
193                    content=[]):
194        from docutils import nodes
195        from pypy.config.pypyoption import get_pypy_config
196        from pypy.config.makerestdoc import get_cmdline
197        txt = docdir.join("config", text + ".rst")
198        html = docdir.join("config", text + ".html")
199        assert txt.check()
200        assert name == "config"
201        sourcedir = py.path.local(inliner.document.settings._source).dirpath()
202        curr = sourcedir
203        prefix = ""
204        while 1:
205            relative = str(html.relto(curr))
206            if relative:
207                break
208            curr = curr.dirpath()
209            prefix += "../"
210        config = get_pypy_config()
211        # begin horror
212        h, n = config._cfgimpl_get_home_by_path(text)
213        opt = getattr(h._cfgimpl_descr, n)
214        # end horror
215        cmdline = get_cmdline(opt.cmdline, text)
216        if cmdline is not None:
217            shortest_long_option = 'X'*1000
218            for cmd in cmdline.split():
219                if cmd.startswith('--') and len(cmd) < len(shortest_long_option):
220                    shortest_long_option = cmd
221            text = shortest_long_option
222        target = prefix + relative
223        reference_node = nodes.reference(rawtext, text, name=text, refuri=target)
224        return [reference_node], []
225    config_role.content = True
226    config_role.options = {}
227    return config_role