hgbook
diff en/cmdref.py @ 171:8c1703a98266
Add a dependency on htlatex to HTML targets, even though we don't call it.
If the files it ships with aren't present, we can't build HTML.
If the files it ships with aren't present, we can't build HTML.
author | Bryan O'Sullivan <bos@serpentine.com> |
---|---|
date | Mon Mar 26 23:57:58 2007 -0700 (2007-03-26) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/en/cmdref.py Mon Mar 26 23:57:58 2007 -0700 1.3 @@ -0,0 +1,156 @@ 1.4 +#!/usr/bin/env python 1.5 + 1.6 +import getopt 1.7 +import itertools 1.8 +import os 1.9 +import re 1.10 +import sys 1.11 + 1.12 +def usage(exitcode): 1.13 + print >> sys.stderr, ('usage: %s [-H|--hidden] hg_repo' % 1.14 + os.path.basename(sys.argv[0])) 1.15 + sys.exit(exitcode) 1.16 + 1.17 +try: 1.18 + opts, args = getopt.getopt(sys.argv[1:], 'AHh?', ['all', 'help', 'hidden']) 1.19 + opt_all = False 1.20 + opt_hidden = False 1.21 + for o, a in opts: 1.22 + if o in ('-h', '-?', '--help'): 1.23 + usage(0) 1.24 + if o in ('-A', '--all'): 1.25 + opt_all = True 1.26 + if o in ('-H', '--hidden'): 1.27 + opt_hidden = True 1.28 +except getopt.GetoptError, err: 1.29 + print >> sys.stderr, 'error:', err 1.30 + usage(1) 1.31 + 1.32 +try: 1.33 + hg_repo, ltx_file = args 1.34 +except ValueError: 1.35 + usage(1) 1.36 + 1.37 +if not os.path.isfile(os.path.join(hg_repo, 'mercurial', 'commands.py')): 1.38 + print >> sys.stderr, ('error: %r does not contain mercurial code' % 1.39 + hg_repo) 1.40 + sys.exit(1) 1.41 + 1.42 +sys.path.insert(0, hg_repo) 1.43 + 1.44 +from mercurial import commands 1.45 + 1.46 +def get_commands(): 1.47 + seen = {} 1.48 + for name, info in sorted(commands.table.iteritems()): 1.49 + aliases = name.split('|', 1) 1.50 + name = aliases.pop(0).lstrip('^') 1.51 + function, options, synopsis = info 1.52 + seen[name] = {} 1.53 + for shortopt, longopt, arg, desc in options: 1.54 + seen[name][longopt] = shortopt 1.55 + return seen 1.56 + 1.57 +def cmd_filter((name, aliases, options)): 1.58 + if opt_all: 1.59 + return True 1.60 + if opt_hidden: 1.61 + return name.startswith('debug') 1.62 + return not name.startswith('debug') 1.63 + 1.64 +def scan(ltx_file): 1.65 + cmdref_re = re.compile(r'^\\cmdref{(?P<cmd>\w+)}') 1.66 + optref_re = re.compile(r'^\\l?optref{(?P<cmd>\w+)}' 1.67 + r'(?:{(?P<short>[^}])})?' 1.68 + r'{(?P<long>[^}]+)}') 1.69 + 1.70 + seen = {} 1.71 + locs = {} 1.72 + for lnum, line in enumerate(open(ltx_file)): 1.73 + m = cmdref_re.match(line) 1.74 + if m: 1.75 + d = m.groupdict() 1.76 + cmd = d['cmd'] 1.77 + seen[cmd] = {} 1.78 + locs[cmd] = lnum + 1 1.79 + continue 1.80 + m = optref_re.match(line) 1.81 + if m: 1.82 + d = m.groupdict() 1.83 + seen[d['cmd']][d['long']] = d['short'] 1.84 + continue 1.85 + return seen, locs 1.86 + 1.87 +documented, locs = scan(ltx_file) 1.88 +known = get_commands() 1.89 + 1.90 +doc_set = set(documented) 1.91 +known_set = set(known) 1.92 + 1.93 +errors = 0 1.94 + 1.95 +for nonexistent in sorted(doc_set.difference(known_set)): 1.96 + print >> sys.stderr, ('%s:%d: %r command does not exist' % 1.97 + (ltx_file, locs[nonexistent], nonexistent)) 1.98 + errors += 1 1.99 + 1.100 +def optcmp(a, b): 1.101 + la, sa = a 1.102 + lb, sb = b 1.103 + sc = cmp(sa, sb) 1.104 + if sc: 1.105 + return sc 1.106 + return cmp(la, lb) 1.107 + 1.108 +for cmd in doc_set.intersection(known_set): 1.109 + doc_opts = documented[cmd] 1.110 + known_opts = known[cmd] 1.111 + 1.112 + do_set = set(doc_opts) 1.113 + ko_set = set(known_opts) 1.114 + 1.115 + for nonexistent in sorted(do_set.difference(ko_set)): 1.116 + print >> sys.stderr, ('%s:%d: %r option to %r command does not exist' % 1.117 + (ltx_file, locs[cmd], nonexistent, cmd)) 1.118 + errors += 1 1.119 + 1.120 + def mycmp(la, lb): 1.121 + sa = known_opts[la] 1.122 + sb = known_opts[lb] 1.123 + return optcmp((la, sa), (lb, sb)) 1.124 + 1.125 + for undocumented in sorted(ko_set.difference(do_set), cmp=mycmp): 1.126 + print >> sys.stderr, ('%s:%d: %r option to %r command not documented' % 1.127 + (ltx_file, locs[cmd], undocumented, cmd)) 1.128 + shortopt = known_opts[undocumented] 1.129 + if shortopt: 1.130 + print '\optref{%s}{%s}{%s}' % (cmd, shortopt, undocumented) 1.131 + else: 1.132 + print '\loptref{%s}{%s}' % (cmd, undocumented) 1.133 + errors += 1 1.134 + sys.stdout.flush() 1.135 + 1.136 +if errors: 1.137 + sys.exit(1) 1.138 + 1.139 +sorted_locs = sorted(locs.iteritems(), key=lambda x:x[1]) 1.140 + 1.141 +def next_loc(cmd): 1.142 + for i, (name, loc) in enumerate(sorted_locs): 1.143 + if name >= cmd: 1.144 + return sorted_locs[i-1][1] + 1 1.145 + return loc 1.146 + 1.147 +for undocumented in sorted(known_set.difference(doc_set)): 1.148 + print >> sys.stderr, ('%s:%d: %r command not documented' % 1.149 + (ltx_file, next_loc(undocumented), undocumented)) 1.150 + print '\cmdref{%s}' % undocumented 1.151 + for longopt, shortopt in sorted(known[undocumented].items(), cmp=optcmp): 1.152 + if shortopt: 1.153 + print '\optref{%s}{%s}{%s}' % (undocumented, shortopt, longopt) 1.154 + else: 1.155 + print '\loptref{%s}{%s}' % (undocumented, longopt) 1.156 + sys.stdout.flush() 1.157 + errors += 1 1.158 + 1.159 +sys.exit(errors and 1 or 0)