hgbook
changeset 622:2180358c32c4
Move some files to contrib
author | Dongsheng Song <dongsheng.song@gmail.com> |
---|---|
date | Thu Mar 12 15:40:40 2009 +0800 (2009-03-12) |
parents | 1ef7708b3b7f |
children | 082bb76417f1 |
files | contrib/hg-interdiff contrib/hg-replay contrib/latex-to-docbook contrib/sillybench.py examples/hg-interdiff examples/hg-replay sillybench/sillybench.py tools/latex-to-docbook |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/contrib/hg-interdiff Thu Mar 12 15:40:40 2009 +0800 1.3 @@ -0,0 +1,45 @@ 1.4 +#!/usr/bin/env python 1.5 +# 1.6 +# Adapter for using interdiff with mercurial's extdiff extension. 1.7 +# 1.8 +# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com> 1.9 +# 1.10 +# This software may be used and distributed according to the terms of 1.11 +# the GNU General Public License, incorporated herein by reference. 1.12 + 1.13 +import os, sys 1.14 + 1.15 +def walk(base): 1.16 + # yield all non-directories below the base path. 1.17 + for root, dirs, files in os.walk(base): 1.18 + for f in files: 1.19 + path = os.path.join(root, f) 1.20 + yield path[len(base)+1:], path 1.21 + else: 1.22 + if os.path.isfile(base): 1.23 + yield '', base 1.24 + 1.25 +# create list of unique file names under both directories. 1.26 +files = dict(walk(sys.argv[1])) 1.27 +files.update(walk(sys.argv[2])) 1.28 +files = files.keys() 1.29 +files.sort() 1.30 + 1.31 +def name(base, f): 1.32 + if f: 1.33 + path = os.path.join(base, f) 1.34 + else: 1.35 + path = base 1.36 + # interdiff requires two files; use /dev/null if one is missing. 1.37 + if os.path.exists(path): 1.38 + return path 1.39 + return '/dev/null' 1.40 + 1.41 +ret = 0 1.42 + 1.43 +for f in files: 1.44 + if os.system('interdiff "%s" "%s"' % (name(sys.argv[1], f), 1.45 + name(sys.argv[2], f))): 1.46 + ret = 1 1.47 + 1.48 +sys.exit(ret)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/contrib/hg-replay Thu Mar 12 15:40:40 2009 +0800 2.3 @@ -0,0 +1,107 @@ 2.4 +#!/usr/bin/env python 2.5 +# 2.6 +# Adapter for using interdiff with mercurial's extdiff extension. 2.7 +# 2.8 +# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com> 2.9 +# 2.10 +# This software may be used and distributed according to the terms of 2.11 +# the GNU General Public License, incorporated herein by reference. 2.12 + 2.13 +import os 2.14 +import shutil 2.15 +import sys 2.16 +import tempfile 2.17 + 2.18 +if len(sys.argv) < 4: 2.19 + print >> sys.stderr, ('usage: %s srcrepo destrepo cset-to-omit [...]' % 2.20 + os.path.basename(sys.argv[0])) 2.21 + sys.exit(1) 2.22 + 2.23 +srcrepo, destrepo = sys.argv[1], sys.argv[2] 2.24 +omit = sys.argv[3:] 2.25 + 2.26 +changemap = {} 2.27 +revs = [] 2.28 + 2.29 +parent = None 2.30 + 2.31 +sys.stdout.write('gathering history...') 2.32 +sys.stdout.flush() 2.33 + 2.34 +for line in os.popen("hg --cwd %r log -r0:tip --template '{rev}:{node} {parents}\n'" % srcrepo): 2.35 + changes = line.split() 2.36 + cset = changes[0].split(':')[1] 2.37 + rev = len(revs) 2.38 + changemap[cset] = rev 2.39 + if len(changes) >= 2: 2.40 + p1 = int(changes[1].split(':', 1)[0]) 2.41 + if len(changes) == 3: 2.42 + p2 = int(changes[2].split(':', 1)[0]) 2.43 + else: 2.44 + p2 = None 2.45 + if len(changes) == 1: 2.46 + p1 = parent 2.47 + revs.append((cset, p1, p2)) 2.48 + parent = rev 2.49 + 2.50 +sys.stdout.write(' %d revs\n' % len(revs)) 2.51 + 2.52 +def findrev(r): 2.53 + try: 2.54 + i = int(r) 2.55 + if str(i) == r: 2.56 + rev = i 2.57 + if rev < 0: 2.58 + rev += len(revs) 2.59 + if rev < 0 or rev > len(revs): 2.60 + print >> sys.stderr, 'bad changeset: %r' % r 2.61 + sys.exit(1) 2.62 + cset = revs[rev][0] 2.63 + except ValueError: 2.64 + cset = r 2.65 + matches = [changemap[c] for c in changemap if c.startswith(cset)] 2.66 + if len(matches) != 1: 2.67 + print >> sys.stderr, 'bad changeset: %r' % r 2.68 + sys.exit(1) 2.69 + rev = matches[0] 2.70 + return rev 2.71 + 2.72 +def run(cmd): 2.73 + print cmd 2.74 + ret = os.system(cmd) 2.75 + if ret: 2.76 + print >> sys.stderr, 'failure:', cmd 2.77 + sys.exit(1) 2.78 + 2.79 +omit = map(findrev, omit) 2.80 +omit.sort() 2.81 +newrevs = revs[:omit[0]] 2.82 +tip = len(newrevs) - 1 2.83 +run('hg clone -q -r%s %r %r' % (tip, srcrepo, destrepo)) 2.84 + 2.85 +os.environ['HGMERGE'] = 'true' 2.86 + 2.87 +patchdir = tempfile.mkdtemp(prefix='replay.') 2.88 +try: 2.89 + run('hg --cwd %r export --git -o %r%s%%R %d:tip' % 2.90 + (srcrepo, patchdir, os.sep, omit[0]+1)) 2.91 + for rev in xrange(omit[0], len(revs)): 2.92 + if rev in omit: 2.93 + print 'omit', rev 2.94 + newrevs.append((None, revs[rev][1], None)) 2.95 + continue 2.96 + _, p1, p2 = revs[rev] 2.97 + np1 = newrevs[p1][1] 2.98 + if tip != np1: 2.99 + run('hg --cwd %r update -q -C %s' % (destrepo, np1)) 2.100 + np2 = None 2.101 + if p2: 2.102 + np2 = newrevs[p2][1] 2.103 + run('hg --cwd %r merge -q %s' % (destrepo, np2)) 2.104 + print >> sys.stderr, 'XXX - cannot handle merges properly yet' 2.105 + run('hg --cwd %r import -q -f %r%s%d' % (destrepo, patchdir, os.sep, rev)) 2.106 + tip = len(newrevs) - 1 2.107 + newrevs.append((None, tip, np2)) 2.108 +finally: 2.109 + print 'cleaning up ...' 2.110 + #shutil.rmtree(patchdir)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/contrib/latex-to-docbook Thu Mar 12 15:40:40 2009 +0800 3.3 @@ -0,0 +1,198 @@ 3.4 +#!/usr/bin/python 3.5 +# 3.6 +# This is the most horrible of hacks. Pretend you're not looking.</para> 3.7 + 3.8 +import cStringIO as StringIO 3.9 +import re, sys 3.10 + 3.11 +sections = { 3.12 + 'chapter': 'chapter', 3.13 + 'section': 'sect1', 3.14 + 'subsection': 'sect2', 3.15 + 'subsubsection': 'sect3', 3.16 + } 3.17 + 3.18 +envs = { 3.19 + 'codesample2': 'programlisting', 3.20 + 'codesample4': 'programlisting', 3.21 + 'enumerate': 'orderedlist', 3.22 + 'figure': 'informalfigure', 3.23 + 'itemize': 'itemizedlist', 3.24 + 'note': 'note', 3.25 + 'quote': 'blockquote', 3.26 + } 3.27 + 3.28 +def process(ifp, ofp): 3.29 + print >> ofp, '<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->\n' 3.30 + stack = [] 3.31 + para = True 3.32 + inlist = 0 3.33 + for line in ifp: 3.34 + if line.startswith('%%% Local Variables:'): 3.35 + break 3.36 + line = (line.rstrip() 3.37 + .replace('~', ' ') 3.38 + .replace('&', '&') 3.39 + .replace('---', '&emdash;') 3.40 + .replace('\_', '_') 3.41 + .replace('\{', '{') 3.42 + .replace('\}', '}') 3.43 + .replace('\$', '$') 3.44 + .replace('\%', '%') 3.45 + .replace('\#', '#') 3.46 + .replace('<', '<') 3.47 + .replace('>', '>') 3.48 + .replace('``', '<quote>') 3.49 + .replace("''", '</quote>') 3.50 + .replace('\\', '\\')) 3.51 + line = re.sub(r'\s*\\(?:centering|small)\b\s*', '', line) 3.52 + line = re.sub(r'\\(?:hgrc\\|hgrc)\b', 3.53 + r'<filename role="special"> /.hgrc</filename>', line) 3.54 + line = re.sub(r'\\item\[(?P<key>[^]]+)\]', r'\item \g<key>:', line) 3.55 + line = re.sub(r'\\bug{(?P<id>\d+)}', 3.56 + r'<ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue\g<id>">issue \g<id></ulink>', line) 3.57 + line = re.sub(r'\\cite{([^}]+)}', r'<citation>\1</citation>', line) 3.58 + line = re.sub(r'\\hggopt{(?P<opt>[^}]+)}', 3.59 + r'<option role="hg-opt-global">\g<opt></option>', line) 3.60 + line = re.sub(r'\\hgxopt{(?P<ext>[^}]+)}{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}', 3.61 + r'<option role="hg-ext-\g<ext>-cmd-\g<cmd>-opt">\g<opt></option>', line) 3.62 + line = re.sub(r'\\hgxcmd{(?P<ext>[^}]+)}{(?P<cmd>[^}]+)}', 3.63 + r'<command role="hg-ext-\g<ext>">\g<cmd></command>', line) 3.64 + line = re.sub(r'\\hgext{(?P<ext>[^}]+)}', 3.65 + r'<literal role="hg-ext">\g<ext></literal>', line) 3.66 + line = re.sub(r'\\hgopt{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}', 3.67 + r'<option role="hg-opt-\g<cmd>">\g<opt></option>', 3.68 + line) 3.69 + line = re.sub(r'\\cmdopt{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}', 3.70 + r'<option role="cmd-opt-\g<cmd>">\g<opt></option>', 3.71 + line) 3.72 + line = re.sub(r'\\hgcmd{(?P<cmd>[^}]+)}', 3.73 + r'<command role="hg-cmd">hg \g<cmd></command>', line) 3.74 + line = re.sub(r'\\caption{(?P<text>[^}]+?)}', 3.75 + r'<caption><para>\g<text></para></caption>', line) 3.76 + line = re.sub(r'\\grafix{(?P<name>[^}]+)}', 3.77 + r'<mediaobject><imageobject><imagedata fileref="\g<name>"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>', line) 3.78 + line = re.sub(r'\\envar{(?P<name>[^}]+)}', 3.79 + r'<envar>\g<name></envar>', line) 3.80 + line = re.sub(r'\\rcsection{(?P<sect>[^}]+)}', 3.81 + r'<literal role="rc-\g<sect>">\g<sect></literal>', line) 3.82 + line = re.sub(r'\\rcitem{(?P<sect>[^}]+)}{(?P<name>[^}]+)}', 3.83 + r'<envar role="rc-item-\g<sect>">\g<name></envar>', line) 3.84 + line = re.sub(r'\\dirname{(?P<dir>[^}]+?)}', 3.85 + r'<filename class="directory">\g<dir></filename>', line) 3.86 + line = re.sub(r'\\filename{(?P<file>[^}]+?)}', 3.87 + r'<filename>\g<file></filename>', line) 3.88 + line = re.sub(r'\\tildefile{(?P<file>[^}]+)}', 3.89 + r'<filename role="home">~/\g<file></filename>', line) 3.90 + line = re.sub(r'\\sfilename{(?P<file>[^}]+)}', 3.91 + r'<filename role="special">\g<file></filename>', line) 3.92 + line = re.sub(r'\\sdirname{(?P<dir>[^}]+)}', 3.93 + r'<filename role="special" class="directory">\g<dir></filename>', line) 3.94 + line = re.sub(r'\\interaction{(?P<id>[^}]+)}', 3.95 + r'<!-- &interaction.\g<id>; -->', line) 3.96 + line = re.sub(r'\\excode{(?P<id>[^}]+)}', 3.97 + r'<!-- &example.\g<id>; -->', line) 3.98 + line = re.sub(r'\\pymod{(?P<mod>[^}]+)}', 3.99 + r'<literal role="py-mod">\g<mod></literal>', line) 3.100 + line = re.sub(r'\\pymodclass{(?P<mod>[^}]+)}{(?P<class>[^}]+)}', 3.101 + r'<literal role="py-mod-\g<mod>">\g<class></literal>', line) 3.102 + line = re.sub(r'\\url{(?P<url>[^}]+)}', 3.103 + r'<ulink url="\g<url>">\g<url></ulink>', line) 3.104 + line = re.sub(r'\\href{(?P<url>[^}]+)}{(?P<text>[^}]+)}', 3.105 + r'<ulink url="\g<url>">\g<text></ulink>', line) 3.106 + line = re.sub(r'\\command{(?P<cmd>[^}]+)}', 3.107 + r'<command>\g<cmd></command>', line) 3.108 + line = re.sub(r'\\option{(?P<opt>[^}]+)}', 3.109 + r'<option>\g<opt></option>', line) 3.110 + line = re.sub(r'\\ref{(?P<id>[^}]+)}', r'<xref linkend="\g<id>"/>', line) 3.111 + line = re.sub(r'\\emph{(?P<txt>[^}]+)}', 3.112 + r'<emphasis>\g<txt></emphasis>', line) 3.113 + line = re.sub(r'\\texttt{(?P<txt>[^}]+)}', 3.114 + r'<literal>\g<txt></literal>', line) 3.115 + line = re.sub(r'\\textbf{(?P<txt>[^}]+)}', 3.116 + r'<emphasis role="bold">\g<txt></emphasis>', line) 3.117 + line = re.sub(r'\\hook{(?P<name>[^}]+)}', 3.118 + r'<literal role="hook">\g<name></literal>', line) 3.119 + line = re.sub(r'\\tplfilter{(?P<name>[^}]+)}', 3.120 + r'<literal role="template-filter">\g<name></literal>', line) 3.121 + line = re.sub(r'\\tplkword{(?P<name>[^}]+)}', 3.122 + r'<literal role="template-keyword">\g<name></literal>', line) 3.123 + line = re.sub(r'\\tplkwfilt{(?P<tpl>[^}]+)}{(?P<name>[^}]+)}', 3.124 + r'<literal role="template-kw-filt-\g<tpl>">\g<name></literal>', line) 3.125 + line = re.sub(r'\\[vV]erb(.)(?P<txt>[^\1]+?)\1', 3.126 + r'<literal>\g<txt></literal>', line) 3.127 + line = re.sub(r'\\package{(?P<name>[^}]+)}', 3.128 + r'<literal role="package">\g<name></literal>', line) 3.129 + line = re.sub(r'\\hgcmdargs{(?P<cmd>[^}]+)}{(?P<args>[^}]+)}', 3.130 + r'<command role="hg-cmd">hg \g<cmd> \g<args></command>', 3.131 + line) 3.132 + line = re.sub(r'\\cmdargs{(?P<cmd>[^}]+)}{(?P<args>[^}]+)}', 3.133 + r'<command>\g<cmd> \g<args></command>', 3.134 + line) 3.135 + m = re.match(r'\\(chapter|section|subsection|subsubsection){(.*)}', line) 3.136 + if m: 3.137 + kind, content = m.groups() 3.138 + sec = sections[kind] 3.139 + while stack and stack[-1] >= sec: 3.140 + close = stack.pop() 3.141 + print >> ofp, '</%s>' % close 3.142 + stack.append(sec) 3.143 + print >> ofp, '<%s>\n<title>%s</title>' % (sec, content) 3.144 + else: 3.145 + m = re.match(r'\s*\\(begin|end){(?P<sect>[^}]+)}', line) 3.146 + if m: 3.147 + if not para: 3.148 + print >> ofp, '</para>' 3.149 + if inlist: 3.150 + ofp.write('</listitem>') 3.151 + para = True 3.152 + state, env = m.groups() 3.153 + env = envs[env] 3.154 + if state == 'begin': 3.155 + ofp.write('<') 3.156 + if env in ('itemizedlist', 'orderedlist'): 3.157 + inlist = 1 3.158 + else: 3.159 + ofp.write('</') 3.160 + if env in ('itemizedlist', 'orderedlist'): 3.161 + inlist = 0 3.162 + print >> ofp, env + '>' 3.163 + else: 3.164 + if line.startswith('\\item '): 3.165 + if inlist > 1: 3.166 + print >> ofp, '</para>' 3.167 + print >> ofp, '</listitem>' 3.168 + else: 3.169 + inlist = 2 3.170 + para = True 3.171 + line = line[6:] 3.172 + if line and para: 3.173 + if inlist: 3.174 + ofp.write('<listitem>') 3.175 + ofp.write('<para>') 3.176 + para = False 3.177 + if not line and not para: 3.178 + print >> ofp, '</para>' 3.179 + if inlist: 3.180 + ofp.write('</listitem>') 3.181 + para = True 3.182 + print >> ofp, line 3.183 + while stack: 3.184 + print >> ofp, '</%s>' % stack.pop() 3.185 + ofp.write('\n'.join(['\n<!--', 3.186 + 'local variables: ', 3.187 + 'sgml-parent-document: ("00book.xml" "book" "chapter")', 3.188 + 'end:', 3.189 + '-->'])) 3.190 + 3.191 + 3.192 +if __name__ == '__main__': 3.193 + for name in sys.argv[1:]: 3.194 + if not name.endswith('.tex'): 3.195 + continue 3.196 + newname = name[:-3] + 'xml' 3.197 + ofp = StringIO.StringIO() 3.198 + process(open(name), ofp) 3.199 + s = ofp.getvalue() 3.200 + s = re.sub('\n+</para>', '</para>', s, re.M) 3.201 + open(newname, 'w').write(s)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/contrib/sillybench.py Thu Mar 12 15:40:40 2009 +0800 4.3 @@ -0,0 +1,177 @@ 4.4 +#!/usr/bin/python 4.5 +# 4.6 +# Silly benchmarking program, to give a vague idea of how fast a few 4.7 +# tools are on a handful of common operations. 4.8 +# 4.9 +# Use a fairly big and real source tarball to test with: Firefox 4.10 +# 2.0.0.3 (37622 files, 5374 directories, 343MB unpacked onto 4.11 +# 4KB-blocksize ext3). 4.12 + 4.13 +import csv 4.14 +import os 4.15 +import shutil 4.16 +import sys 4.17 +import tempfile 4.18 +import time 4.19 +import urllib2 4.20 + 4.21 +url = 'ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.3/source/firefox-2.0.0.3-source.tar.bz2' 4.22 + 4.23 +class CommandFailure(Exception): 4.24 + pass 4.25 + 4.26 +class rcs(object): 4.27 + def __init__(self): 4.28 + self.logfp = open(self.__class__.__name__ + '.csv', 'w') 4.29 + self.csv = csv.writer(self.logfp) 4.30 + 4.31 + def download(self): 4.32 + name = url[url.rfind('/')+1:] 4.33 + path = os.path.join(os.environ['HOME'], name) 4.34 + if not os.path.isfile(path): 4.35 + ofp = open(path + '.part', 'wb') 4.36 + try: 4.37 + ifp = urllib2.urlopen(url) 4.38 + nbytes = ifp.info()['content-length'] 4.39 + sys.stdout.write('%s: %s bytes ' % (name, nbytes)) 4.40 + sys.stdout.flush() 4.41 + while True: 4.42 + data = ifp.read(131072) 4.43 + if not data: break 4.44 + sys.stdout.write('.') 4.45 + sys.stdout.flush() 4.46 + ofp.write(data) 4.47 + del ofp 4.48 + os.rename(path + '.part', path) 4.49 + except: 4.50 + if os.path.exists(path + '.part'): 4.51 + os.unlink(path + '.part') 4.52 + if os.path.exists(path): 4.53 + os.unlink(path) 4.54 + raise 4.55 + return path 4.56 + 4.57 + def run(self, args, mustsucceed=True): 4.58 + ret = os.spawnvp(os.P_WAIT, args[0], args) 4.59 + if ret < 0: 4.60 + msg = 'killed by signal %d' % (-ret) 4.61 + if ret > 0: 4.62 + msg = 'exited with status %d' % (ret) 4.63 + if ret: 4.64 + if mustsucceed: 4.65 + raise CommandFailure('%s: %s' % (msg, ' '.join(args))) 4.66 + print >> sys.stderr, 'WARNING: %s: %s' % (msg, ' '.join(args)) 4.67 + 4.68 + def time(self, *args, **kwargs): 4.69 + start = time.time() 4.70 + self.run(*args, **kwargs) 4.71 + end = time.time() 4.72 + return end - start 4.73 + 4.74 + def logtime(self, name, elapsed, rest=[]): 4.75 + self.log('time:' + name, '%.3f' % elapsed, rest) 4.76 + 4.77 + def log(self, name, value, rest=[]): 4.78 + item = (name, value, repr(rest)) 4.79 + print ' '.join(item) 4.80 + self.csv.writerow(item) 4.81 + self.logfp.flush() 4.82 + 4.83 + def unpack(self): 4.84 + tarball = self.download() 4.85 + t = self.time(['tar', '-C', self.wdir, '-jxf', tarball]) 4.86 + self.logtime('internal:untar', t) 4.87 + for name in os.listdir(os.path.join(self.wdir, 'mozilla')): 4.88 + os.rename(os.path.join(self.wdir, 'mozilla', name), 4.89 + os.path.join(self.wdir, name)) 4.90 + 4.91 + def cleanup(self): 4.92 + pass 4.93 + 4.94 + def add(self, paths): 4.95 + pass 4.96 + 4.97 + def commit(self, msg, paths): 4.98 + pass 4.99 + 4.100 + def status(self, path): 4.101 + pass 4.102 + 4.103 + def remove(self, path): 4.104 + pass 4.105 + 4.106 + 4.107 +class subversion(rcs): 4.108 + def __init__(self, root): 4.109 + rcs.__init__(self) 4.110 + self.repo = os.path.join(root, 'repo') 4.111 + self.wdir = os.path.join(root, 'wc') 4.112 + create = self.time(['svnadmin', 'create', '--fs-type=fsfs', self.repo]) 4.113 + self.logtime('svn:create', create) 4.114 + co = self.time(['svn', 'co', 'file://' + self.repo, self.wdir]) 4.115 + self.logtime('svn:co', co) 4.116 + self.logtime('init', create + co) 4.117 + os.chdir(self.wdir) 4.118 + 4.119 + def dropmeta(self, names): 4.120 + return [n for n in names if os.path.basename(n) != '.svn'] 4.121 + 4.122 + def add(self, paths): 4.123 + t = self.time(['svn', 'add', '-q'] + paths) 4.124 + self.logtime('add %r' % paths, t) 4.125 + 4.126 + def commit(self, msg, paths=[]): 4.127 + if paths: 4.128 + t = self.time(['svn', 'ci', '-q', '-m', msg] + paths) 4.129 + else: 4.130 + t = self.time(['svn', 'ci', '-q', '-m', msg]) 4.131 + self.logtime('commit %r' % paths, t) 4.132 + 4.133 + 4.134 +class mercurial(rcs): 4.135 + def __init__(self, root): 4.136 + rcs.__init__(self) 4.137 + self.repo = os.path.join(root, 'repo') 4.138 + self.wdir = self.repo 4.139 + init = self.time(['hg', 'init', self.repo]) 4.140 + self.logtime('init', init) 4.141 + os.chdir(self.wdir) 4.142 + 4.143 + def dropmeta(self, names): 4.144 + return [n for n in names if os.path.basename(n) != '.hg'] 4.145 + 4.146 + def add(self, paths): 4.147 + t = self.time(['hg', 'add', '-q'] + paths) 4.148 + self.logtime('add %r' % paths, t) 4.149 + 4.150 + def commit(self, msg, paths=[]): 4.151 + if paths: 4.152 + t = self.time(['hg', 'ci', '-q', '-m', msg] + paths) 4.153 + else: 4.154 + t = self.time(['hg', 'ci', '-q', '-m', msg]) 4.155 + self.logtime('commit %r' % paths, t) 4.156 + 4.157 +def benchmark(cls): 4.158 + oldcwd = os.getcwd() 4.159 + root = tempfile.mkdtemp(prefix='sillybench.') 4.160 + try: 4.161 + print 'root', root 4.162 + inst = cls(root) 4.163 + inst.unpack() 4.164 + names = inst.dropmeta(os.listdir('.')) 4.165 + dirs = [n for n in names if os.path.isdir(n)] 4.166 + nondirs = [n for n in names if not os.path.isdir(n)] 4.167 + dirs.sort(key=hash) 4.168 + names.sort(key=hash) 4.169 + for d in dirs[:len(dirs)/2]: 4.170 + inst.add([d]) 4.171 + inst.commit('Add %r' % d, [d]) 4.172 + inst.add(dirs[len(dirs)/2:] + names) 4.173 + inst.commit('Add remaining dirs and files') 4.174 + finally: 4.175 + print >> sys.stderr, '[cleaning up...]' 4.176 + shutil.rmtree(root) 4.177 + os.chdir(oldcwd) 4.178 + 4.179 +benchmark(mercurial) 4.180 +#benchmark(subversion)
5.1 --- a/examples/hg-interdiff Thu Mar 12 15:35:19 2009 +0800 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,45 +0,0 @@ 5.4 -#!/usr/bin/env python 5.5 -# 5.6 -# Adapter for using interdiff with mercurial's extdiff extension. 5.7 -# 5.8 -# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com> 5.9 -# 5.10 -# This software may be used and distributed according to the terms of 5.11 -# the GNU General Public License, incorporated herein by reference. 5.12 - 5.13 -import os, sys 5.14 - 5.15 -def walk(base): 5.16 - # yield all non-directories below the base path. 5.17 - for root, dirs, files in os.walk(base): 5.18 - for f in files: 5.19 - path = os.path.join(root, f) 5.20 - yield path[len(base)+1:], path 5.21 - else: 5.22 - if os.path.isfile(base): 5.23 - yield '', base 5.24 - 5.25 -# create list of unique file names under both directories. 5.26 -files = dict(walk(sys.argv[1])) 5.27 -files.update(walk(sys.argv[2])) 5.28 -files = files.keys() 5.29 -files.sort() 5.30 - 5.31 -def name(base, f): 5.32 - if f: 5.33 - path = os.path.join(base, f) 5.34 - else: 5.35 - path = base 5.36 - # interdiff requires two files; use /dev/null if one is missing. 5.37 - if os.path.exists(path): 5.38 - return path 5.39 - return '/dev/null' 5.40 - 5.41 -ret = 0 5.42 - 5.43 -for f in files: 5.44 - if os.system('interdiff "%s" "%s"' % (name(sys.argv[1], f), 5.45 - name(sys.argv[2], f))): 5.46 - ret = 1 5.47 - 5.48 -sys.exit(ret)
6.1 --- a/examples/hg-replay Thu Mar 12 15:35:19 2009 +0800 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,107 +0,0 @@ 6.4 -#!/usr/bin/env python 6.5 -# 6.6 -# Adapter for using interdiff with mercurial's extdiff extension. 6.7 -# 6.8 -# Copyright 2006 Bryan O'Sullivan <bos@serpentine.com> 6.9 -# 6.10 -# This software may be used and distributed according to the terms of 6.11 -# the GNU General Public License, incorporated herein by reference. 6.12 - 6.13 -import os 6.14 -import shutil 6.15 -import sys 6.16 -import tempfile 6.17 - 6.18 -if len(sys.argv) < 4: 6.19 - print >> sys.stderr, ('usage: %s srcrepo destrepo cset-to-omit [...]' % 6.20 - os.path.basename(sys.argv[0])) 6.21 - sys.exit(1) 6.22 - 6.23 -srcrepo, destrepo = sys.argv[1], sys.argv[2] 6.24 -omit = sys.argv[3:] 6.25 - 6.26 -changemap = {} 6.27 -revs = [] 6.28 - 6.29 -parent = None 6.30 - 6.31 -sys.stdout.write('gathering history...') 6.32 -sys.stdout.flush() 6.33 - 6.34 -for line in os.popen("hg --cwd %r log -r0:tip --template '{rev}:{node} {parents}\n'" % srcrepo): 6.35 - changes = line.split() 6.36 - cset = changes[0].split(':')[1] 6.37 - rev = len(revs) 6.38 - changemap[cset] = rev 6.39 - if len(changes) >= 2: 6.40 - p1 = int(changes[1].split(':', 1)[0]) 6.41 - if len(changes) == 3: 6.42 - p2 = int(changes[2].split(':', 1)[0]) 6.43 - else: 6.44 - p2 = None 6.45 - if len(changes) == 1: 6.46 - p1 = parent 6.47 - revs.append((cset, p1, p2)) 6.48 - parent = rev 6.49 - 6.50 -sys.stdout.write(' %d revs\n' % len(revs)) 6.51 - 6.52 -def findrev(r): 6.53 - try: 6.54 - i = int(r) 6.55 - if str(i) == r: 6.56 - rev = i 6.57 - if rev < 0: 6.58 - rev += len(revs) 6.59 - if rev < 0 or rev > len(revs): 6.60 - print >> sys.stderr, 'bad changeset: %r' % r 6.61 - sys.exit(1) 6.62 - cset = revs[rev][0] 6.63 - except ValueError: 6.64 - cset = r 6.65 - matches = [changemap[c] for c in changemap if c.startswith(cset)] 6.66 - if len(matches) != 1: 6.67 - print >> sys.stderr, 'bad changeset: %r' % r 6.68 - sys.exit(1) 6.69 - rev = matches[0] 6.70 - return rev 6.71 - 6.72 -def run(cmd): 6.73 - print cmd 6.74 - ret = os.system(cmd) 6.75 - if ret: 6.76 - print >> sys.stderr, 'failure:', cmd 6.77 - sys.exit(1) 6.78 - 6.79 -omit = map(findrev, omit) 6.80 -omit.sort() 6.81 -newrevs = revs[:omit[0]] 6.82 -tip = len(newrevs) - 1 6.83 -run('hg clone -q -r%s %r %r' % (tip, srcrepo, destrepo)) 6.84 - 6.85 -os.environ['HGMERGE'] = 'true' 6.86 - 6.87 -patchdir = tempfile.mkdtemp(prefix='replay.') 6.88 -try: 6.89 - run('hg --cwd %r export --git -o %r%s%%R %d:tip' % 6.90 - (srcrepo, patchdir, os.sep, omit[0]+1)) 6.91 - for rev in xrange(omit[0], len(revs)): 6.92 - if rev in omit: 6.93 - print 'omit', rev 6.94 - newrevs.append((None, revs[rev][1], None)) 6.95 - continue 6.96 - _, p1, p2 = revs[rev] 6.97 - np1 = newrevs[p1][1] 6.98 - if tip != np1: 6.99 - run('hg --cwd %r update -q -C %s' % (destrepo, np1)) 6.100 - np2 = None 6.101 - if p2: 6.102 - np2 = newrevs[p2][1] 6.103 - run('hg --cwd %r merge -q %s' % (destrepo, np2)) 6.104 - print >> sys.stderr, 'XXX - cannot handle merges properly yet' 6.105 - run('hg --cwd %r import -q -f %r%s%d' % (destrepo, patchdir, os.sep, rev)) 6.106 - tip = len(newrevs) - 1 6.107 - newrevs.append((None, tip, np2)) 6.108 -finally: 6.109 - print 'cleaning up ...' 6.110 - #shutil.rmtree(patchdir)
7.1 --- a/sillybench/sillybench.py Thu Mar 12 15:35:19 2009 +0800 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,177 +0,0 @@ 7.4 -#!/usr/bin/python 7.5 -# 7.6 -# Silly benchmarking program, to give a vague idea of how fast a few 7.7 -# tools are on a handful of common operations. 7.8 -# 7.9 -# Use a fairly big and real source tarball to test with: Firefox 7.10 -# 2.0.0.3 (37622 files, 5374 directories, 343MB unpacked onto 7.11 -# 4KB-blocksize ext3). 7.12 - 7.13 -import csv 7.14 -import os 7.15 -import shutil 7.16 -import sys 7.17 -import tempfile 7.18 -import time 7.19 -import urllib2 7.20 - 7.21 -url = 'ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.3/source/firefox-2.0.0.3-source.tar.bz2' 7.22 - 7.23 -class CommandFailure(Exception): 7.24 - pass 7.25 - 7.26 -class rcs(object): 7.27 - def __init__(self): 7.28 - self.logfp = open(self.__class__.__name__ + '.csv', 'w') 7.29 - self.csv = csv.writer(self.logfp) 7.30 - 7.31 - def download(self): 7.32 - name = url[url.rfind('/')+1:] 7.33 - path = os.path.join(os.environ['HOME'], name) 7.34 - if not os.path.isfile(path): 7.35 - ofp = open(path + '.part', 'wb') 7.36 - try: 7.37 - ifp = urllib2.urlopen(url) 7.38 - nbytes = ifp.info()['content-length'] 7.39 - sys.stdout.write('%s: %s bytes ' % (name, nbytes)) 7.40 - sys.stdout.flush() 7.41 - while True: 7.42 - data = ifp.read(131072) 7.43 - if not data: break 7.44 - sys.stdout.write('.') 7.45 - sys.stdout.flush() 7.46 - ofp.write(data) 7.47 - del ofp 7.48 - os.rename(path + '.part', path) 7.49 - except: 7.50 - if os.path.exists(path + '.part'): 7.51 - os.unlink(path + '.part') 7.52 - if os.path.exists(path): 7.53 - os.unlink(path) 7.54 - raise 7.55 - return path 7.56 - 7.57 - def run(self, args, mustsucceed=True): 7.58 - ret = os.spawnvp(os.P_WAIT, args[0], args) 7.59 - if ret < 0: 7.60 - msg = 'killed by signal %d' % (-ret) 7.61 - if ret > 0: 7.62 - msg = 'exited with status %d' % (ret) 7.63 - if ret: 7.64 - if mustsucceed: 7.65 - raise CommandFailure('%s: %s' % (msg, ' '.join(args))) 7.66 - print >> sys.stderr, 'WARNING: %s: %s' % (msg, ' '.join(args)) 7.67 - 7.68 - def time(self, *args, **kwargs): 7.69 - start = time.time() 7.70 - self.run(*args, **kwargs) 7.71 - end = time.time() 7.72 - return end - start 7.73 - 7.74 - def logtime(self, name, elapsed, rest=[]): 7.75 - self.log('time:' + name, '%.3f' % elapsed, rest) 7.76 - 7.77 - def log(self, name, value, rest=[]): 7.78 - item = (name, value, repr(rest)) 7.79 - print ' '.join(item) 7.80 - self.csv.writerow(item) 7.81 - self.logfp.flush() 7.82 - 7.83 - def unpack(self): 7.84 - tarball = self.download() 7.85 - t = self.time(['tar', '-C', self.wdir, '-jxf', tarball]) 7.86 - self.logtime('internal:untar', t) 7.87 - for name in os.listdir(os.path.join(self.wdir, 'mozilla')): 7.88 - os.rename(os.path.join(self.wdir, 'mozilla', name), 7.89 - os.path.join(self.wdir, name)) 7.90 - 7.91 - def cleanup(self): 7.92 - pass 7.93 - 7.94 - def add(self, paths): 7.95 - pass 7.96 - 7.97 - def commit(self, msg, paths): 7.98 - pass 7.99 - 7.100 - def status(self, path): 7.101 - pass 7.102 - 7.103 - def remove(self, path): 7.104 - pass 7.105 - 7.106 - 7.107 -class subversion(rcs): 7.108 - def __init__(self, root): 7.109 - rcs.__init__(self) 7.110 - self.repo = os.path.join(root, 'repo') 7.111 - self.wdir = os.path.join(root, 'wc') 7.112 - create = self.time(['svnadmin', 'create', '--fs-type=fsfs', self.repo]) 7.113 - self.logtime('svn:create', create) 7.114 - co = self.time(['svn', 'co', 'file://' + self.repo, self.wdir]) 7.115 - self.logtime('svn:co', co) 7.116 - self.logtime('init', create + co) 7.117 - os.chdir(self.wdir) 7.118 - 7.119 - def dropmeta(self, names): 7.120 - return [n for n in names if os.path.basename(n) != '.svn'] 7.121 - 7.122 - def add(self, paths): 7.123 - t = self.time(['svn', 'add', '-q'] + paths) 7.124 - self.logtime('add %r' % paths, t) 7.125 - 7.126 - def commit(self, msg, paths=[]): 7.127 - if paths: 7.128 - t = self.time(['svn', 'ci', '-q', '-m', msg] + paths) 7.129 - else: 7.130 - t = self.time(['svn', 'ci', '-q', '-m', msg]) 7.131 - self.logtime('commit %r' % paths, t) 7.132 - 7.133 - 7.134 -class mercurial(rcs): 7.135 - def __init__(self, root): 7.136 - rcs.__init__(self) 7.137 - self.repo = os.path.join(root, 'repo') 7.138 - self.wdir = self.repo 7.139 - init = self.time(['hg', 'init', self.repo]) 7.140 - self.logtime('init', init) 7.141 - os.chdir(self.wdir) 7.142 - 7.143 - def dropmeta(self, names): 7.144 - return [n for n in names if os.path.basename(n) != '.hg'] 7.145 - 7.146 - def add(self, paths): 7.147 - t = self.time(['hg', 'add', '-q'] + paths) 7.148 - self.logtime('add %r' % paths, t) 7.149 - 7.150 - def commit(self, msg, paths=[]): 7.151 - if paths: 7.152 - t = self.time(['hg', 'ci', '-q', '-m', msg] + paths) 7.153 - else: 7.154 - t = self.time(['hg', 'ci', '-q', '-m', msg]) 7.155 - self.logtime('commit %r' % paths, t) 7.156 - 7.157 -def benchmark(cls): 7.158 - oldcwd = os.getcwd() 7.159 - root = tempfile.mkdtemp(prefix='sillybench.') 7.160 - try: 7.161 - print 'root', root 7.162 - inst = cls(root) 7.163 - inst.unpack() 7.164 - names = inst.dropmeta(os.listdir('.')) 7.165 - dirs = [n for n in names if os.path.isdir(n)] 7.166 - nondirs = [n for n in names if not os.path.isdir(n)] 7.167 - dirs.sort(key=hash) 7.168 - names.sort(key=hash) 7.169 - for d in dirs[:len(dirs)/2]: 7.170 - inst.add([d]) 7.171 - inst.commit('Add %r' % d, [d]) 7.172 - inst.add(dirs[len(dirs)/2:] + names) 7.173 - inst.commit('Add remaining dirs and files') 7.174 - finally: 7.175 - print >> sys.stderr, '[cleaning up...]' 7.176 - shutil.rmtree(root) 7.177 - os.chdir(oldcwd) 7.178 - 7.179 -benchmark(mercurial) 7.180 -#benchmark(subversion)
8.1 --- a/tools/latex-to-docbook Thu Mar 12 15:35:19 2009 +0800 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,198 +0,0 @@ 8.4 -#!/usr/bin/python 8.5 -# 8.6 -# This is the most horrible of hacks. Pretend you're not looking.</para> 8.7 - 8.8 -import cStringIO as StringIO 8.9 -import re, sys 8.10 - 8.11 -sections = { 8.12 - 'chapter': 'chapter', 8.13 - 'section': 'sect1', 8.14 - 'subsection': 'sect2', 8.15 - 'subsubsection': 'sect3', 8.16 - } 8.17 - 8.18 -envs = { 8.19 - 'codesample2': 'programlisting', 8.20 - 'codesample4': 'programlisting', 8.21 - 'enumerate': 'orderedlist', 8.22 - 'figure': 'informalfigure', 8.23 - 'itemize': 'itemizedlist', 8.24 - 'note': 'note', 8.25 - 'quote': 'blockquote', 8.26 - } 8.27 - 8.28 -def process(ifp, ofp): 8.29 - print >> ofp, '<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->\n' 8.30 - stack = [] 8.31 - para = True 8.32 - inlist = 0 8.33 - for line in ifp: 8.34 - if line.startswith('%%% Local Variables:'): 8.35 - break 8.36 - line = (line.rstrip() 8.37 - .replace('~', ' ') 8.38 - .replace('&', '&') 8.39 - .replace('---', '&emdash;') 8.40 - .replace('\_', '_') 8.41 - .replace('\{', '{') 8.42 - .replace('\}', '}') 8.43 - .replace('\$', '$') 8.44 - .replace('\%', '%') 8.45 - .replace('\#', '#') 8.46 - .replace('<', '<') 8.47 - .replace('>', '>') 8.48 - .replace('``', '<quote>') 8.49 - .replace("''", '</quote>') 8.50 - .replace('\\', '\\')) 8.51 - line = re.sub(r'\s*\\(?:centering|small)\b\s*', '', line) 8.52 - line = re.sub(r'\\(?:hgrc\\|hgrc)\b', 8.53 - r'<filename role="special"> /.hgrc</filename>', line) 8.54 - line = re.sub(r'\\item\[(?P<key>[^]]+)\]', r'\item \g<key>:', line) 8.55 - line = re.sub(r'\\bug{(?P<id>\d+)}', 8.56 - r'<ulink role="hg-bug" url="http://www.selenic.com/mercurial/bts/issue\g<id>">issue \g<id></ulink>', line) 8.57 - line = re.sub(r'\\cite{([^}]+)}', r'<citation>\1</citation>', line) 8.58 - line = re.sub(r'\\hggopt{(?P<opt>[^}]+)}', 8.59 - r'<option role="hg-opt-global">\g<opt></option>', line) 8.60 - line = re.sub(r'\\hgxopt{(?P<ext>[^}]+)}{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}', 8.61 - r'<option role="hg-ext-\g<ext>-cmd-\g<cmd>-opt">\g<opt></option>', line) 8.62 - line = re.sub(r'\\hgxcmd{(?P<ext>[^}]+)}{(?P<cmd>[^}]+)}', 8.63 - r'<command role="hg-ext-\g<ext>">\g<cmd></command>', line) 8.64 - line = re.sub(r'\\hgext{(?P<ext>[^}]+)}', 8.65 - r'<literal role="hg-ext">\g<ext></literal>', line) 8.66 - line = re.sub(r'\\hgopt{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}', 8.67 - r'<option role="hg-opt-\g<cmd>">\g<opt></option>', 8.68 - line) 8.69 - line = re.sub(r'\\cmdopt{(?P<cmd>[^}]+)}{(?P<opt>[^}]+)}', 8.70 - r'<option role="cmd-opt-\g<cmd>">\g<opt></option>', 8.71 - line) 8.72 - line = re.sub(r'\\hgcmd{(?P<cmd>[^}]+)}', 8.73 - r'<command role="hg-cmd">hg \g<cmd></command>', line) 8.74 - line = re.sub(r'\\caption{(?P<text>[^}]+?)}', 8.75 - r'<caption><para>\g<text></para></caption>', line) 8.76 - line = re.sub(r'\\grafix{(?P<name>[^}]+)}', 8.77 - r'<mediaobject><imageobject><imagedata fileref="\g<name>"/></imageobject><textobject><phrase>XXX add text</phrase></textobject></mediaobject>', line) 8.78 - line = re.sub(r'\\envar{(?P<name>[^}]+)}', 8.79 - r'<envar>\g<name></envar>', line) 8.80 - line = re.sub(r'\\rcsection{(?P<sect>[^}]+)}', 8.81 - r'<literal role="rc-\g<sect>">\g<sect></literal>', line) 8.82 - line = re.sub(r'\\rcitem{(?P<sect>[^}]+)}{(?P<name>[^}]+)}', 8.83 - r'<envar role="rc-item-\g<sect>">\g<name></envar>', line) 8.84 - line = re.sub(r'\\dirname{(?P<dir>[^}]+?)}', 8.85 - r'<filename class="directory">\g<dir></filename>', line) 8.86 - line = re.sub(r'\\filename{(?P<file>[^}]+?)}', 8.87 - r'<filename>\g<file></filename>', line) 8.88 - line = re.sub(r'\\tildefile{(?P<file>[^}]+)}', 8.89 - r'<filename role="home">~/\g<file></filename>', line) 8.90 - line = re.sub(r'\\sfilename{(?P<file>[^}]+)}', 8.91 - r'<filename role="special">\g<file></filename>', line) 8.92 - line = re.sub(r'\\sdirname{(?P<dir>[^}]+)}', 8.93 - r'<filename role="special" class="directory">\g<dir></filename>', line) 8.94 - line = re.sub(r'\\interaction{(?P<id>[^}]+)}', 8.95 - r'<!-- &interaction.\g<id>; -->', line) 8.96 - line = re.sub(r'\\excode{(?P<id>[^}]+)}', 8.97 - r'<!-- &example.\g<id>; -->', line) 8.98 - line = re.sub(r'\\pymod{(?P<mod>[^}]+)}', 8.99 - r'<literal role="py-mod">\g<mod></literal>', line) 8.100 - line = re.sub(r'\\pymodclass{(?P<mod>[^}]+)}{(?P<class>[^}]+)}', 8.101 - r'<literal role="py-mod-\g<mod>">\g<class></literal>', line) 8.102 - line = re.sub(r'\\url{(?P<url>[^}]+)}', 8.103 - r'<ulink url="\g<url>">\g<url></ulink>', line) 8.104 - line = re.sub(r'\\href{(?P<url>[^}]+)}{(?P<text>[^}]+)}', 8.105 - r'<ulink url="\g<url>">\g<text></ulink>', line) 8.106 - line = re.sub(r'\\command{(?P<cmd>[^}]+)}', 8.107 - r'<command>\g<cmd></command>', line) 8.108 - line = re.sub(r'\\option{(?P<opt>[^}]+)}', 8.109 - r'<option>\g<opt></option>', line) 8.110 - line = re.sub(r'\\ref{(?P<id>[^}]+)}', r'<xref linkend="\g<id>"/>', line) 8.111 - line = re.sub(r'\\emph{(?P<txt>[^}]+)}', 8.112 - r'<emphasis>\g<txt></emphasis>', line) 8.113 - line = re.sub(r'\\texttt{(?P<txt>[^}]+)}', 8.114 - r'<literal>\g<txt></literal>', line) 8.115 - line = re.sub(r'\\textbf{(?P<txt>[^}]+)}', 8.116 - r'<emphasis role="bold">\g<txt></emphasis>', line) 8.117 - line = re.sub(r'\\hook{(?P<name>[^}]+)}', 8.118 - r'<literal role="hook">\g<name></literal>', line) 8.119 - line = re.sub(r'\\tplfilter{(?P<name>[^}]+)}', 8.120 - r'<literal role="template-filter">\g<name></literal>', line) 8.121 - line = re.sub(r'\\tplkword{(?P<name>[^}]+)}', 8.122 - r'<literal role="template-keyword">\g<name></literal>', line) 8.123 - line = re.sub(r'\\tplkwfilt{(?P<tpl>[^}]+)}{(?P<name>[^}]+)}', 8.124 - r'<literal role="template-kw-filt-\g<tpl>">\g<name></literal>', line) 8.125 - line = re.sub(r'\\[vV]erb(.)(?P<txt>[^\1]+?)\1', 8.126 - r'<literal>\g<txt></literal>', line) 8.127 - line = re.sub(r'\\package{(?P<name>[^}]+)}', 8.128 - r'<literal role="package">\g<name></literal>', line) 8.129 - line = re.sub(r'\\hgcmdargs{(?P<cmd>[^}]+)}{(?P<args>[^}]+)}', 8.130 - r'<command role="hg-cmd">hg \g<cmd> \g<args></command>', 8.131 - line) 8.132 - line = re.sub(r'\\cmdargs{(?P<cmd>[^}]+)}{(?P<args>[^}]+)}', 8.133 - r'<command>\g<cmd> \g<args></command>', 8.134 - line) 8.135 - m = re.match(r'\\(chapter|section|subsection|subsubsection){(.*)}', line) 8.136 - if m: 8.137 - kind, content = m.groups() 8.138 - sec = sections[kind] 8.139 - while stack and stack[-1] >= sec: 8.140 - close = stack.pop() 8.141 - print >> ofp, '</%s>' % close 8.142 - stack.append(sec) 8.143 - print >> ofp, '<%s>\n<title>%s</title>' % (sec, content) 8.144 - else: 8.145 - m = re.match(r'\s*\\(begin|end){(?P<sect>[^}]+)}', line) 8.146 - if m: 8.147 - if not para: 8.148 - print >> ofp, '</para>' 8.149 - if inlist: 8.150 - ofp.write('</listitem>') 8.151 - para = True 8.152 - state, env = m.groups() 8.153 - env = envs[env] 8.154 - if state == 'begin': 8.155 - ofp.write('<') 8.156 - if env in ('itemizedlist', 'orderedlist'): 8.157 - inlist = 1 8.158 - else: 8.159 - ofp.write('</') 8.160 - if env in ('itemizedlist', 'orderedlist'): 8.161 - inlist = 0 8.162 - print >> ofp, env + '>' 8.163 - else: 8.164 - if line.startswith('\\item '): 8.165 - if inlist > 1: 8.166 - print >> ofp, '</para>' 8.167 - print >> ofp, '</listitem>' 8.168 - else: 8.169 - inlist = 2 8.170 - para = True 8.171 - line = line[6:] 8.172 - if line and para: 8.173 - if inlist: 8.174 - ofp.write('<listitem>') 8.175 - ofp.write('<para>') 8.176 - para = False 8.177 - if not line and not para: 8.178 - print >> ofp, '</para>' 8.179 - if inlist: 8.180 - ofp.write('</listitem>') 8.181 - para = True 8.182 - print >> ofp, line 8.183 - while stack: 8.184 - print >> ofp, '</%s>' % stack.pop() 8.185 - ofp.write('\n'.join(['\n<!--', 8.186 - 'local variables: ', 8.187 - 'sgml-parent-document: ("00book.xml" "book" "chapter")', 8.188 - 'end:', 8.189 - '-->'])) 8.190 - 8.191 - 8.192 -if __name__ == '__main__': 8.193 - for name in sys.argv[1:]: 8.194 - if not name.endswith('.tex'): 8.195 - continue 8.196 - newname = name[:-3] + 'xml' 8.197 - ofp = StringIO.StringIO() 8.198 - process(open(name), ofp) 8.199 - s = ofp.getvalue() 8.200 - s = re.sub('\n+</para>', '</para>', s, re.M) 8.201 - open(newname, 'w').write(s)