]> granicus.if.org Git - zziplib/commitdiff
allow dir2man to generate html, plus dir2index to complete the htmpages.tar #46
authorGuido Draheim <guidod@gmx.de>
Sat, 24 Mar 2018 10:25:40 +0000 (11:25 +0100)
committerGuido Draheim <guidod@gmx.de>
Sat, 24 Mar 2018 10:25:40 +0000 (11:25 +0100)
docs/Makefile.am
docs/Makefile.in
docs/dbk2man.py
docs/dir2index.py [new file with mode: 0755]

index 526b10679a0259ae7f8be2e59c237f8e264a5121..505093499ae5f9eb217639501c919703ae3f73e9 100644 (file)
@@ -22,6 +22,7 @@ changelog = @top_srcdir@/ChangeLog
 
 EXTRA_DIST = make-doc.py $(doc_FILES) $(htm_FILES) $(SDL_RWOPS) \
              make-doc.pl make-dbk.pl   mksite.sh mksite.pl body.htm \
+             dbk2man.py dir2index.py \
              $(zzipdoc_FILES) sdocbook.css \
              zziplib-manpages.dbk zziplib-master.dbk \
              zziplib-manpages.tar
@@ -193,6 +194,25 @@ htmpages.tar : zziplib.xml zzipmmapped.xml zzipfseeko.xml zziplib-manpages.dbk
        ; echo '$(DELETE); rm html/*.* ; rmdir html' \
        ;       $(DELETE); rm html/*.* ; rmdir html  \
        ; fi ; true
+       @ if test "$(XMLTO)" = ":" \
+       ; then echo going to regenerate "$@" in subdir "'"html"'" \
+       ; echo 'test ! -d html || rm /* ; test -d html || mkdir html' \
+       ;       test ! -d html || rm html/* ; test -d html || mkdir html  \
+       ; echo 'cp $(srcdir)/zziplib-manpages.dbk zziplib-manpages.xml' \
+       ;       cp $(srcdir)/zziplib-manpages.dbk zziplib-manpages.xml \
+       ; echo     '$(srcdir)/dbk2man.py -o html html zziplib.xml' \
+       ; $(PYTHON) $(srcdir)/dbk2man.py -o html html zziplib.xml  \
+       ; echo     '$(srcdir)/dbk2man.py -o html html zzipmmapped.xml' \
+       ; $(PYTHON) $(srcdir)/dbk2man.py -o html html zzipmmapped.xml  \
+       ; echo     '$(srcdir)/dbk2man.py -o html html zzipfseeko.xml' \
+       ; $(PYTHON) $(srcdir)/dbk2man.py -o html html zzipfseeko.xml  \
+       ; echo     '$(srcdir)/dir2index.py -o html html ' \
+       ; $(PYTHON) $(srcdir)/dir2index.py -o html html   \
+       ; echo '$(PAX_TAR_CREATE) $@ html/*.*' \
+       ;       $(PAX_TAR_CREATE) $@ html/*.*  \
+       ; echo '$(DELETE); rm html/*.* ; rmdir html' \
+       ;       $(DELETE); rm html/*.* ; rmdir html  \
+       ; fi ; true
        @ if test -s $@ \
        ; then echo cp $@ zziplib-$@ "(saved)"; cp $@ zziplib-$@ \
        ; else echo cp $(srcdir)/zziplib-$@ $@; cp $(srcdir)/zziplib-$@ $@ \
index d04c677b0ee712f57b90a7eeea9490909eace121..219c5b30385a617464dc2afef6ddafd504a2c727 100644 (file)
@@ -325,6 +325,7 @@ SDL_RWOPS = $(SDL)/SDL_rwops_zzcat.c \
 changelog = @top_srcdir@/ChangeLog
 EXTRA_DIST = make-doc.py $(doc_FILES) $(htm_FILES) $(SDL_RWOPS) \
              make-doc.pl make-dbk.pl   mksite.sh mksite.pl body.htm \
+             dbk2man.py dir2index.py \
              $(zzipdoc_FILES) sdocbook.css \
              zziplib-manpages.dbk zziplib-master.dbk \
              zziplib-manpages.tar
@@ -699,6 +700,25 @@ htmpages.tar : zziplib.xml zzipmmapped.xml zzipfseeko.xml zziplib-manpages.dbk
        ; echo '$(DELETE); rm html/*.* ; rmdir html' \
        ;       $(DELETE); rm html/*.* ; rmdir html  \
        ; fi ; true
+       @ if test "$(XMLTO)" = ":" \
+       ; then echo going to regenerate "$@" in subdir "'"html"'" \
+       ; echo 'test ! -d html || rm /* ; test -d html || mkdir html' \
+       ;       test ! -d html || rm html/* ; test -d html || mkdir html  \
+       ; echo 'cp $(srcdir)/zziplib-manpages.dbk zziplib-manpages.xml' \
+       ;       cp $(srcdir)/zziplib-manpages.dbk zziplib-manpages.xml \
+       ; echo     '$(srcdir)/dbk2man.py -o html html zziplib.xml' \
+       ; $(PYTHON) $(srcdir)/dbk2man.py -o html html zziplib.xml  \
+       ; echo     '$(srcdir)/dbk2man.py -o html html zzipmmapped.xml' \
+       ; $(PYTHON) $(srcdir)/dbk2man.py -o html html zzipmmapped.xml  \
+       ; echo     '$(srcdir)/dbk2man.py -o html html zzipfseeko.xml' \
+       ; $(PYTHON) $(srcdir)/dbk2man.py -o html html zzipfseeko.xml  \
+       ; echo     '$(srcdir)/dir2index.py -o html html ' \
+       ; $(PYTHON) $(srcdir)/dir2index.py -o html html   \
+       ; echo '$(PAX_TAR_CREATE) $@ html/*.*' \
+       ;       $(PAX_TAR_CREATE) $@ html/*.*  \
+       ; echo '$(DELETE); rm html/*.* ; rmdir html' \
+       ;       $(DELETE); rm html/*.* ; rmdir html  \
+       ; fi ; true
        @ if test -s $@ \
        ; then echo cp $@ zziplib-$@ "(saved)"; cp $@ zziplib-$@ \
        ; else echo cp $(srcdir)/zziplib-$@ $@; cp $(srcdir)/zziplib-$@ $@ \
index 83edef134a94bfc978fbc60e1748919fc217d1b6..59a4b5f96593248ebff91358a00165b7f9dcdfc3 100755 (executable)
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#! /usr/bin/python>
 from __future__ import print_function
 
 """ Converts an xml-file with docbook elements into troff manual pages.
@@ -15,6 +15,23 @@ import xml.etree.ElementTree as ET
 
 logg = logging.getLogger("dbk2man")
 
+def esc(text):
+    text = text.replace(".", "\\&.")
+    text = text.replace("-", "\\-")
+    return text
+def unescape(text):
+    text = text.replace('&lt;', '<')
+    text = text.replace('&gt;', '>')
+    text = text.replace('&quot;', '"')
+    text = text.replace('&amp;', '&')
+    return text
+def htm(text):
+    text = text.replace('&', '&amp;')
+    text = text.replace('<', '&lt;')
+    text = text.replace('>', '&gt;')
+    text = text.replace('"', '&quot;')
+    return text
+
 def parse_docbook(filename):
     tree = ET.parse(filename)
     return tree.getroot()
@@ -47,16 +64,6 @@ def docbook2(man, root, subdirectory = "."):
             overview[refname] = refpurpose
     return overview
 
-def esc(text):
-    text = text.replace(".", "\\&.")
-    text = text.replace("-", "\\-")
-    return text
-def unescape(text):
-    text = text.replace('&lt;', '<')
-    text = text.replace('&gt;', '>')
-    text = text.replace('&quot;', '"')
-    text = text.replace('&amp;', '&')
-    return text
 
 
 def refentryinfo2(man, refentry, title):
@@ -73,23 +80,36 @@ def refentryinfo2(man, refentry, title):
         if found is not None: refentrytitle = found.text
         found = section.find("manvolnum")
         if found is not None: manvolnum = found.text
-    header = []
-    if refentrytitle:
-        header += [ refentrytitle ]
-        if manvolnum:
-            header += [ manvolnum ]
-            if date:
-                header += [ date ]
-                if productname:
-                    header += [ productname ]
-                if title:
-                    header += [ title ]
-    if header:
+    if man:
+        header = []
+        if refentrytitle:
+            header += [ refentrytitle ]
+            if manvolnum:
+                header += [ manvolnum ]
+                if date:
+                    header += [ date ]
+                    if productname:
+                        header += [ productname ]
+                    if title:
+                        header += [ title ]
+        if not header:
+            logg.warning("no <refmeta> found")
+            return ""
         text = '.TH ' + " ".join([ '"%s"' % esc(part) for part in header])
         return text + "\n"
     else:
-        logg.warning("no <refmeta> found")
-        return ""
+        text = "<html><head><title>"
+        if productname or title: 
+            text += "%s: " % htm(productname or title)
+        text += htm(refentrytitle)
+        if manvolnum: 
+            text += "(%s)" % htm(manvolnum)
+        text += "</title>"
+        text += "\n" + '<meta name="product" content="%s" />' % htm(productname or title)
+        text += "\n" + '<meta name="refentry" content="%s" />' % htm(refentrytitle)
+        text += "\n" + '<meta name="manvolnum" content="%s" />' % htm(manvolnum)
+        text += "\n" + '<meta name="date" content="%s" />' % htm(date)
+        return text + "\n</head><body>\n"
 
 def refentrytitle2(man, refentry, title = ""):
     refentrytitle = ""
@@ -107,90 +127,166 @@ def refentrytitle2(man, refentry, title = ""):
              refname = found.text
              if refname not in refentries:
                  refentries.append(refname)
-    if refentrytitle:
+    if not refentrytitle:
+        logg.warning("no <refentrytitle> found")
+        return ""
+    elif man:
         text = '.SH "NAME"' + "\n"
         text += "" + esc(", ".join(refentries))
         text += " " + esc("-")
         text += " " + esc(refpurpose)
         return text + "\n"
     else:
-        logg.warning("no <refentrytitle> found")
-        return ""
-
+        text = '<h3>Name</h3>' + "\n"
+        text += "<p>" + htm(", ".join(refentries))
+        text += " " + htm("-")
+        text += " " + htm(refpurpose)
+        text += "</p>"
+        return text + "\n"
 
 def refsynopsisdiv2(man, refentry, title = ""):
-    section = refentry.find("refsynopsisdiv")
-    if section is not None:
-        text = '.SH "SYNOPSIS"' + "\n"
-        text += ".sp\n"
-        text += ".nf\n"
-        for funcsynopsis in section.findall("funcsynopsis"):
-            funcsynopsisinfo = ""
-            found = funcsynopsis.find("funcsynopsisinfo")
-            if found is not None: funcsynopsisinfo = found.text
-            if funcsynopsisinfo:
-                for info in funcsynopsisinfo.split("\n"):
-                    text += '.B "%s"' % esc(info)
-                    text += "\n"
-                text += ".sp" + "\n"
-            else:
-                logg.debug("no <funcsynopsisinfo> found")
-                logg.debug("\n%s", ET.tostring(funcsynopsis))
-            funcs = 0
-            for funcprototype in funcsynopsis.findall("funcprototype"):
-                item = ET.tostring(funcprototype)
-                item = item.replace("<funcprototype>","")
-                item = item.replace("</funcprototype>","")
-                if False:
-                    item = item.replace("\n", " ")
-                    item = item.replace("<funcdef>","")
-                    item = item.replace("</funcdef>","")
-                    item = item.replace("<paramdef>",'<def>')
-                    item = item.replace("</paramdef>",'<def>')
-                    items = item.split("<def>")
-                    text += '.BI %s' % " ".join(['"%s"' % part for part in items if part])
-                else:
-                    item = item.replace("<funcdef>","")
-                    item = re.sub(r"([_\w]+)</funcdef>", lambda x: "\\fI%s\\fR" % x.group(1), item)
-                    item = item.replace("<paramdef>",'')
-                    item = item.replace("</paramdef>",'')
-                    text += item 
+    refsynopsisdiv = refentry.find("refsynopsisdiv")
+    if refsynopsisdiv is None:
+        logg.warning("no <resynopsisdiv> found")
+        return ""
+    if man:
+        return refsynopsisdiv2man(refsynopsisdiv, title)
+    else:
+        return refsynopsisdiv2htm(refsynopsisdiv, title)
+
+def refsynopsisdiv2man(refsynopsisdiv, title = ""):
+    text = '.SH "SYNOPSIS"' + "\n"
+    text += ".sp\n"
+    text += ".nf\n"
+    for funcsynopsis in refsynopsisdiv.findall("funcsynopsis"):
+        funcsynopsisinfo = ""
+        found = funcsynopsis.find("funcsynopsisinfo")
+        if found is not None: funcsynopsisinfo = found.text
+        if funcsynopsisinfo:
+            for info in funcsynopsisinfo.split("\n"):
+                text += '.B "%s"' % esc(info)
                 text += "\n"
-                funcs += 1
-            if not funcs:
-                logg.warning("no <funcprototype> found")
-                logg.warning("\n%s", ET.tostring(funcsynopsis))
-            text += ".fi" + "\n"
             text += ".sp" + "\n"
-        return text
-    else:
-        logg.warning("no <resynopsidiv> found")
-        return ""
+        else:
+            logg.debug("no <funcsynopsisinfo> found")
+            logg.debug("\n%s", ET.tostring(funcsynopsis))
+        funcs = 0
+        for funcprototype in funcsynopsis.findall("funcprototype"):
+            item = ET.tostring(funcprototype)
+            item = item.replace("<funcprototype>","")
+            item = item.replace("</funcprototype>","")
+            if False:
+                item = item.replace("\n", " ")
+                item = item.replace("<funcdef>","")
+                item = item.replace("</funcdef>","")
+                item = item.replace("<paramdef>",'<def>')
+                item = item.replace("</paramdef>",'<def>')
+                items = item.split("<def>")
+                text += '.BI %s' % " ".join(['"%s"' % part for part in items if part])
+            else:
+                item = item.replace("<funcdef>","")
+                item = re.sub(r"([_\w]+)</funcdef>", lambda x: "\\fI%s\\fR" % x.group(1), item)
+                item = item.replace("<paramdef>",'')
+                item = item.replace("</paramdef>",'')
+                text += item 
+            text += "\n"
+            funcs += 1
+        if not funcs:
+            logg.warning("no <funcprototype> found")
+            logg.warning("\n%s", ET.tostring(funcsynopsis))
+        text += ".fi" + "\n"
+        text += ".sp" + "\n"
+    return text
+
+def refsynopsisdiv2htm(refsynopsisdiv, title = ""):
+    text = '<h3>Synopsis</h3>' + "\n"
+    text += '<pre>' + "\n"
+    for funcsynopsis in refsynopsisdiv.findall("funcsynopsis"):
+        funcsynopsisinfo = ""
+        found = funcsynopsis.find("funcsynopsisinfo")
+        if found is not None: funcsynopsisinfo = found.text
+        if funcsynopsisinfo:
+            for info in funcsynopsisinfo.split("\n"):
+                text += '<b>%s</b>' % htm(info)
+                text += "\n"
+            text += "\n"
+        else:
+            logg.debug("no <funcsynopsisinfo> found")
+            logg.debug("\n%s", ET.tostring(funcsynopsis))
+        funcs = 0
+        for funcprototype in funcsynopsis.findall("funcprototype"):
+            item = ET.tostring(funcprototype)
+            item = item.replace("<funcprototype>","")
+            item = item.replace("</funcprototype>","")
+            item = item.replace("<funcdef>","")
+            item = re.sub(r"([_\w]+)</funcdef>", lambda x: "<b>%s</b>" % x.group(1), item)
+            item = item.replace("<paramdef>",'')
+            item = item.replace("</paramdef>",'')
+            text += item 
+            text += "\n"
+            funcs += 1
+        if not funcs:
+            logg.warning("no <funcprototype> found")
+            logg.warning("\n%s", ET.tostring(funcsynopsis))
+        text += "</pre>" + "\n"
+    return text
 
 def refsections2(man, refentry, title = ""):
     text = ""
     for refsect in refentry.findall("refsect1"):
-        head = refsect.find("title")
-        if head is not None:
-           text += '.SH "%s"' % (esc(head.text.upper()))
-           text += "\n"
-        for para in list(refsect):
-            if para.tag == 'title':
-                continue
-            if para.tag == 'para':
-                text += cleanpara(para) + "\n"
+        if man:
+            text += refsect2man(refsect, title)
+            text += ".sp\n"
+        else:
+            text += refsect2htm(refsect, title)
+    return text
+
+
+def refsect2man(refsect, title = ""):
+    text = ""
+    head = refsect.find("title")
+    if head is not None:
+       text += '.SH "%s"' % (esc(head.text.upper()))
+       text += "\n"
+    for para in list(refsect):
+        if para.tag == 'title':
+            continue
+        if para.tag == 'para':
+            text += para2man(para) + "\n"
+            text += ".sp\n"
+            continue
+        if para.tag == 'itemizedlist':
+            for item in list(para):
+                text += para2man(item) + "\n"
                 text += ".sp\n"
-                continue
-            if para.tag == 'itemizedlist':
-                for item in list(para):
-                    text += cleanpara(item) + "\n"
-                    text += ".sp\n"
-                continue
-            logg.warning("unknown para <%s>", para.tag)
-        text += ".sp\n"
+            continue
+        logg.warning("unknown para <%s>", para.tag)
+    return text
+
+def refsect2htm(refsect, title = ""):
+    text = ""
+    head = refsect.find("title")
+    if head is not None:
+       text += '<h3>%s</h3>' % htm(head.text)
+       text += "\n"
+    for para in list(refsect):
+        if para.tag == 'title':
+            continue
+        if para.tag == 'para':
+            text += "<p>" + para2htm(para)
+            text += "</p>" + "\n"
+            continue
+        if para.tag == 'itemizedlist':
+            text += "<ul>" + "\n"
+            for item in list(para):
+                text + "<li><p>" + para2htm(item)
+                text += "</p></li>" + "\n"
+            text += "</ul>" + "\n"
+            continue
+        logg.warning("unknown para <%s>", para.tag)
     return text
 
-def cleanpara(para):
+def para2man(para):
    item = unescape(ET.tostring(para))
    item = item.replace("\n", " ")
    item = item.replace("  ", " ")
@@ -207,16 +303,39 @@ def cleanpara(para):
    item = item.replace("</literal>", "\\fP")
    return item
 
+def para2htm(para):
+   item = unescape(ET.tostring(para))
+   item = item.replace("\n", " ")
+   item = item.replace("  ", " ")
+   item = item.replace("  ", " ")
+   item = item.replace("  ", " ")
+   item = item.replace("  ", " ")
+   item = item.replace("<listitem>", "")
+   item = item.replace("</listitem>", "")
+   item = item.replace("<para>", "")
+   item = item.replace("</para>", "")
+   item = item.replace("<function>", "<em><code>")
+   item = item.replace("</function>", "</code></em>")
+   item = item.replace("<literal>", "<code>")
+   item = item.replace("</literal>", "</code>")
+   return item
+
 def styleinfo2(man):
-   styles = []
-   styles += [ ".ie \\n(.g .ds Aq \\(aq" ]
-   styles += [ ".el        .ds Aq " ] # http://bugs.debian.org/507673
-   styles += [ ".nh" ] # disable hyphenation
-   styles += [ ".ad l" ] # align left, no justification
-   return "".join([ "%s\n" % part for part in styles ])
+    if man:
+        styles = []
+        styles += [ ".ie \\n(.g .ds Aq \\(aq" ]
+        styles += [ ".el        .ds Aq " ] # http://bugs.debian.org/507673
+        styles += [ ".nh" ] # disable hyphenation
+        styles += [ ".ad l" ] # align left, no justification
+        return "".join([ "%s\n" % part for part in styles ])
+    else:
+        return ""
 
 def refends2(man):
-    return ""
+    if man:
+        return ""
+    else:
+        return "</body></html>" + "\n"
 
 def refentry2(man, refentry, subdirectory = ".", title = ""):
     if refentry.tag != "refentry":
@@ -228,7 +347,7 @@ def refentry2(man, refentry, subdirectory = ".", title = ""):
     text += refentrytitle2(man, refentry, title)
     text += refsynopsisdiv2(man, refentry)
     text += refsections2(man, refentry)
-    text += refends2(man, refentry, title)
+    text += refends2(man)
 
     ### write the files
     refentrytitle = ""
@@ -251,22 +370,27 @@ def refentry2(man, refentry, subdirectory = ".", title = ""):
         found = section.find("refpurpose")
         if found is not None: refpurpose = found.text
     #
-    written = 0
-    for manpage in manpages:
-        if not refentrytitle:
-            refentrytitle = manpage
-        filename = "%s/man%s/%s.%s" % (subdirectory, manvolnum, manpage, manvolnum)
-        if manpage != refentrytitle:
-            manpagetext = ".so %s.%s\n" % (refentrytitle, manvolnum)
-            writefile(filename, manpagetext)
-        else:
-            manpagetext = text
+    if man:
+        written = 0
+        for manpage in manpages:
+            if not refentrytitle:
+                refentrytitle = manpage
+            filename = "%s/man%s/%s.%s" % (subdirectory, manvolnum, manpage, manvolnum)
+            if manpage != refentrytitle:
+                manpagetext = ".so %s.%s\n" % (refentrytitle, manvolnum)
+                writefile(filename, manpagetext)
+            else:
+                manpagetext = text
+                writefile(filename, manpagetext)
+                written += 1
+        if not written:
+            manpage = refentrytitle
+            filename = "%s/man%s/%s.%s" % (subdirectory, manvolnum, manpage, manvolnum)
             writefile(filename, manpagetext)
-            written += 1
-    if not written:
+    else:
         manpage = refentrytitle
-        filename = "%s/man%s/%s.%s" % (subdirectory, manvolnum, manpage, manvolnum)
-        writefile(filename, manpagetext)
+        filename = "%s/%s.%s.%s" % (subdirectory, manpage, manvolnum, "html")
+        writefile(filename, text)
     #
     overview = {}
     for manpage in manpages:
@@ -304,4 +428,4 @@ if __name__ == "__main__":
     if args and args[0] in ("man", "html"):
        make = args[0]
        args = args[1:]
-    dbk2(make, args, opt.into)
+    dbk2(make == 'man', args, opt.into)
diff --git a/docs/dir2index.py b/docs/dir2index.py
new file mode 100755 (executable)
index 0000000..4bce424
--- /dev/null
@@ -0,0 +1,74 @@
+#! /usr/bin/python>
+from __future__ import print_function
+
+""" Searches through a directory and creates an index page for it
+"""
+
+__author__ = "Guido U. Draheim"
+
+import logging
+import os.path
+import re
+import xml.etree.ElementTree as ET
+
+logg = logging.getLogger("dir2index")
+
+def esc(text):
+    text = text.replace(".", "\\&.")
+    text = text.replace("-", "\\-")
+    return text
+def unescape(text):
+    text = text.replace('&lt;', '<')
+    text = text.replace('&gt;', '>')
+    text = text.replace('&quot;', '"')
+    text = text.replace('&amp;', '&')
+    return text
+def htm(text):
+    text = text.replace('&', '&amp;')
+    text = text.replace('<', '&lt;')
+    text = text.replace('>', '&gt;')
+    text = text.replace('"', '&quot;')
+    return text
+
+def parse_html(filename):
+    tree = ET.parse(filename)
+    return tree.getroot()
+
+def dir2(man, dirs, into):
+    text = "<html><body>" + "\n"
+    for dirname in dirs:
+        text += "<ul>"
+        for filename in os.listdir(dirname):
+            name = filename
+            if name.endswith(".html"): name = name[:-5]
+            if name.endswith(".htm"): name = name[:-4]
+            if name.endswith(".3"): name = name[:-2]
+            text += '<li><a href="%s">%s</a></li>' % (filename, name)
+            text += "\n"
+        text += "</ul>"
+    text += "</body></html>" + "\n"
+    writefile("%s/index.html" % into, text)
+
+def writefile(filename, manpagetext):
+    dirname = os.path.dirname(filename)
+    if not os.path.isdir(dirname):
+        logg.debug("mkdir %s", dirname)
+        os.makedirs(dirname)
+    with open(filename, "w") as f:
+        f.write(manpagetext)
+    logg.debug("written %s [%s]", filename, manpagetext.split("\n", 1)[0])
+
+if __name__ == "__main__":
+    from optparse import OptionParser
+    _o = OptionParser("%prog [options] directories...")
+    _o.add_option("-o","--into", metavar="DIR", default=".",
+        help="specify base directory for output [%default]")
+    _o.add_option("-t","--make", metavar="DIR", default="man",
+        help="make 'man'/'html' output pages [%default]")
+    _o.add_option("-v","--verbose", action="count", default=0,
+        help="increase logging level [%default]")
+    opt, args = _o.parse_args()
+    logging.basicConfig(level = max(0, logging.WARNING - 10 * opt.verbose))
+    # ensure commandline is compatible with "xmlto -o DIR TYPE INPUTFILE"
+    make = opt.make
+    dir2(make == 'man', args, opt.into)