First draft of a doc generator for this

(Already supports multiple Modules per python module)
This commit is contained in:
enkore 2013-02-23 18:41:33 +01:00
parent d31fe9a62d
commit 9dc7041997
3 changed files with 222 additions and 0 deletions

167
i3pystatus/mkdocs.py Executable file
View File

@ -0,0 +1,167 @@
#!/usr/bin/env python
import sys
import io
import pkgutil
from collections import namedtuple
import i3pystatus
IGNORE = ("__main__", "mkdocs")
class Module:
name = ""
doc = ""
settings = []
class Setting:
name = ""
doc = ""
required = False
default = None
#finder = ClassFinder(baseclass=Module, exclude=[Module, IntervalModule, AsyncModule])
finder = i3pystatus.ModuleFinder()
def trim(docstring):
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxsize
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxsize:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
def get_modules():
modules = []
for finder, modname, ispkg in pkgutil.iter_modules(i3pystatus.get_path()):
if modname not in IGNORE:
modules.append(get_module(finder, modname))
return modules
def get_module(finder, modname):
fullname = "i3pystatus.{modname}".format(modname=modname)
return (modname, finder.find_loader(fullname)[0].load_module(fullname))
def get_settings(cls):
settings = []
for setting in cls.settings:
s = Setting()
if isinstance(setting, tuple):
s.name = setting[0]
s.doc = setting[1]
else:
s.name = setting
if setting in cls.required:
s.required = True
elif hasattr(cls, s.name):
s.default = getattr(cls, s.name)
settings.append(s)
return settings
def get_all():
mods = []
for name, module in get_modules():
classes = finder.search_module(module)
for cls in classes:
m = Module()
if len(classes) == 1:
m.name = name
else:
m.name = "{module}.{cls}".format(module=name, cls=cls.__name__)
if hasattr(cls, "__doc__"):
m.doc = cls.__doc__
elif hasattr(module, "__doc__"):
m.doc = module.__doc__
m.settings = get_settings(cls)
mods.append(m)
return mods
def format_settings(settings):
return "\n".join((format_setting(setting) for setting in settings))
def format_setting(setting):
attrs = []
if setting.required:
attrs.append("required")
if setting.default:
attrs.append("default: {default}".format(default=setting.default))
formatted = "* {name} ".format(name=setting.name)
if setting.doc or attrs:
formatted += ""
if setting.doc:
formatted += setting.doc
if attrs:
formatted += " ({attrs})".format(attrs=", ".join(attrs))
return formatted
def write_mods(f, mods):
for mod in mods:
f.write("""
### {name}
{doc}
{settings}\n""".format(
name=mod.name,
doc=trim(mod.doc),
settings=format_settings(mod.settings)
))
# io.StringIO
write_mods(sys.stdout, get_all())
with open("template.md", "r") as template:
tpl = template.read()
f = io.StringIO()
write_mods(f, get_all())
print(tpl.replace("!!module_doc!!", f.getvalue()))
# return [finder.search_module]
# mods = []
#
# for modname, module in modules:
# classes = finder.search_module(module)
#
#
#
# mods.append(get_mod(modname))
# mods.append(mod(
# name=modname,
# docstring=module.__doc__ if hasattr(module, "__doc__") else "",
# settings=get_settings(module)
# ))

4
mkdocs.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
python -m i3pystatus.mkdocs > README.md

51
template.md Normal file
View File

@ -0,0 +1,51 @@
# i3pystatus
i3pystatus is a (hopefully growing) collection of python scripts for
status output compatible to i3status / i3bar of the i3 window manager.
## Installation
To install it, follow these steps:
cd ~/.config/i3status/
git clone git@github.com:janoliver/i3pystatus contrib
cd contrib/i3pystatus
cp __main__.py.dist __main__.py
Add the following to `~/.config/i3status/config`:
general {
output_format = "i3bar"
colors = true
interval = 5
}
Change your i3wm config to the following:
# i3bar
bar {
status_command cd ~/.config/i3status/contrib ; i3status | python -m i3pystatus
position top
workspace_buttons yes
}
And finally adjust the settings in `~/.config/i3status/contrib/i3pystatus/__main__.py`
as you like.
## Modules
!!module_doc!!
## Contribute
To contribute a module, make sure it uses one of the Module classes. Most modules
use IntervalModule, which just calls a function repeatedly in a specified interval.
The output attribute should be set to a dictionary which represents your modules output,
the protocol is documented [here](http://i3wm.org/docs/i3bar-protocol.html).
Please add an example for how to configure it to `__main__.py.dist`. It should be
a python class that can be registered with the `I3statusHandler` class. Also don't
forget to add yourself to the LICENSE file.
**Patches and pull requests are very welcome :-)**