diff options
author | Timo Richter <timo@iera.de> | 2011-08-26 14:03:25 +0200 |
---|---|---|
committer | Jan Holesovsky <kendy@suse.cz> | 2011-08-26 14:03:56 +0200 |
commit | ba84d4ed501e1ae10683c2edf72ef2d3944e1333 (patch) | |
tree | da20dfa3d59c961dd432e462fb8f5d58a78bb955 /helpcontent2/wiki-to-help | |
parent | 96210e715d167f793ce8830b4152f3327c265552 (diff) |
Index is being created. Images are included in chm-files.
--images accepts zip files
Program output is more quiet
Added -v for verbosity
Call of "convert.py" -h is a lot faster
Diffstat (limited to 'helpcontent2/wiki-to-help')
-rw-r--r-- | helpcontent2/wiki-to-help/README | 6 | ||||
-rwxr-xr-x | helpcontent2/wiki-to-help/convert.py | 73 | ||||
-rw-r--r-- | helpcontent2/wiki-to-help/executor.py | 21 | ||||
-rw-r--r-- | helpcontent2/wiki-to-help/hhc.py | 28 | ||||
-rw-r--r-- | helpcontent2/wiki-to-help/mw.py | 20 | ||||
-rw-r--r-- | helpcontent2/wiki-to-help/mwlib_mods/__init__.py | 4 | ||||
-rw-r--r-- | helpcontent2/wiki-to-help/mwlib_mods/indexterm_from_title.py | 24 |
7 files changed, 142 insertions, 34 deletions
diff --git a/helpcontent2/wiki-to-help/README b/helpcontent2/wiki-to-help/README index f384debb20..151be5feae 100644 --- a/helpcontent2/wiki-to-help/README +++ b/helpcontent2/wiki-to-help/README @@ -9,6 +9,12 @@ The following programs are required: - python - python-lxml - xsltproc + - unzip + +HHC-Installer depends on: + - wine + - cabextract + - wget 1.1 On GNU and UNIX diff --git a/helpcontent2/wiki-to-help/convert.py b/helpcontent2/wiki-to-help/convert.py index dd0c0a597a..0e6cf0b694 100755 --- a/helpcontent2/wiki-to-help/convert.py +++ b/helpcontent2/wiki-to-help/convert.py @@ -15,11 +15,12 @@ Microsoft HHC: http://go.microsoft.com/fwlink/?LinkId=14188 import subprocess, tempfile, os, shutil, argparse -import mwlib_mods +#import mwlib_mods # is being imported. see below from hhc import HHC from mw import MW from metabook_translated import MetabookTranslated from metabook_translated import LanguageSeparator +from executor import Executor scriptpath=os.path.dirname(os.path.realpath(__file__) ) @@ -28,10 +29,11 @@ class Main(object): def parseArgs(self): parser = argparse.ArgumentParser(description='Conversion from a mediawiki xml-dumpfile to helpfiles') parser.add_argument("--startpage", metavar="PATH", dest="startpage", default=None, type=str, help="Sets a HTML-file as the start page") - parser.add_argument("--images", metavar="PATH", dest="imgPath", default=None, type=str, help="Uses images from PATH") + parser.add_argument("--images", metavar="PATH", dest="imgPath", default=None, type=str, help="Uses images from PATH. PATH is a zipfile or a directory.") parser.add_argument("--keep", dest="keepTmp", default=False, action='store_true', help="Keeps temporary files in /tmp") parser.add_argument("--only-en", dest="onlyEn", action='store_true', default=False, help="Converts only English articles") parser.add_argument("--no-chm", dest="createChm", default=True, action='store_false', help="Avoids creation of a CHM file at the end") + parser.add_argument("-v", dest="verbose", default=False, action='store_true', help="Verbose") parser.add_argument("input", type=str, help="XML input") parser.add_argument("output", type=str, help="Directory for output") @@ -39,6 +41,7 @@ class Main(object): def __init__(self): args = self.parseArgs() + import mwlib_mods r = Converter( keepTmp=args.keepTmp, createChm=args.createChm, @@ -47,11 +50,13 @@ class Main(object): startpage=args.startpage, onlyEn=args.onlyEn, imgPath=args.imgPath, + verbose=args.verbose, )() exit(int(not r)) class Converter(object): + verbose=False createChm = None # keepTmp = None # #style=os.path.join(scriptpath,'xsl/htmlhelp/htmlhelp.xsl') # final @@ -59,18 +64,9 @@ class Converter(object): title="LibreOffice" # final tmp=None + includeFiles=[] - def ex(self,*cmd): - """ - Execute a program - @cmd Command, args - @return boolean True if succeed - """ - cmd = [elem for elem in cmd] - print cmd - return (subprocess.Popen(cmd).wait() == 0) - - def __init__(self,source,dest,onlyEn,imgPath, + def __init__(self,source,dest,onlyEn,imgPath,verbose, keepTmp=False,createChm=True,startpage=None): """ Parameters are documented in Main.parseArgs() @@ -79,7 +75,6 @@ class Converter(object): self.keepTmp=keepTmp self.tmp = tempfile.mkdtemp() self.style = os.path.abspath(self.style) - self.hhc = HHC() source = os.path.abspath(source) dest = os.path.abspath(dest) if startpage is not None: @@ -88,11 +83,10 @@ class Converter(object): self.dest=dest self.startpage=startpage self.onlyEn = onlyEn - if imgPath: - self.imgPath = os.path.join(imgPath,"IMAGENAME") - else: - self.imgPath = "IMAGENAME" - + self.imgPath = imgPath + self.verbose = verbose + self.ex = Executor(showErr=verbose,showOutput=True,showCmd=verbose) + self.hhc = HHC(showErr=True,showOutput=verbose,showCmd=verbose) def createDir(self,path): try: @@ -100,6 +94,39 @@ class Converter(object): except OSError: pass + def setupImgPath(self): + """ + If --images is not given, the path will be in the format "name.jpg". + If --images is given a zipfile, it is being extracted to "images/". + If --images is a directory, it is being copied to "images/". + The filenames in images/ are being stored to self.includeFiles. + """ + imgDest = "images" # puts images to output/imgDest/ + if not self.imgPath: + self.imgPath = "IMAGENAME" + return + extension = os.path.splitext(self.imgPath)[1].lower() + imgTmp = os.path.join(self.tmp,"images") + print "Moving images..." + if extension == ".zip": + self.ex("unzip","-q","-o","-j","-d",imgTmp,self.imgPath) + else: + shutil.copytree(self.imgPath,imgTmp) + self.imgPath = os.path.join(imgDest,"IMAGENAME") + # Save filenames for inclusion in chm + for fname in os.listdir(imgTmp): + fpath = os.path.join(imgDest,fname) + self.includeFiles.append(fpath) + + def writeHhp(self): + """ + Writes changes to the .hhp-file. + self.includeFiles will be flushed to the hhp. + """ + hhp=os.path.join(self.tmp,"htmlhelp.hhp") + with open(hhp,"a") as f: + f.write("\n".join(self.includeFiles)) + def __call__(self): """ Create the environment for conversion and call convert() @@ -108,6 +135,8 @@ class Converter(object): tmp = self.tmp self.createDir(self.dest) + self.setupImgPath() + shutil.copy(os.path.join(scriptpath,"nfo.json"),tmp) metabook_template = os.path.join(scriptpath,"metabook.json") ls = LanguageSeparator.fromFileToFiles(metabook_template,self.source,tmp) @@ -127,16 +156,20 @@ class Converter(object): @lang Language of book @metabook Path to metabook-json-file """ + print "Rendering language "+lang tmp = self.tmp docbookfile = os.path.join(tmp,"docbook_%s.xml"%lang) chmDest = os.path.join(self.dest,lang+".chm") - MW.render("-L",lang,"-W","imagesrcresolver=%s"%self.imgPath, + renderArgs = ("-L",lang,"-W","imagesrcresolver=%s"%self.imgPath, "--config=%s/wikiconf.txt"%(tmp), "-w","docbook","-o",docbookfile,"-m",metabook,"--title",self.title) + MW.quietCall(MW.render,renderArgs,showErr=self.verbose) shutil.copy(docbookfile,self.dest) + print "Parsing docbook" if not self.ex("/usr/bin/xsltproc","--nonet","--novalid","-o",tmp+'/',self.style,docbookfile): return False self.setStartpage(self.startpage) + self.writeHhp() if self.createChm: print("Compiling chm...") self.hhc(tmp) diff --git a/helpcontent2/wiki-to-help/executor.py b/helpcontent2/wiki-to-help/executor.py new file mode 100644 index 0000000000..464ec222e4 --- /dev/null +++ b/helpcontent2/wiki-to-help/executor.py @@ -0,0 +1,21 @@ +import subprocess, os + +class Executor(object): + def __init__(self,showErr=True,showOutput=True,showCmd=False): + self.showCmd=showCmd + if showErr: self.stderr = None + else: self.stderr=open(os.devnull,"w") + if showOutput: self.stdout = None + else: self.stdout=open(os.devnull,"w") + + def __call__(self,*cmd): + """ + Execute a program, e.g. Executor()("/bin/ls","/home") + @cmd Command, args + @return boolean True if succeed + """ + if self.showCmd: + print cmd + return (subprocess.Popen(list(cmd),stderr=self.stderr, + stdout=self.stdout).wait() == 0) + diff --git a/helpcontent2/wiki-to-help/hhc.py b/helpcontent2/wiki-to-help/hhc.py index d2d8302604..dc7a54daaa 100644 --- a/helpcontent2/wiki-to-help/hhc.py +++ b/helpcontent2/wiki-to-help/hhc.py @@ -1,22 +1,25 @@ -import platform, os, subprocess +import platform, os +from executor import Executor class HHC(object): """ Class for execution of Html Help Compiler """ hhcexe="c:\\htmlhelp\\hhc.exe" - def __init__(self): - pass + def __init__(self,**args): + """ + @args Arguments for Executor.__init__() + """ + self.args=args def exWindows(self,source): """ Private. Compile @source calling HHC natively under Windows """ cmd=[self.hhcexe,os.path.join(source,"htmlhelp.hhp")] - r = (subprocess.Popen(cmd).wait()) - return r + return Executor(**self.args).executor(*tuple(cmd)) def exWine(self,source): """ Private. Compile @source calling HHC via Wine """ #dirname = os.path.dirname(source) - wine = Wine(source,"j:") + wine = Wine(source,"j:",self.args) r = wine(self.hhcexe,"j:\\htmlhelp.hhp") del wine return r @@ -34,10 +37,13 @@ class HHC(object): class Wine(object): # TODO: this should be a singleton - def __init__(self,workingDir,driveletter): - """ Setup the wine environment. Granting access so that wine is able to output files to @workingDir. + def __init__(self,workingDir,driveletter,args={}): + """ + Setup the wine environment. Granting access so that wine is able @workingDir will be accessable via @driveletter - E.g. Wine("/tmp/dir","j:") """ + @args Arguments for Executor as dict (**args) + E.g. Wine("/tmp/dir","j:") + """ homedir = os.path.expanduser('~') wineprefix=os.path.join(homedir,".wine") drive=os.path.join(wineprefix,"dosdevices",driveletter) @@ -47,13 +53,13 @@ class Wine(object): os.symlink(workingDir,drive) self.drive = drive #self.driveBak = driveBak + self.executor = Executor(**args) def ex(self,*cmd): """ execute something with wine """ cmd = [elem for elem in cmd] cmd = ["/usr/bin/wine"]+cmd - r= (subprocess.Popen(cmd).wait()) - return r + return self.executor(*tuple(cmd)) def __call__(self,*cmd): return self.ex(*cmd) diff --git a/helpcontent2/wiki-to-help/mw.py b/helpcontent2/wiki-to-help/mw.py index ca56633dae..f19ca15be8 100644 --- a/helpcontent2/wiki-to-help/mw.py +++ b/helpcontent2/wiki-to-help/mw.py @@ -1,6 +1,6 @@ #import mwlib.cdbwiki, mwlib.apps.render, mwlib.apps import mwlib.apps -import sys +import sys, os class MW(object): """ @@ -9,6 +9,24 @@ class MW(object): """ @staticmethod + def quietCall(function,args=(),showErr=True,showOutput=True): + """ + Calls a python function and redirects parts to /dev/null. + This is platform independent. + """ + saveout = sys.stdout + saveerr = sys.stderr + + if not showErr: sys.stderr=nullerr=open(os.devnull,"w") + if not showOutput: sys.stdout=nullout=open(os.devnull,"w") + function(*args) + if not showErr: nullerr.close() + if not showOutput: nullout.close() + + sys.stdout=saveout + sys.stderr=saveerr + + @staticmethod def _setArgs(function,args): """ Set sys.argv for @function """ bak = sys.argv diff --git a/helpcontent2/wiki-to-help/mwlib_mods/__init__.py b/helpcontent2/wiki-to-help/mwlib_mods/__init__.py index c9c59e96f9..ca93600d47 100644 --- a/helpcontent2/wiki-to-help/mwlib_mods/__init__.py +++ b/helpcontent2/wiki-to-help/mwlib_mods/__init__.py @@ -17,6 +17,6 @@ docbook_internLinks.apply() import custom_nfo custom_nfo.apply() -#import images_from_path -#images_from_path.apply() +import indexterm_from_title +indexterm_from_title.apply() diff --git a/helpcontent2/wiki-to-help/mwlib_mods/indexterm_from_title.py b/helpcontent2/wiki-to-help/mwlib_mods/indexterm_from_title.py new file mode 100644 index 0000000000..53d3cfdefa --- /dev/null +++ b/helpcontent2/wiki-to-help/mwlib_mods/indexterm_from_title.py @@ -0,0 +1,24 @@ +""" +Adds +<indexterm><primary>TITLE</primary></indexterm> +to each <article> +""" + +## Set up docbookwriter +import mwlib.docbookwriter +#import lxml.etree +SubElement = mwlib.docbookwriter.SubElement +class MyDocBookWriter(mwlib.docbookwriter.DocBookWriter): + def dbwriteArticle(self, a): + """ + Add <indexterm><primary>a.caption</primary></indexterm> + """ + e = super(MyDocBookWriter,self).dbwriteArticle(a) + i = SubElement(e,"indexterm") + p = SubElement(i,"primary") + p.text = a.caption + return e + +def apply(): + mwlib.docbookwriter.DocBookWriter = MyDocBookWriter + |