FooBarWidget-mizuho 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/asciidoc/BUGS +3 -3
- data/asciidoc/CHANGELOG +112 -63
- data/asciidoc/CHANGELOG.txt +50 -0
- data/asciidoc/INSTALL +6 -6
- data/asciidoc/Makefile.in +21 -5
- data/asciidoc/README +3 -3
- data/asciidoc/asciidoc.conf +9 -12
- data/asciidoc/asciidoc.py +204 -151
- data/asciidoc/common.aap +2 -2
- data/asciidoc/doc/a2x.1 +4 -3
- data/asciidoc/doc/a2x.1.txt +1 -1
- data/asciidoc/doc/article.css-embedded.html +13 -12
- data/asciidoc/doc/article.html +46 -644
- data/asciidoc/doc/article.pdf +0 -0
- data/asciidoc/doc/asciidoc.1 +2 -2
- data/asciidoc/doc/asciidoc.1.css-embedded.html +14 -13
- data/asciidoc/doc/asciidoc.1.css.html +3 -3
- data/asciidoc/doc/asciidoc.1.html +3 -3
- data/asciidoc/doc/asciidoc.css-embedded.html +238 -225
- data/asciidoc/doc/asciidoc.css.html +227 -215
- data/asciidoc/doc/asciidoc.dict +10 -1
- data/asciidoc/doc/asciidoc.html +181 -164
- data/asciidoc/doc/asciidoc.txt +167 -148
- data/asciidoc/doc/asciimathml.txt +5 -4
- data/asciidoc/doc/book.css-embedded.html +13 -12
- data/asciidoc/doc/faq.txt +60 -3
- data/asciidoc/doc/music-filter.html +94 -41
- data/asciidoc/doc/music-filter.pdf +0 -0
- data/asciidoc/doc/source-highlight-filter.html +125 -465
- data/asciidoc/doc/source-highlight-filter.pdf +0 -0
- data/asciidoc/docbook.conf +8 -2
- data/asciidoc/examples/website/CHANGELOG.html +129 -4
- data/asciidoc/examples/website/INSTALL.html +6 -6
- data/asciidoc/examples/website/README-website.html +3 -3
- data/asciidoc/examples/website/README.html +3 -3
- data/asciidoc/examples/website/a2x.1.html +4 -4
- data/asciidoc/examples/website/asciidoc-docbook-xsl.html +3 -3
- data/asciidoc/examples/website/asciidoc-graphviz-sample.txt +1 -0
- data/asciidoc/examples/website/downloads.html +7 -7
- data/asciidoc/examples/website/faq.html +95 -40
- data/asciidoc/examples/website/index.html +34 -13
- data/asciidoc/examples/website/index.txt +25 -9
- data/asciidoc/examples/website/latex-backend.html +4 -4
- data/asciidoc/examples/website/manpage.html +3 -3
- data/asciidoc/examples/website/music-filter.html +3 -3
- data/asciidoc/examples/website/sample1.png +0 -0
- data/asciidoc/examples/website/sample3.png +0 -0
- data/asciidoc/examples/website/sample4.png +0 -0
- data/asciidoc/examples/website/source-highlight-filter.html +5 -5
- data/asciidoc/examples/website/support.html +3 -3
- data/asciidoc/examples/website/userguide.html +227 -215
- data/asciidoc/examples/website/version9.html +3 -3
- data/asciidoc/filters/{code-filter-readme.txt → code/code-filter-readme.txt} +0 -0
- data/asciidoc/filters/{code-filter-test.txt → code/code-filter-test.txt} +0 -0
- data/asciidoc/filters/{code-filter.conf → code/code-filter.conf} +1 -1
- data/asciidoc/filters/{code-filter.py → code/code-filter.py} +0 -0
- data/asciidoc/filters/graphviz/asciidoc-graphviz-sample.txt +130 -0
- data/asciidoc/filters/graphviz/graphviz-filter.conf +39 -0
- data/asciidoc/filters/graphviz/graphviz2png.py +154 -0
- data/asciidoc/filters/{music-filter-test.txt → music/music-filter-test.txt} +0 -0
- data/asciidoc/filters/{music-filter.conf → music/music-filter.conf} +0 -0
- data/asciidoc/filters/{music2png.py → music/music2png.py} +0 -0
- data/asciidoc/filters/{source-highlight-filter-test.txt → source/source-highlight-filter-test.txt} +0 -0
- data/asciidoc/filters/{source-highlight-filter.conf → source/source-highlight-filter.conf} +2 -1
- data/asciidoc/html4.conf +5 -2
- data/asciidoc/stylesheets/xhtml11-quirks.css +0 -8
- data/asciidoc/stylesheets/xhtml11.css +11 -2
- data/asciidoc/vim/syntax/asciidoc.vim +1 -1
- data/asciidoc/xhtml11.conf +5 -2
- data/lib/mizuho/parser.rb +5 -1
- data/mizuho.gemspec +5 -16
- data/test/parser_spec.rb +49 -0
- metadata +22 -10
data/asciidoc/CHANGELOG.txt
CHANGED
@@ -3,6 +3,56 @@ AsciiDoc ChangeLog
|
|
3
3
|
|
4
4
|
:replacements.\bweb:: http://www.methods.co.nz/asciidoc/
|
5
5
|
|
6
|
+
Version 8.3.3 (2009-01-02)
|
7
|
+
--------------------------
|
8
|
+
This release supercedes 8.3.2.
|
9
|
+
|
10
|
+
.Bug fixes
|
11
|
+
- The broken and confusing numeration and numeration2 numbered list
|
12
|
+
attributes have been dropped, use the style attribute instead.
|
13
|
+
|
14
|
+
|
15
|
+
Version 8.3.2 (2009-01-01)
|
16
|
+
--------------------------
|
17
|
+
.Additions and changes
|
18
|
+
- Added Gouichi Iisaka's Graphviz filter to distribution.
|
19
|
+
- The 'SidebarBlock' element can now be rendered with an 'abstract'
|
20
|
+
style.
|
21
|
+
- Reorganized filters into a separate subdirectory for each filter.
|
22
|
+
- Updated `Makefile.in` and `MANIFEST` files to reflect new filters
|
23
|
+
organization.
|
24
|
+
- Added 'listing' style to 'LiteralBlock' element so listings with
|
25
|
+
nested listing blocks can be rendered as a listing block.
|
26
|
+
- Changed example 'code' filter to use preferred 'ListingBlock' syntax
|
27
|
+
(the old `~` delimited filter syntax is no longer used).
|
28
|
+
- Implemented 'enumeration' and 'enumeration2' numbered list
|
29
|
+
attributes for specifying the list numbering style ('arabic',
|
30
|
+
'loweralpha', 'upperalpha', 'lowerroman' and 'upperroman').
|
31
|
+
- AsciiDoc now recognizes 'upperalpha', 'lowerroman' and 'upperroman'
|
32
|
+
numbers in `listdef-numbered2` numbered lists and sets the number
|
33
|
+
style based on the style of the first numbered list item
|
34
|
+
(alternative to setting 'enumeration2' attribute).
|
35
|
+
- Updated `formatlistpat` definition in `.vimrc` example in User
|
36
|
+
Guide.
|
37
|
+
- You can now backslash escape system block macros.
|
38
|
+
- Added 'Pychart' FAQ.
|
39
|
+
- Drop paragraph 'text' and list 'text', 'index' and 'label' match
|
40
|
+
groups from attributes -- they are included in the element's text
|
41
|
+
and we don't want them processed a second time as attributes.
|
42
|
+
- Changed comment line block macro to a passthrough block macro to
|
43
|
+
ensure no substitutions.
|
44
|
+
- A 'subslist' no longer has to be appended to a 'PassthroughBlock'
|
45
|
+
macro definition, if omitted no substitutions are performed.
|
46
|
+
- Code tidy up: replaced deprecated `<>` operator with `!=`.
|
47
|
+
- Removed unused linuxdoc code.
|
48
|
+
- Code tidy ups: dropped old types module reference; replaced
|
49
|
+
`has_key()` with preferred `in` operator.
|
50
|
+
|
51
|
+
.Bug fixes
|
52
|
+
- Old syntax source highlight filter regression: special characters
|
53
|
+
where not escaped in DocBook outputs.
|
54
|
+
|
55
|
+
|
6
56
|
Version 8.3.1 (2008-12-14)
|
7
57
|
--------------------------
|
8
58
|
.Additions and changes
|
data/asciidoc/INSTALL
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
AsciiDoc Installation
|
2
2
|
|
3
|
-
version 8.3.
|
3
|
+
version 8.3.3, 2 January 2009
|
4
4
|
|
5
5
|
Note: The current version of AsciiDoc requires Python 2.4 or newer to
|
6
6
|
run. If you don't already have an up-to-date version of Python
|
@@ -27,8 +27,8 @@
|
|
27
27
|
|
28
28
|
The autoconf(1) generated configure script creates a make file that is
|
29
29
|
tailored for your system. To install:
|
30
|
-
$ tar -xzf asciidoc-8.3.
|
31
|
-
$ cd asciidoc-8.3.
|
30
|
+
$ tar -xzf asciidoc-8.3.3.tar.gz
|
31
|
+
$ cd asciidoc-8.3.3
|
32
32
|
$ ./configure
|
33
33
|
$ make
|
34
34
|
$ sudo make install
|
@@ -51,7 +51,7 @@
|
|
51
51
|
new folder:
|
52
52
|
$ mkdir asciidoc
|
53
53
|
$ cd asciidoc
|
54
|
-
$ unzip ../asciidoc-8.3.
|
54
|
+
$ unzip ../asciidoc-8.3.3.zip
|
55
55
|
__________________________________________________________________
|
56
56
|
|
57
57
|
4. Testing your installation
|
@@ -65,8 +65,8 @@
|
|
65
65
|
directly or create a suitable asciidoc.bat file.
|
66
66
|
__________________________________________________________________
|
67
67
|
|
68
|
-
Version 8.3.
|
69
|
-
Last updated
|
68
|
+
Version 8.3.3
|
69
|
+
Last updated 2009-01-02 12:45:19 NZDT
|
70
70
|
|
71
71
|
References
|
72
72
|
|
data/asciidoc/Makefile.in
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# Make file to install/uninstall AsciiDoc
|
3
3
|
#
|
4
4
|
|
5
|
+
.NOTPARALLEL:
|
6
|
+
|
5
7
|
INSTALL = @INSTALL@
|
6
8
|
INSTALL_PROG = @INSTALL_PROGRAM@
|
7
9
|
INSTALL_DATA = @INSTALL_DATA@
|
@@ -32,11 +34,25 @@ manpdir = $(mandir)/man1
|
|
32
34
|
conf = $(wildcard *.conf)
|
33
35
|
confdir = $(ASCIIDOCCONF)
|
34
36
|
|
35
|
-
filters = $(wildcard filters/*.py)
|
36
37
|
filtersdir = $(ASCIIDOCCONF)/filters
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
codefilter = filters/code/code-filter.py
|
40
|
+
codefilterdir = $(filtersdir)/code
|
41
|
+
codefilterconf = filters/code/code-filter.conf
|
42
|
+
codefilterconfdir = $(filtersdir)/code
|
43
|
+
|
44
|
+
graphvizfilter = filters/graphviz/graphviz2png.py
|
45
|
+
graphvizfilterdir = $(filtersdir)/graphviz
|
46
|
+
graphvizfilterconf = filters/graphviz/graphviz-filter.conf
|
47
|
+
graphvizfilterconfdir = $(filtersdir)/graphviz
|
48
|
+
|
49
|
+
musicfilter = filters/music/music2png.py
|
50
|
+
musicfilterdir = $(filtersdir)/music
|
51
|
+
musicfilterconf = filters/music/music-filter.conf
|
52
|
+
musicfilterconfdir = $(filtersdir)/music
|
53
|
+
|
54
|
+
sourcefilterconf = filters/source/source-highlight-filter.conf
|
55
|
+
sourcefilterconfdir = $(filtersdir)/source
|
40
56
|
|
41
57
|
docbook = $(wildcard docbook-xsl/*.xsl)
|
42
58
|
docbookdir = $(ASCIIDOCCONF)/docbook-xsl
|
@@ -59,8 +75,8 @@ iconsdir = $(ASCIIDOCCONF)/images/icons
|
|
59
75
|
doc = $(wildcard README*) $(wildcard BUGS*) $(wildcard INSTALL*) $(wildcard CHANGELOG*)
|
60
76
|
docdir = $(datadir)/doc/asciidoc
|
61
77
|
|
62
|
-
DATATARGETS = manp conf
|
63
|
-
PROGTARGETS = prog
|
78
|
+
DATATARGETS = manp conf docbook dblatex css js callouts icons codefilterconf musicfilterconf sourcefilterconf graphvizfilterconf
|
79
|
+
PROGTARGETS = prog codefilter musicfilter graphvizfilter
|
64
80
|
TARGETS = $(DATATARGETS) $(PROGTARGETS) doc
|
65
81
|
|
66
82
|
INSTDIRS = $(TARGETS:%=%dir)
|
data/asciidoc/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
AsciiDoc README File
|
2
2
|
|
3
|
-
version 8.3.
|
3
|
+
version 8.3.3, 2 January 2009
|
4
4
|
__________________________________________________________________
|
5
5
|
|
6
6
|
1. Prerequisites
|
@@ -36,8 +36,8 @@
|
|
36
36
|
granted under the terms of the GNU General Public License (GPL).
|
37
37
|
__________________________________________________________________
|
38
38
|
|
39
|
-
Version 8.3.
|
40
|
-
Last updated
|
39
|
+
Version 8.3.3
|
40
|
+
Last updated 2009-01-02 12:45:18 NZDT
|
41
41
|
|
42
42
|
References
|
43
43
|
|
data/asciidoc/asciidoc.conf
CHANGED
@@ -231,20 +231,11 @@ endif::asciidoc7compatible[]
|
|
231
231
|
(?u)^(?P<name>image)::(?P<target>\S*?)(\[(?P<attrlist>.*?)\])$=#
|
232
232
|
|
233
233
|
# Passthrough macros.
|
234
|
-
(?u)^(?P<name>pass)::(?P<subslist>\S*?)(\[(?P<passtext>.*?)\])$=#
|
234
|
+
(?u)^(?P<name>pass)::(?P<subslist>\S*?)(\[(?P<passtext>.*?)\])$=#
|
235
235
|
|
236
236
|
^'{3,}$=#ruler
|
237
237
|
^<{3,}$=#pagebreak
|
238
|
-
^//([^/].*|)$=#comment
|
239
|
-
|
240
|
-
# Default block macro (listed last as a catchall)).
|
241
|
-
#(?u)^(?P<name>\w(\w|-)*?)::(?P<target>\S*?)(\[(?P<attrlist>.*?)\])$=#
|
242
|
-
|
243
|
-
#--------------
|
244
|
-
# System macros
|
245
|
-
#--------------
|
246
|
-
# This default system macro is hardwired into asciidoc.
|
247
|
-
#(?u)^(?P<name>\w(\w|-)*?)::(?P<target>\S*?)(\[(?P<attrlist>.*?)\])$=+
|
238
|
+
^//(?P<passtext>[^/].*|)$=#comment
|
248
239
|
|
249
240
|
#-----------------
|
250
241
|
# Delimited blocks
|
@@ -260,6 +251,8 @@ options=skip
|
|
260
251
|
delimiter=^\*{4,}$
|
261
252
|
template=sidebarblock
|
262
253
|
options=sectionbody
|
254
|
+
posattrs=style
|
255
|
+
abstract-style=template="abstractblock"
|
263
256
|
|
264
257
|
[blockdef-list]
|
265
258
|
delimiter=^--$
|
@@ -288,6 +281,7 @@ delimiter=^\.{4,}$
|
|
288
281
|
template=literalblock
|
289
282
|
subs=verbatim
|
290
283
|
posattrs=style
|
284
|
+
listing-style=template="listingblock"
|
291
285
|
# DEPRECATED: Use verse style on quote blocks instead.
|
292
286
|
verse-style=template="verseblock",subs="normal"
|
293
287
|
|
@@ -311,6 +305,7 @@ WARNING-style=template="admonitionblock",name="warning",caption="{warning_captio
|
|
311
305
|
CAUTION-style=template="admonitionblock",name="caution",caption="{caution_caption}"
|
312
306
|
|
313
307
|
# For use by custom filters.
|
308
|
+
# NOTE: No longer used, a styled listing block (blockdef-listing) is preferable.
|
314
309
|
[blockdef-filter]
|
315
310
|
delimiter=^~{4,}$
|
316
311
|
template=listingblock
|
@@ -341,12 +336,14 @@ delimiter=^\s*(?P<index>\d*)\. +(?P<text>.+)$
|
|
341
336
|
posattrs=style
|
342
337
|
type=numbered
|
343
338
|
tags=numbered
|
339
|
+
style=arabic
|
344
340
|
|
345
341
|
[listdef-numbered2]
|
346
|
-
delimiter=^\s*(?P<index>[.a-
|
342
|
+
delimiter=^\s*(?P<index>[.a-zA-Z]|[ivxIVX]+)\. +(?P<text>.+)$
|
347
343
|
posattrs=style
|
348
344
|
type=numbered
|
349
345
|
tags=numbered2
|
346
|
+
style=loweralpha
|
350
347
|
|
351
348
|
[listdef-labeled]
|
352
349
|
delimiter=^\s*(?P<label>.*\S)::(\s+(?P<text>.+))?$
|
data/asciidoc/asciidoc.py
CHANGED
@@ -7,9 +7,8 @@ under the terms of the GNU General Public License (GPL).
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
import sys, os, re, time, traceback, tempfile, subprocess, codecs, locale
|
10
|
-
from types import *
|
11
10
|
|
12
|
-
VERSION = '8.3.
|
11
|
+
VERSION = '8.3.3' # See CHANGLOG file for version history.
|
13
12
|
|
14
13
|
#---------------------------------------------------------------------------
|
15
14
|
# Program onstants.
|
@@ -110,22 +109,19 @@ def verbose(msg,linenos=True):
|
|
110
109
|
if config.verbose:
|
111
110
|
console(msg,linenos=linenos)
|
112
111
|
|
113
|
-
def warning(msg,linenos=True):
|
114
|
-
console(msg,'WARNING: ',linenos)
|
112
|
+
def warning(msg,linenos=True,offset=0):
|
113
|
+
console(msg,'WARNING: ',linenos,offset=offset)
|
115
114
|
document.has_warnings = True
|
116
115
|
|
117
116
|
def deprecated(msg, linenos=True):
|
118
117
|
console(msg, 'DEPRECATED: ', linenos)
|
119
118
|
|
120
|
-
def message(msg, prefix='', linenos=True, cursor=None):
|
121
|
-
"""
|
122
|
-
Return formatted message string. 'offset' is added to reported line number
|
123
|
-
for warnings emitted when reading ahead.
|
124
|
-
"""
|
119
|
+
def message(msg, prefix='', linenos=True, cursor=None, offset=0):
|
120
|
+
"""Return formatted message string."""
|
125
121
|
if linenos and reader.cursor:
|
126
122
|
if not cursor:
|
127
123
|
cursor = reader.cursor
|
128
|
-
prefix += '%s: line %d: ' % (os.path.basename(cursor[0]),cursor[1])
|
124
|
+
prefix += '%s: line %d: ' % (os.path.basename(cursor[0]),cursor[1]+offset)
|
129
125
|
return prefix + msg
|
130
126
|
|
131
127
|
def error(msg, cursor=None, halt=False):
|
@@ -141,8 +137,8 @@ def error(msg, cursor=None, halt=False):
|
|
141
137
|
console(msg,'ERROR: ',cursor=cursor)
|
142
138
|
document.has_errors = True
|
143
139
|
|
144
|
-
def console(msg, prefix='', linenos=True, cursor=None):
|
145
|
-
print_stderr(message(msg,prefix,linenos,cursor))
|
140
|
+
def console(msg, prefix='', linenos=True, cursor=None, offset=0):
|
141
|
+
print_stderr(message(msg,prefix,linenos,cursor,offset))
|
146
142
|
|
147
143
|
def file_in(fname, directory):
|
148
144
|
"""Return True if file fname resides inside directory."""
|
@@ -308,7 +304,7 @@ def parse_attributes(attrs,dict):
|
|
308
304
|
def f(*args,**keywords):
|
309
305
|
# Name and add aguments '1','2'... to keywords.
|
310
306
|
for i in range(len(args)):
|
311
|
-
if not
|
307
|
+
if not str(i+1) in keywords:
|
312
308
|
keywords[str(i+1)] = args[i]
|
313
309
|
return keywords
|
314
310
|
|
@@ -560,16 +556,28 @@ def update_attrs(attrs,dict):
|
|
560
556
|
raise EAsciiDoc,'illegal attribute name: %s' % k
|
561
557
|
attrs[k] = v
|
562
558
|
|
563
|
-
def filter_lines(filter_cmd, lines,
|
559
|
+
def filter_lines(filter_cmd, lines, attrs={}):
|
564
560
|
"""
|
565
561
|
Run 'lines' through the 'filter_cmd' shell command and return the result.
|
566
|
-
The '
|
562
|
+
The 'attrs' dictionary contains additional filter attributes.
|
567
563
|
"""
|
564
|
+
def findfilter(name,dir,filter):
|
565
|
+
"""Find filter file 'fname' with style name 'name' in directory
|
566
|
+
'dir'. Return found file path or None if not found."""
|
567
|
+
if name:
|
568
|
+
result = os.path.join(dir,'filters',name,filter)
|
569
|
+
if os.path.isfile(result):
|
570
|
+
return result
|
571
|
+
result = os.path.join(dir,'filters',filter)
|
572
|
+
if os.path.isfile(result):
|
573
|
+
return result
|
574
|
+
return None
|
575
|
+
|
568
576
|
# Return input lines if there's not filter.
|
569
577
|
if not filter_cmd or not filter_cmd.strip():
|
570
578
|
return lines
|
571
579
|
# Perform attributes substitution on the filter command.
|
572
|
-
s = subs_attrs(filter_cmd,
|
580
|
+
s = subs_attrs(filter_cmd, attrs)
|
573
581
|
if not s:
|
574
582
|
raise EAsciiDoc,'undefined filter attribute in command: %s' % filter_cmd
|
575
583
|
filter_cmd = s.strip()
|
@@ -583,33 +591,23 @@ def filter_lines(filter_cmd, lines, dict={}):
|
|
583
591
|
# Unquoted catch all.
|
584
592
|
mo = re.match(r'^(?P<cmd>\S+)(?P<tail>.*)$', filter_cmd)
|
585
593
|
cmd = mo.group('cmd').strip()
|
586
|
-
|
587
|
-
# sub-directories.
|
588
|
-
found = False
|
594
|
+
found = None
|
589
595
|
if not os.path.dirname(cmd):
|
590
|
-
#
|
591
|
-
|
596
|
+
# Filter command has no directory path so search filter directories.
|
597
|
+
filtername = attrs.get('style')
|
592
598
|
if USER_DIR:
|
593
|
-
|
594
|
-
if os.path.isfile(cmd2):
|
595
|
-
found = True
|
599
|
+
found = findfilter(filtername, USER_DIR, cmd)
|
596
600
|
if not found:
|
597
|
-
|
598
|
-
if os.path.isfile(cmd2):
|
599
|
-
found = True
|
601
|
+
found = findfilter(filtername, CONF_DIR, cmd)
|
600
602
|
if not found:
|
601
|
-
|
602
|
-
if os.path.isfile(cmd2):
|
603
|
-
found = True
|
604
|
-
if found:
|
605
|
-
cmd = cmd2
|
603
|
+
found = findfilter(filtername, APP_DIR, cmd)
|
606
604
|
else:
|
607
605
|
if os.path.isfile(cmd):
|
608
|
-
found =
|
606
|
+
found = cmd
|
609
607
|
else:
|
610
608
|
warning('filter not found: %s' % cmd)
|
611
609
|
if found:
|
612
|
-
filter_cmd = '"' +
|
610
|
+
filter_cmd = '"' + found + '"' + mo.group('tail')
|
613
611
|
if sys.platform == 'win32':
|
614
612
|
# Windows doesn't like running scripts directly so explicitly
|
615
613
|
# specify interpreter.
|
@@ -743,7 +741,7 @@ def subs_attrs(lines, dictionary=None):
|
|
743
741
|
if n == 0: break
|
744
742
|
return result
|
745
743
|
|
746
|
-
if
|
744
|
+
if type(lines) == str:
|
747
745
|
string_result = True
|
748
746
|
lines = [lines]
|
749
747
|
else:
|
@@ -929,6 +927,7 @@ class Lex:
|
|
929
927
|
prev_cursor = None
|
930
928
|
def __init__(self):
|
931
929
|
raise AssertionError,'no class instances allowed'
|
930
|
+
@staticmethod
|
932
931
|
def next():
|
933
932
|
"""Returns class of next element on the input (None if EOF). The
|
934
933
|
reader is assumed to be at the first line following a previous element,
|
@@ -981,8 +980,8 @@ class Lex:
|
|
981
980
|
Lex.prev_cursor = reader.cursor
|
982
981
|
Lex.prev_element = result
|
983
982
|
return result
|
984
|
-
next = staticmethod(next)
|
985
983
|
|
984
|
+
@staticmethod
|
986
985
|
def subs_1(s,options):
|
987
986
|
"""Perform substitution specified in 'options' (in 'options' order) on
|
988
987
|
Does not process 'attributes' substitutions."""
|
@@ -1011,8 +1010,8 @@ class Lex:
|
|
1011
1010
|
if not result:
|
1012
1011
|
break
|
1013
1012
|
return result
|
1014
|
-
subs_1 = staticmethod(subs_1)
|
1015
1013
|
|
1014
|
+
@staticmethod
|
1016
1015
|
def subs(lines,options):
|
1017
1016
|
"""Perform inline processing specified by 'options' (in 'options'
|
1018
1017
|
order) on sequence of 'lines'."""
|
@@ -1040,8 +1039,8 @@ class Lex:
|
|
1040
1039
|
if 'macros' in options:
|
1041
1040
|
para = macros.restore_passthroughs(para)
|
1042
1041
|
return para.splitlines()
|
1043
|
-
subs = staticmethod(subs)
|
1044
1042
|
|
1043
|
+
@staticmethod
|
1045
1044
|
def set_margin(lines, margin=0):
|
1046
1045
|
"""Utility routine that sets the left margin to 'margin' space in a
|
1047
1046
|
block of non-blank lines."""
|
@@ -1055,7 +1054,6 @@ class Lex:
|
|
1055
1054
|
for i in range(len(lines)):
|
1056
1055
|
lines[i] = ' '*margin + lines[i][width:]
|
1057
1056
|
return lines
|
1058
|
-
set_margin = staticmethod(set_margin)
|
1059
1057
|
|
1060
1058
|
#---------------------------------------------------------------------------
|
1061
1059
|
# Document element classes parse AsciiDoc reader input and write DocBook writer
|
@@ -1167,7 +1165,7 @@ class Document:
|
|
1167
1165
|
error('SYNOPSIS section expected')
|
1168
1166
|
else:
|
1169
1167
|
Title.translate()
|
1170
|
-
if Title.attributes['title'].upper()
|
1168
|
+
if Title.attributes['title'].upper() != 'SYNOPSIS':
|
1171
1169
|
error('second section must be named SYNOPSIS')
|
1172
1170
|
if Title.level != 1:
|
1173
1171
|
error('SYNOPSIS section title must be at level 1')
|
@@ -1272,6 +1270,7 @@ class Header:
|
|
1272
1270
|
"""Static methods and attributes only."""
|
1273
1271
|
def __init__(self):
|
1274
1272
|
raise AssertionError,'no class instances allowed'
|
1273
|
+
@staticmethod
|
1275
1274
|
def translate():
|
1276
1275
|
assert Lex.next() is Title and Title.level == 0
|
1277
1276
|
Title.translate()
|
@@ -1324,7 +1323,7 @@ class Header:
|
|
1324
1323
|
error('NAME section expected')
|
1325
1324
|
else:
|
1326
1325
|
Title.translate()
|
1327
|
-
if Title.attributes['title'].upper()
|
1326
|
+
if Title.attributes['title'].upper() != 'NAME':
|
1328
1327
|
error('first section must be named NAME')
|
1329
1328
|
if Title.level != 1:
|
1330
1329
|
error('NAME section title must be at level 1')
|
@@ -1338,9 +1337,6 @@ class Header:
|
|
1338
1337
|
attrs['manname'] = mo.group('manname').strip()
|
1339
1338
|
attrs['manpurpose'] = mo.group('manpurpose').strip()
|
1340
1339
|
document.process_author_names()
|
1341
|
-
if document.backend == 'linuxdoc' and not attrs.has_key('author'):
|
1342
|
-
warning('linuxdoc requires author name')
|
1343
|
-
translate = staticmethod(translate)
|
1344
1340
|
|
1345
1341
|
class AttributeEntry:
|
1346
1342
|
"""Static methods and attributes only."""
|
@@ -1351,6 +1347,7 @@ class AttributeEntry:
|
|
1351
1347
|
value = None
|
1352
1348
|
def __init__(self):
|
1353
1349
|
raise AssertionError,'no class instances allowed'
|
1350
|
+
@staticmethod
|
1354
1351
|
def isnext():
|
1355
1352
|
result = False # Assume not next.
|
1356
1353
|
if not AttributeEntry.pattern:
|
@@ -1377,7 +1374,7 @@ class AttributeEntry:
|
|
1377
1374
|
AttributeEntry.value = AttributeEntry.value.strip()
|
1378
1375
|
result = True
|
1379
1376
|
return result
|
1380
|
-
|
1377
|
+
@staticmethod
|
1381
1378
|
def translate():
|
1382
1379
|
assert Lex.next() is AttributeEntry
|
1383
1380
|
attr = AttributeEntry # Alias for brevity.
|
@@ -1411,12 +1408,11 @@ class AttributeEntry:
|
|
1411
1408
|
document.attributes[attr.name] = attr.value
|
1412
1409
|
elif attr.name in document.attributes:
|
1413
1410
|
del document.attributes[attr.name]
|
1414
|
-
|
1411
|
+
@staticmethod
|
1415
1412
|
def translate_all():
|
1416
1413
|
""" Process all contiguous attribute lines on reader."""
|
1417
1414
|
while AttributeEntry.isnext():
|
1418
1415
|
AttributeEntry.translate()
|
1419
|
-
translate_all = staticmethod(translate_all)
|
1420
1416
|
|
1421
1417
|
class AttributeList:
|
1422
1418
|
"""Static methods and attributes only."""
|
@@ -1425,10 +1421,11 @@ class AttributeList:
|
|
1425
1421
|
attrs = {}
|
1426
1422
|
def __init__(self):
|
1427
1423
|
raise AssertionError,'no class instances allowed'
|
1424
|
+
@staticmethod
|
1428
1425
|
def isnext():
|
1429
1426
|
result = False # Assume not next.
|
1430
1427
|
if not AttributeList.pattern:
|
1431
|
-
if not
|
1428
|
+
if not 'attributelist-pattern' in document.attributes:
|
1432
1429
|
error("[attributes] missing 'attributelist-pattern' entry")
|
1433
1430
|
AttributeList.pattern = document.attributes['attributelist-pattern']
|
1434
1431
|
line = reader.read_next()
|
@@ -1438,7 +1435,7 @@ class AttributeList:
|
|
1438
1435
|
AttributeList.match = mo
|
1439
1436
|
result = True
|
1440
1437
|
return result
|
1441
|
-
|
1438
|
+
@staticmethod
|
1442
1439
|
def translate():
|
1443
1440
|
assert Lex.next() is AttributeList
|
1444
1441
|
reader.read() # Discard attribute list from reader.
|
@@ -1451,7 +1448,7 @@ class AttributeList:
|
|
1451
1448
|
parse_attributes(v, AttributeList.attrs)
|
1452
1449
|
else:
|
1453
1450
|
AttributeList.attrs[k] = v
|
1454
|
-
|
1451
|
+
@staticmethod
|
1455
1452
|
def consume(d):
|
1456
1453
|
"""Add attribute list to the dictionary 'd' and reset the
|
1457
1454
|
list."""
|
@@ -1463,7 +1460,6 @@ class AttributeList:
|
|
1463
1460
|
options = parse_options(d['options'], (), 'illegal option name')
|
1464
1461
|
for option in options:
|
1465
1462
|
d[option+'-option'] = ''
|
1466
|
-
consume = staticmethod(consume)
|
1467
1463
|
|
1468
1464
|
class BlockTitle:
|
1469
1465
|
"""Static methods and attributes only."""
|
@@ -1471,6 +1467,7 @@ class BlockTitle:
|
|
1471
1467
|
pattern = None
|
1472
1468
|
def __init__(self):
|
1473
1469
|
raise AssertionError,'no class instances allowed'
|
1470
|
+
@staticmethod
|
1474
1471
|
def isnext():
|
1475
1472
|
result = False # Assume not next.
|
1476
1473
|
line = reader.read_next()
|
@@ -1480,7 +1477,7 @@ class BlockTitle:
|
|
1480
1477
|
BlockTitle.title = mo.group('title')
|
1481
1478
|
result = True
|
1482
1479
|
return result
|
1483
|
-
|
1480
|
+
@staticmethod
|
1484
1481
|
def translate():
|
1485
1482
|
assert Lex.next() is BlockTitle
|
1486
1483
|
reader.read() # Discard title from reader.
|
@@ -1492,13 +1489,12 @@ class BlockTitle:
|
|
1492
1489
|
if not s:
|
1493
1490
|
warning('blank block title')
|
1494
1491
|
BlockTitle.title = s
|
1495
|
-
|
1492
|
+
@staticmethod
|
1496
1493
|
def consume(d):
|
1497
1494
|
"""If there is a title add it to dictionary 'd' then reset title."""
|
1498
1495
|
if BlockTitle.title:
|
1499
1496
|
d['title'] = BlockTitle.title
|
1500
1497
|
BlockTitle.title = None
|
1501
|
-
consume = staticmethod(consume)
|
1502
1498
|
|
1503
1499
|
class Title:
|
1504
1500
|
"""Processes Header and Section titles. Static methods and attributes
|
@@ -1515,6 +1511,7 @@ class Title:
|
|
1515
1511
|
linecount = None # Number of lines in title (1 or 2).
|
1516
1512
|
def __init__(self):
|
1517
1513
|
raise AssertionError,'no class instances allowed'
|
1514
|
+
@staticmethod
|
1518
1515
|
def translate():
|
1519
1516
|
"""Parse the Title.attributes and Title.level from the reader. The
|
1520
1517
|
real work has already been done by parse()."""
|
@@ -1531,11 +1528,11 @@ class Title:
|
|
1531
1528
|
if not s:
|
1532
1529
|
warning('blank section title')
|
1533
1530
|
Title.attributes['title'] = s
|
1534
|
-
|
1531
|
+
@staticmethod
|
1535
1532
|
def isnext():
|
1536
1533
|
lines = reader.read_ahead(2)
|
1537
1534
|
return Title.parse(lines)
|
1538
|
-
|
1535
|
+
@staticmethod
|
1539
1536
|
def parse(lines):
|
1540
1537
|
"""Parse title at start of lines tuple."""
|
1541
1538
|
if len(lines) == 0: return False
|
@@ -1544,7 +1541,7 @@ class Title:
|
|
1544
1541
|
result = False
|
1545
1542
|
for level in range(len(Title.underlines)):
|
1546
1543
|
k = 'sect%s' % level
|
1547
|
-
if Title.dump_dict
|
1544
|
+
if k in Title.dump_dict:
|
1548
1545
|
mo = re.match(Title.dump_dict[k], lines[0])
|
1549
1546
|
if mo:
|
1550
1547
|
Title.attributes = mo.groupdict()
|
@@ -1578,16 +1575,16 @@ class Title:
|
|
1578
1575
|
result = True
|
1579
1576
|
# Check for expected pattern match groups.
|
1580
1577
|
if result:
|
1581
|
-
if not Title.attributes
|
1578
|
+
if not 'title' in Title.attributes:
|
1582
1579
|
warning('[titles] entry has no <title> group')
|
1583
1580
|
Title.attributes['title'] = lines[0]
|
1584
1581
|
for k,v in Title.attributes.items():
|
1585
1582
|
if v is None: del Title.attributes[k]
|
1586
1583
|
return result
|
1587
|
-
|
1584
|
+
@staticmethod
|
1588
1585
|
def load(entries):
|
1589
1586
|
"""Load and validate [titles] section entries dictionary."""
|
1590
|
-
if
|
1587
|
+
if 'underlines' in entries:
|
1591
1588
|
errmsg = 'malformed [titles] underlines entry'
|
1592
1589
|
try:
|
1593
1590
|
underlines = parse_list(entries['underlines'])
|
@@ -1600,17 +1597,17 @@ class Title:
|
|
1600
1597
|
raise EAsciiDoc,errmsg
|
1601
1598
|
Title.underlines = tuple(underlines)
|
1602
1599
|
Title.dump_dict['underlines'] = entries['underlines']
|
1603
|
-
if
|
1600
|
+
if 'subs' in entries:
|
1604
1601
|
Title.subs = parse_options(entries['subs'], SUBS_OPTIONS,
|
1605
1602
|
'illegal [titles] subs entry')
|
1606
1603
|
Title.dump_dict['subs'] = entries['subs']
|
1607
|
-
if
|
1604
|
+
if 'sectiontitle' in entries:
|
1608
1605
|
pat = entries['sectiontitle']
|
1609
1606
|
if not pat or not is_regexp(pat):
|
1610
1607
|
raise EAsciiDoc,'malformed [titles] sectiontitle entry'
|
1611
1608
|
Title.pattern = pat
|
1612
1609
|
Title.dump_dict['sectiontitle'] = pat
|
1613
|
-
if
|
1610
|
+
if 'blocktitle' in entries:
|
1614
1611
|
pat = entries['blocktitle']
|
1615
1612
|
if not pat or not is_regexp(pat):
|
1616
1613
|
raise EAsciiDoc,'malformed [titles] blocktitle entry'
|
@@ -1618,7 +1615,7 @@ class Title:
|
|
1618
1615
|
Title.dump_dict['blocktitle'] = pat
|
1619
1616
|
# Load single-line title patterns.
|
1620
1617
|
for k in ('sect0','sect1','sect2','sect3','sect4'):
|
1621
|
-
if entries
|
1618
|
+
if k in entries:
|
1622
1619
|
pat = entries[k]
|
1623
1620
|
if not pat or not is_regexp(pat):
|
1624
1621
|
raise EAsciiDoc,'malformed [titles] %s entry' % k
|
@@ -1626,10 +1623,10 @@ class Title:
|
|
1626
1623
|
# TODO: Check we have either a Title.pattern or at least one
|
1627
1624
|
# single-line title pattern -- can this be done here or do we need
|
1628
1625
|
# check routine like the other block checkers?
|
1629
|
-
|
1626
|
+
@staticmethod
|
1630
1627
|
def dump():
|
1631
1628
|
dump_section('titles',Title.dump_dict)
|
1632
|
-
|
1629
|
+
@staticmethod
|
1633
1630
|
def setsectname():
|
1634
1631
|
"""Set Title section name. First search for section title in
|
1635
1632
|
[specialsections], if not found use default 'sect<level>' name."""
|
@@ -1645,7 +1642,7 @@ class Title:
|
|
1645
1642
|
break
|
1646
1643
|
else:
|
1647
1644
|
Title.sectname = 'sect%d' % Title.level
|
1648
|
-
|
1645
|
+
@staticmethod
|
1649
1646
|
def getnumber(level):
|
1650
1647
|
"""Return next section number at section 'level' formatted like
|
1651
1648
|
1.2.3.4."""
|
@@ -1663,7 +1660,6 @@ class Title:
|
|
1663
1660
|
# Reset unprocessed section levels.
|
1664
1661
|
Title.section_numbers[l] = 0
|
1665
1662
|
return number
|
1666
|
-
getnumber = staticmethod(getnumber)
|
1667
1663
|
|
1668
1664
|
|
1669
1665
|
class Section:
|
@@ -1672,16 +1668,17 @@ class Section:
|
|
1672
1668
|
ids = [] # List of already used ids.
|
1673
1669
|
def __init__(self):
|
1674
1670
|
raise AssertionError,'no class instances allowed'
|
1671
|
+
@staticmethod
|
1675
1672
|
def savetag(level,etag):
|
1676
1673
|
"""Save section end."""
|
1677
1674
|
Section.endtags.append((level,etag))
|
1678
|
-
|
1675
|
+
@staticmethod
|
1679
1676
|
def setlevel(level):
|
1680
1677
|
"""Set document level and write open section close tags up to level."""
|
1681
1678
|
while Section.endtags and Section.endtags[-1][0] >= level:
|
1682
1679
|
writer.write(Section.endtags.pop()[1])
|
1683
1680
|
document.level = level
|
1684
|
-
|
1681
|
+
@staticmethod
|
1685
1682
|
def gen_id(title):
|
1686
1683
|
"""
|
1687
1684
|
The normalized value of the id attribute is an NCName according to
|
@@ -1708,7 +1705,7 @@ class Section:
|
|
1708
1705
|
else:
|
1709
1706
|
ident = base_ident
|
1710
1707
|
i += 1
|
1711
|
-
|
1708
|
+
@staticmethod
|
1712
1709
|
def translate():
|
1713
1710
|
assert Lex.next() is Title
|
1714
1711
|
prev_sectname = Title.sectname
|
@@ -1743,17 +1740,13 @@ class Section:
|
|
1743
1740
|
Section.savetag(Title.level,etag)
|
1744
1741
|
writer.write(stag)
|
1745
1742
|
Section.translate_body()
|
1746
|
-
|
1743
|
+
@staticmethod
|
1747
1744
|
def translate_body(terminator=Title):
|
1748
1745
|
isempty = True
|
1749
1746
|
next = Lex.next()
|
1750
1747
|
while next and next is not terminator:
|
1751
1748
|
if next is Title and isinstance(terminator,DelimitedBlock):
|
1752
1749
|
error('title not permitted in sidebar body')
|
1753
|
-
if document.backend == 'linuxdoc' \
|
1754
|
-
and document.level == 0 \
|
1755
|
-
and not isinstance(next,Paragraph):
|
1756
|
-
warning('only paragraphs are permitted in linuxdoc synopsis')
|
1757
1750
|
next.translate()
|
1758
1751
|
next = Lex.next()
|
1759
1752
|
isempty = False
|
@@ -1764,7 +1757,6 @@ class Section:
|
|
1764
1757
|
if isempty:
|
1765
1758
|
if document.backend == 'docbook' and Title.sectname != 'sect-index':
|
1766
1759
|
error('empty section is not valid')
|
1767
|
-
translate_body = staticmethod(translate_body)
|
1768
1760
|
|
1769
1761
|
class AbstractBlock:
|
1770
1762
|
def __init__(self):
|
@@ -1930,7 +1922,7 @@ class AbstractBlock:
|
|
1930
1922
|
if self.style:
|
1931
1923
|
if not is_name(self.style):
|
1932
1924
|
raise EAsciiDoc, 'illegal style name: %s' % self.style
|
1933
|
-
if not self.
|
1925
|
+
if not self.style in self.styles:
|
1934
1926
|
if not isinstance(self,List): # Lists don't have templates.
|
1935
1927
|
warning('[%s] \'%s\' style not in %s' % (
|
1936
1928
|
self.name,self.style,self.styles.keys()))
|
@@ -1938,7 +1930,7 @@ class AbstractBlock:
|
|
1938
1930
|
all_styles_have_template = True
|
1939
1931
|
for k,v in self.styles.items():
|
1940
1932
|
t = v.get('template')
|
1941
|
-
if t and not config.sections
|
1933
|
+
if t and not t in config.sections:
|
1942
1934
|
warning('[%s] missing template section' % t)
|
1943
1935
|
if not t:
|
1944
1936
|
all_styles_have_template = False
|
@@ -1946,7 +1938,7 @@ class AbstractBlock:
|
|
1946
1938
|
# styles have templates.
|
1947
1939
|
if self.is_conf_entry('template') and not 'skip' in self.options:
|
1948
1940
|
if self.template:
|
1949
|
-
if not config.sections
|
1941
|
+
if not self.template in config.sections:
|
1950
1942
|
warning('[%s] missing template section' % self.template)
|
1951
1943
|
elif not all_styles_have_template:
|
1952
1944
|
if not isinstance(self,List): # Lists don't have templates.
|
@@ -2003,6 +1995,9 @@ class AbstractBlock:
|
|
2003
1995
|
|
2004
1996
|
params = list(self.PARAM_NAMES) + params
|
2005
1997
|
self.attributes = {}
|
1998
|
+
if self.style:
|
1999
|
+
# If a default style is defined make it available in the template.
|
2000
|
+
self.attributes['style'] = self.style
|
2006
2001
|
self.attributes.update(attrs)
|
2007
2002
|
# Calculate dynamic block parameters.
|
2008
2003
|
# Start with configuration file defaults.
|
@@ -2020,19 +2015,19 @@ class AbstractBlock:
|
|
2020
2015
|
if style:
|
2021
2016
|
if not is_name(style):
|
2022
2017
|
raise EAsciiDoc, 'illegal style name: %s' % style
|
2023
|
-
if self.styles
|
2018
|
+
if style in self.styles:
|
2024
2019
|
self.attributes['style'] = style
|
2025
2020
|
for k,v in self.styles[style].items():
|
2026
2021
|
if k == 'posattrs':
|
2027
2022
|
posattrs = v
|
2028
2023
|
elif k in params:
|
2029
2024
|
self.parameters[k] = v
|
2030
|
-
elif not self.attributes
|
2025
|
+
elif not k in self.attributes:
|
2031
2026
|
# Style attributes don't take precedence over explicit.
|
2032
2027
|
self.attributes[k] = v
|
2033
2028
|
# Set named positional attributes.
|
2034
2029
|
for i,v in enumerate(posattrs):
|
2035
|
-
if
|
2030
|
+
if str(i+1) in self.attributes:
|
2036
2031
|
self.attributes[v] = self.attributes[str(i+1)]
|
2037
2032
|
# Override config and style attributes with attribute list attributes.
|
2038
2033
|
self.update_parameters(attrs)
|
@@ -2102,8 +2097,8 @@ class Paragraph(AbstractBlock):
|
|
2102
2097
|
return result
|
2103
2098
|
def translate(self):
|
2104
2099
|
AbstractBlock.translate(self)
|
2105
|
-
attrs =
|
2106
|
-
attrs
|
2100
|
+
attrs = self.mo.groupdict().copy()
|
2101
|
+
if 'text' in attrs: del attrs['text']
|
2107
2102
|
BlockTitle.consume(attrs)
|
2108
2103
|
AttributeList.consume(attrs)
|
2109
2104
|
self.merge_attributes(attrs)
|
@@ -2153,14 +2148,15 @@ class List(AbstractBlock):
|
|
2153
2148
|
self.PARAM_NAMES += ('tags',)
|
2154
2149
|
# tabledef conf file parameters.
|
2155
2150
|
self.type=None
|
2156
|
-
self.tags=None
|
2151
|
+
self.tags=None # Name of listtags-<tags> conf section.
|
2157
2152
|
# Calculated parameters.
|
2158
2153
|
self.tag=None # Current tags AttrDict.
|
2159
2154
|
self.label=None # List item label (labeled lists).
|
2160
2155
|
self.text=None # Text in first line of list item.
|
2161
2156
|
self.index=None # Matched delimiter 'index' group (numbered lists).
|
2162
|
-
self.type=None # List type.
|
2157
|
+
self.type=None # List type ('numbered','bulleted','labeled').
|
2163
2158
|
self.listindex=None # Current list index (1..)
|
2159
|
+
self.number_style=None # Numbered list number style ('arabic'..)
|
2164
2160
|
def load(self,name,entries):
|
2165
2161
|
AbstractBlock.load(self,name,entries)
|
2166
2162
|
def dump(self):
|
@@ -2202,9 +2198,6 @@ class List(AbstractBlock):
|
|
2202
2198
|
def iscontinued(self):
|
2203
2199
|
if reader.read_next() == '+':
|
2204
2200
|
reader.read() # Discard.
|
2205
|
-
# Allow attribute list to precede continued list item element.
|
2206
|
-
while Lex.next() is AttributeList:
|
2207
|
-
Lex.next().translate()
|
2208
2201
|
return True
|
2209
2202
|
else:
|
2210
2203
|
return False
|
@@ -2233,6 +2226,7 @@ class List(AbstractBlock):
|
|
2233
2226
|
lists.delimiter + r'|^\+$|^$|' + blocks.delimiter
|
2234
2227
|
+ r'|' + tables.delimiter
|
2235
2228
|
+ r'|' + tables_OLD.delimiter
|
2229
|
+
+ r'|' + AttributeList.pattern
|
2236
2230
|
)
|
2237
2231
|
if self.text is not None:
|
2238
2232
|
text = [self.text] + list(text)
|
@@ -2240,6 +2234,9 @@ class List(AbstractBlock):
|
|
2240
2234
|
writer.write_tag(self.tag.text, text, self.presubs, self.attributes)
|
2241
2235
|
continued = self.iscontinued()
|
2242
2236
|
while True:
|
2237
|
+
# Allow attribute list to precede continued list item element.
|
2238
|
+
while Lex.next() is AttributeList:
|
2239
|
+
Lex.next().translate()
|
2243
2240
|
next = Lex.next()
|
2244
2241
|
if next in lists.open:
|
2245
2242
|
break
|
@@ -2267,11 +2264,16 @@ class List(AbstractBlock):
|
|
2267
2264
|
lists.delimiter + r'|^$|' + blocks.delimiter
|
2268
2265
|
+ r'|' + tables.delimiter
|
2269
2266
|
+ r'|' + tables_OLD.delimiter
|
2267
|
+
+ r'|' + AttributeList.pattern
|
2270
2268
|
)
|
2271
2269
|
if self.text is not None:
|
2272
2270
|
text = [self.text] + list(text)
|
2273
|
-
|
2271
|
+
if text:
|
2272
|
+
writer.write_tag(self.tag.text, text, self.presubs, self.attributes)
|
2274
2273
|
while True:
|
2274
|
+
# Allow attribute list to precede continued list item element.
|
2275
|
+
while Lex.next() is AttributeList:
|
2276
|
+
Lex.next().translate()
|
2275
2277
|
next = Lex.next()
|
2276
2278
|
if next in lists.open:
|
2277
2279
|
break
|
@@ -2288,21 +2290,63 @@ class List(AbstractBlock):
|
|
2288
2290
|
else:
|
2289
2291
|
break
|
2290
2292
|
writer.write(itemtag[1])
|
2293
|
+
|
2294
|
+
@staticmethod
|
2295
|
+
def parse_index(index):
|
2296
|
+
"""Parse the numbered list item index and return a (style,ordinal)
|
2297
|
+
tuple. style in ('arabic'...); ordinal in (1...).
|
2298
|
+
NOTE: 'i' and 'I' return (1,'lowerroman') and (1,'upperroman')."""
|
2299
|
+
def roman_to_int(roman):
|
2300
|
+
roman = roman.lower()
|
2301
|
+
digits = {'i':1,'v':5,'x':10}
|
2302
|
+
result = 0
|
2303
|
+
for i in range(len(roman)):
|
2304
|
+
digit = digits[roman[i]]
|
2305
|
+
# If next digit is larger this digit is negative.
|
2306
|
+
if i+1 < len(roman) and digits[roman[i+1]] > digit:
|
2307
|
+
result -= digit
|
2308
|
+
else:
|
2309
|
+
result += digit
|
2310
|
+
return result
|
2311
|
+
if re.match(r'^\d+$', index):
|
2312
|
+
style = 'arabic'
|
2313
|
+
ordinal = int(index)
|
2314
|
+
elif re.match(r'^[ivx]+$', index):
|
2315
|
+
style = 'lowerroman'
|
2316
|
+
ordinal = roman_to_int(index)
|
2317
|
+
elif re.match(r'^[IVX]+$', index):
|
2318
|
+
style = 'upperroman'
|
2319
|
+
ordinal = roman_to_int(index)
|
2320
|
+
elif re.match(r'^[a-z]$', index):
|
2321
|
+
style = 'loweralpha'
|
2322
|
+
ordinal = ord(index) - ord('a') + 1
|
2323
|
+
elif re.match(r'^[A-Z]$', index):
|
2324
|
+
style = 'upperalpha'
|
2325
|
+
ordinal = ord(index) - ord('A') + 1
|
2326
|
+
else:
|
2327
|
+
style = None
|
2328
|
+
ordinal = None
|
2329
|
+
return (style,ordinal)
|
2330
|
+
|
2291
2331
|
def check_index(self):
|
2292
|
-
""" Check calculated listindex (1,2,...) against the item
|
2293
|
-
document (self.index)
|
2332
|
+
""" Check calculated listindex (1,2,...) against the item number in the
|
2333
|
+
document (self.index) and check the number style is the same as
|
2334
|
+
the first item (self.number_style)."""
|
2294
2335
|
assert self.type in ('numbered','callout')
|
2295
2336
|
if self.index:
|
2296
|
-
|
2297
|
-
if
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2337
|
+
style,ordinal = self.parse_index(self.index)
|
2338
|
+
if style and self.number_style:
|
2339
|
+
if (self.index in 'ivx' and self.number_style == 'loweralpha' or
|
2340
|
+
self.index in 'IVX' and self.number_style == 'upperalpha'):
|
2341
|
+
# Sidestep possible i,v,x,I,V,X ambiguity.
|
2342
|
+
return
|
2343
|
+
if style != self.number_style:
|
2344
|
+
warning('list item style: expected %s got %s' %
|
2345
|
+
(self.number_style,style), offset=1)
|
2346
|
+
if ordinal != self.listindex:
|
2347
|
+
warning('list item index: expected %s got %s' %
|
2348
|
+
(self.listindex,ordinal), offset=1)
|
2349
|
+
|
2306
2350
|
def check_tags(self):
|
2307
2351
|
""" Check that all necessary tags are present. """
|
2308
2352
|
tags = set(Lists.TAGS)
|
@@ -2316,10 +2360,17 @@ class List(AbstractBlock):
|
|
2316
2360
|
if self.short_name() in ('bibliography','glossary','qanda'):
|
2317
2361
|
deprecated('old %s list syntax' % self.short_name())
|
2318
2362
|
lists.open.append(self)
|
2319
|
-
attrs =
|
2320
|
-
|
2363
|
+
attrs = self.mo.groupdict().copy()
|
2364
|
+
for k in ('label','text','index'):
|
2365
|
+
if k in attrs: del attrs[k]
|
2366
|
+
if self.index:
|
2367
|
+
# Set the numbering style from first list item.
|
2368
|
+
style = self.parse_index(self.index)[0]
|
2369
|
+
if style:
|
2370
|
+
attrs['style'] = style
|
2321
2371
|
BlockTitle.consume(attrs)
|
2322
2372
|
AttributeList.consume(attrs)
|
2373
|
+
self.number_style = attrs.get('style')
|
2323
2374
|
self.merge_attributes(attrs,['tags'])
|
2324
2375
|
self.tag = lists.tags[self.parameters.tags]
|
2325
2376
|
self.check_tags()
|
@@ -2380,7 +2431,7 @@ class Lists(AbstractBlocks):
|
|
2380
2431
|
mo = re.match(r'^listtags-(?P<name>\w+)$',section)
|
2381
2432
|
if mo:
|
2382
2433
|
name = mo.group('name')
|
2383
|
-
if self.tags
|
2434
|
+
if name in self.tags:
|
2384
2435
|
d = self.tags[name]
|
2385
2436
|
else:
|
2386
2437
|
d = AttrDict()
|
@@ -2904,7 +2955,7 @@ class Tables(AbstractBlocks):
|
|
2904
2955
|
mo = re.match(r'^tabletags-(?P<name>\w+)$',section)
|
2905
2956
|
if mo:
|
2906
2957
|
name = mo.group('name')
|
2907
|
-
if self.tags
|
2958
|
+
if name in self.tags:
|
2908
2959
|
d = self.tags[name]
|
2909
2960
|
else:
|
2910
2961
|
d = AttrDict()
|
@@ -2961,15 +3012,15 @@ class Tables(AbstractBlocks):
|
|
2961
3012
|
|
2962
3013
|
class Macros:
|
2963
3014
|
# Default system macro syntax.
|
2964
|
-
|
2965
|
-
|
3015
|
+
SYS_RE = r'(?u)^(?P<name>[\\]?\w(\w|-)*?)::(?P<target>\S*?)' + \
|
3016
|
+
r'(\[(?P<attrlist>.*?)\])$'
|
2966
3017
|
def __init__(self):
|
2967
3018
|
self.macros = [] # List of Macros.
|
2968
3019
|
self.current = None # The last matched block macro.
|
2969
3020
|
self.passthroughs = []
|
2970
3021
|
# Initialize default system macro.
|
2971
3022
|
m = Macro()
|
2972
|
-
m.pattern = self.
|
3023
|
+
m.pattern = self.SYS_RE
|
2973
3024
|
m.prefix = '+'
|
2974
3025
|
m.reo = re.compile(m.pattern)
|
2975
3026
|
self.macros.append(m)
|
@@ -3060,7 +3111,7 @@ class Macro:
|
|
3060
3111
|
self.name = '' # Conf file macro name (None if implicit).
|
3061
3112
|
self.prefix = '' # '' if inline, '+' if system, '#' if block.
|
3062
3113
|
self.reo = None # Compiled pattern re object.
|
3063
|
-
self.subslist =
|
3114
|
+
self.subslist = [] # Default subs for macros passtext group.
|
3064
3115
|
def has_passthrough(self):
|
3065
3116
|
return self.pattern.find(r'(?P<passtext>') >= 0
|
3066
3117
|
def section_name(self,name=None):
|
@@ -3074,7 +3125,7 @@ class Macro:
|
|
3074
3125
|
suffix = '-blockmacro'
|
3075
3126
|
else:
|
3076
3127
|
suffix = '-inlinemacro'
|
3077
|
-
if config.sections
|
3128
|
+
if name+suffix in config.sections:
|
3078
3129
|
return name+suffix
|
3079
3130
|
else:
|
3080
3131
|
warning('missing macro section: [%s]' % (name+suffix))
|
@@ -3112,7 +3163,7 @@ class Macro:
|
|
3112
3163
|
self.reo = re.compile(pattern)
|
3113
3164
|
self.prefix = prefix
|
3114
3165
|
self.name = name
|
3115
|
-
self.subslist = subslist
|
3166
|
+
self.subslist = subslist or []
|
3116
3167
|
|
3117
3168
|
def subs(self,text):
|
3118
3169
|
def subs_func(mo):
|
@@ -3129,7 +3180,7 @@ class Macro:
|
|
3129
3180
|
if self.name:
|
3130
3181
|
name = self.name
|
3131
3182
|
else:
|
3132
|
-
if not
|
3183
|
+
if not 'name' in d:
|
3133
3184
|
warning('missing macro name group: %s' % mo.re.pattern)
|
3134
3185
|
return ''
|
3135
3186
|
name = d['name']
|
@@ -3142,7 +3193,7 @@ class Macro:
|
|
3142
3193
|
AttributeList.consume(d)
|
3143
3194
|
BlockTitle.consume(d)
|
3144
3195
|
# Parse macro attributes.
|
3145
|
-
if
|
3196
|
+
if 'attrlist' in d:
|
3146
3197
|
if d['attrlist'] in (None,''):
|
3147
3198
|
del d['attrlist']
|
3148
3199
|
else:
|
@@ -3160,8 +3211,8 @@ class Macro:
|
|
3160
3211
|
listindex =int(d['index'])
|
3161
3212
|
d['coid'] = calloutmap.add(listindex)
|
3162
3213
|
# Unescape special characters in LaTeX target file names.
|
3163
|
-
if document.backend == 'latex' and
|
3164
|
-
if not
|
3214
|
+
if document.backend == 'latex' and 'target' in d and d['target']:
|
3215
|
+
if not '0' in d:
|
3165
3216
|
d['0'] = d['target']
|
3166
3217
|
d['target']= config.subs_specialchars_reverse(d['target'])
|
3167
3218
|
# BUG: We've already done attribute substitution on the macro which
|
@@ -3217,7 +3268,7 @@ class Macro:
|
|
3217
3268
|
if mo.group()[0] == '\\':
|
3218
3269
|
return mo.group()
|
3219
3270
|
d = mo.groupdict()
|
3220
|
-
if not
|
3271
|
+
if not 'passtext' in d:
|
3221
3272
|
warning('passthrough macro %s: missing passtext group' %
|
3222
3273
|
d.get('name',''))
|
3223
3274
|
return mo.group()
|
@@ -3261,17 +3312,17 @@ class CalloutMap:
|
|
3261
3312
|
# Add next callout index to listindex map entry. Return the callout id.
|
3262
3313
|
self.calloutindex += 1
|
3263
3314
|
# Append the coindex to a list in the comap dictionary.
|
3264
|
-
if not self.comap
|
3315
|
+
if not listindex in self.comap:
|
3265
3316
|
self.comap[listindex] = [self.calloutindex]
|
3266
3317
|
else:
|
3267
3318
|
self.comap[listindex].append(self.calloutindex)
|
3268
3319
|
return self.calloutid(self.listnumber, self.calloutindex)
|
3320
|
+
@staticmethod
|
3269
3321
|
def calloutid(listnumber,calloutindex):
|
3270
3322
|
return 'CO%d-%d' % (listnumber,calloutindex)
|
3271
|
-
calloutid = staticmethod(calloutid)
|
3272
3323
|
def calloutids(self,listindex):
|
3273
3324
|
# Retieve list of callout indexes that refer to listindex.
|
3274
|
-
if self.comap
|
3325
|
+
if listindex in self.comap:
|
3275
3326
|
result = ''
|
3276
3327
|
for coindex in self.comap[listindex]:
|
3277
3328
|
result += ' ' + self.calloutid(self.listnumber,coindex)
|
@@ -3385,13 +3436,13 @@ class Reader1:
|
|
3385
3436
|
assign(parent,self)
|
3386
3437
|
self.parent = parent
|
3387
3438
|
# Set attributes in child.
|
3388
|
-
if
|
3439
|
+
if 'tabsize' in attrs:
|
3389
3440
|
self.tabsize = int(validate(attrs['tabsize'],
|
3390
3441
|
'int($)>=0',
|
3391
3442
|
'illegal include macro tabsize argument'))
|
3392
3443
|
else:
|
3393
3444
|
self.tabsize = config.tabsize
|
3394
|
-
if
|
3445
|
+
if 'depth' in attrs:
|
3395
3446
|
attrs['depth'] = int(validate(attrs['depth'],
|
3396
3447
|
'int($)>=1',
|
3397
3448
|
'illegal include macro depth argument'))
|
@@ -3498,6 +3549,10 @@ class Reader(Reader1):
|
|
3498
3549
|
if s is not None:
|
3499
3550
|
self.cursor[2] = s # So we don't re-evaluate.
|
3500
3551
|
result = s
|
3552
|
+
if result:
|
3553
|
+
# Unescape escaped system macros.
|
3554
|
+
if macros.match('+',r'\\eval|\\sys|\\sys2|\\ifdef|\\ifndef|\\endif|\\include|\\include1',result):
|
3555
|
+
result = result[1:]
|
3501
3556
|
return result
|
3502
3557
|
def eof(self):
|
3503
3558
|
return self.read_next() is None
|
@@ -3649,7 +3704,7 @@ def _subs_specialwords(mo):
|
|
3649
3704
|
Config.subs_specialwords()."""
|
3650
3705
|
word = mo.re.pattern # The special word.
|
3651
3706
|
template = config.specialwords[word] # The corresponding markup template.
|
3652
|
-
if not config.sections
|
3707
|
+
if not template in config.sections:
|
3653
3708
|
raise EAsciiDoc,'missing special word template [%s]' % template
|
3654
3709
|
if mo.group()[0] == '\\':
|
3655
3710
|
return mo.group()[1:] # Return escaped word.
|
@@ -3737,7 +3792,7 @@ class Config:
|
|
3737
3792
|
found = reo.findall(s)
|
3738
3793
|
if found:
|
3739
3794
|
if section: # Store previous section.
|
3740
|
-
if
|
3795
|
+
if section in sections \
|
3741
3796
|
and self.entries_section(section):
|
3742
3797
|
if ''.join(contents):
|
3743
3798
|
# Merge entries.
|
@@ -3751,7 +3806,7 @@ class Config:
|
|
3751
3806
|
else:
|
3752
3807
|
contents.append(s)
|
3753
3808
|
if section and contents: # Store last section.
|
3754
|
-
if
|
3809
|
+
if section in sections \
|
3755
3810
|
and self.entries_section(section):
|
3756
3811
|
if ''.join(contents):
|
3757
3812
|
# Merge entries.
|
@@ -3816,17 +3871,17 @@ class Config:
|
|
3816
3871
|
if lang:
|
3817
3872
|
conf = 'lang-' + lang + '.conf'
|
3818
3873
|
self.load_file(conf,dir)
|
3819
|
-
# Load
|
3820
|
-
|
3821
|
-
|
3822
|
-
for f in
|
3874
|
+
# Load filter .conf files.
|
3875
|
+
filtersdir = os.path.join(dir,'filters')
|
3876
|
+
for dirpath,dirnames,filenames in os.walk(filtersdir):
|
3877
|
+
for f in filenames:
|
3823
3878
|
if re.match(r'^.+\.conf$',f):
|
3824
|
-
self.load_file(f,
|
3879
|
+
self.load_file(f,dirpath)
|
3825
3880
|
|
3826
3881
|
def load_miscellaneous(self,d):
|
3827
3882
|
"""Set miscellaneous configuration entries from dictionary 'd'."""
|
3828
3883
|
def set_misc(name,rule='True',intval=False):
|
3829
|
-
if d
|
3884
|
+
if name in d:
|
3830
3885
|
errmsg = 'illegal [miscellaneous] %s entry' % name
|
3831
3886
|
if intval:
|
3832
3887
|
setattr(self, name, int(validate(d[name],rule,errmsg)))
|
@@ -3837,14 +3892,14 @@ class Config:
|
|
3837
3892
|
set_misc('pagewidth','int($)>0',intval=True)
|
3838
3893
|
set_misc('pageunits')
|
3839
3894
|
set_misc('outfilesuffix')
|
3840
|
-
if
|
3895
|
+
if 'newline' in d:
|
3841
3896
|
# Convert escape sequences to their character values.
|
3842
3897
|
self.newline = eval('"'+d['newline']+'"')
|
3843
|
-
if
|
3898
|
+
if 'subsnormal' in d:
|
3844
3899
|
self.subsnormal = parse_options(d['subsnormal'],SUBS_OPTIONS,
|
3845
3900
|
'illegal [%s] %s: %s' %
|
3846
3901
|
('miscellaneous','subsnormal',d['subsnormal']))
|
3847
|
-
if
|
3902
|
+
if 'subsverbatim' in d:
|
3848
3903
|
self.subsverbatim = parse_options(d['subsverbatim'],SUBS_OPTIONS,
|
3849
3904
|
'illegal [%s] %s: %s' %
|
3850
3905
|
('miscellaneous','subsverbatim',d['subsverbatim']))
|
@@ -3864,7 +3919,7 @@ class Config:
|
|
3864
3919
|
for macro in self.specialwords.values():
|
3865
3920
|
if not is_name(macro):
|
3866
3921
|
raise EAsciiDoc,'illegal special word name: %s' % macro
|
3867
|
-
if not self.sections
|
3922
|
+
if not macro in self.sections:
|
3868
3923
|
warning('missing special word macro: [%s]' % macro)
|
3869
3924
|
# Check all text quotes have a corresponding tag.
|
3870
3925
|
for q in self.quotes.keys():
|
@@ -3874,11 +3929,11 @@ class Config:
|
|
3874
3929
|
else:
|
3875
3930
|
if tag[0] == '#':
|
3876
3931
|
tag = tag[1:]
|
3877
|
-
if not self.tags
|
3932
|
+
if not tag in self.tags:
|
3878
3933
|
warning('[quotes] %s missing tag definition: %s' % (q,tag))
|
3879
3934
|
# Check all specialsections section names exist.
|
3880
3935
|
for k,v in self.specialsections.items():
|
3881
|
-
if not self.sections
|
3936
|
+
if not v in self.sections:
|
3882
3937
|
warning('[%s] missing specialsections section' % v)
|
3883
3938
|
paragraphs.validate()
|
3884
3939
|
lists.validate()
|
@@ -3920,7 +3975,7 @@ class Config:
|
|
3920
3975
|
dump_section('specialcharacters',self.specialchars)
|
3921
3976
|
d = {}
|
3922
3977
|
for k,v in self.specialwords.items():
|
3923
|
-
if d
|
3978
|
+
if v in d:
|
3924
3979
|
d[v] = '%s "%s"' % (d[v],k) # Append word list.
|
3925
3980
|
else:
|
3926
3981
|
d[v] = '"%s"' % k
|
@@ -3950,7 +4005,7 @@ class Config:
|
|
3950
4005
|
"""Section attribute substitution using attributes from
|
3951
4006
|
document.attributes and 'd'. Lines containing undefinded
|
3952
4007
|
attributes are deleted."""
|
3953
|
-
if self.sections
|
4008
|
+
if section in self.sections:
|
3954
4009
|
return subs_attrs(self.sections[section],d)
|
3955
4010
|
else:
|
3956
4011
|
warning('missing [%s] section' % section)
|
@@ -3962,7 +4017,7 @@ class Config:
|
|
3962
4017
|
parse_entries(self.sections.get('tags',()),d)
|
3963
4018
|
for k,v in d.items():
|
3964
4019
|
if v is None:
|
3965
|
-
if self.tags
|
4020
|
+
if k in self.tags:
|
3966
4021
|
del self.tags[k]
|
3967
4022
|
elif v == '':
|
3968
4023
|
self.tags[k] = (None,None)
|
@@ -3986,7 +4041,7 @@ class Config:
|
|
3986
4041
|
# split_tag() and would call subs_tag(). self.tags dictionary values
|
3987
4042
|
# would be strings not tuples.
|
3988
4043
|
|
3989
|
-
if not self.tags
|
4044
|
+
if not name in self.tags:
|
3990
4045
|
raise EAsciiDoc, 'missing tag: %s' % name
|
3991
4046
|
stag,etag = self.tags[name]
|
3992
4047
|
if d is not None:
|
@@ -4011,7 +4066,7 @@ class Config:
|
|
4011
4066
|
raise EAsciiDoc,'[specialsections] entry ' \
|
4012
4067
|
'is not a valid regular expression: %s' % pat
|
4013
4068
|
if sectname is None:
|
4014
|
-
if self.specialsections
|
4069
|
+
if pat in self.specialsections:
|
4015
4070
|
del self.specialsections[pat]
|
4016
4071
|
else:
|
4017
4072
|
self.specialsections[pat] = sectname
|
@@ -4025,18 +4080,18 @@ class Config:
|
|
4025
4080
|
raise EAsciiDoc,'[%s] entry in %s is not a valid' \
|
4026
4081
|
' regular expression: %s' % (sect,self.fname,pat)
|
4027
4082
|
|
4083
|
+
@staticmethod
|
4028
4084
|
def set_replacement(pat, rep, replacements):
|
4029
4085
|
"""Add pattern and replacement to replacements dictionary."""
|
4030
4086
|
pat = strip_quotes(pat)
|
4031
4087
|
if not is_regexp(pat):
|
4032
4088
|
return False
|
4033
4089
|
if rep is None:
|
4034
|
-
if replacements
|
4090
|
+
if pat in replacements:
|
4035
4091
|
del replacements[pat]
|
4036
4092
|
else:
|
4037
4093
|
replacements[pat] = strip_quotes(rep)
|
4038
4094
|
return True
|
4039
|
-
set_replacement = staticmethod(set_replacement)
|
4040
4095
|
|
4041
4096
|
def subs_replacements(self,s,sect='replacements'):
|
4042
4097
|
"""Substitute patterns from self.replacements in 's'."""
|
@@ -4104,7 +4159,7 @@ class Config:
|
|
4104
4159
|
mo = macros.match('+',r'template',line)
|
4105
4160
|
if mo:
|
4106
4161
|
s = mo.group('attrlist')
|
4107
|
-
if self.sections
|
4162
|
+
if s in self.sections:
|
4108
4163
|
result += self.sections[s]
|
4109
4164
|
else:
|
4110
4165
|
warning('missing [%s] section' % s)
|
@@ -4121,7 +4176,7 @@ class Config:
|
|
4121
4176
|
attributes plus 'd' attributes. Return tuple (stag,etag) containing
|
4122
4177
|
pre and post | placeholder tags."""
|
4123
4178
|
assert section is not None
|
4124
|
-
if self.sections
|
4179
|
+
if section in self.sections:
|
4125
4180
|
body = self.sections[section]
|
4126
4181
|
else:
|
4127
4182
|
warning('missing [%s] section' % section)
|
@@ -4689,9 +4744,6 @@ def asciidoc(backend, doctype, confiles, infile, outfile, options):
|
|
4689
4744
|
try:
|
4690
4745
|
if doctype not in ('article','manpage','book'):
|
4691
4746
|
raise EAsciiDoc,'illegal document type'
|
4692
|
-
if backend == 'linuxdoc' and doctype != 'article':
|
4693
|
-
raise EAsciiDoc,'%s %s documents are not supported' \
|
4694
|
-
% (backend,doctype)
|
4695
4747
|
document.backend = backend
|
4696
4748
|
if not os.path.exists(os.path.join(APP_DIR, backend+'.conf')) and not \
|
4697
4749
|
os.path.exists(os.path.join(CONF_DIR, backend+'.conf')):
|
@@ -4820,9 +4872,10 @@ def main():
|
|
4820
4872
|
print_stderr('FAILED: Python 2.3 or better required.')
|
4821
4873
|
sys.exit(1)
|
4822
4874
|
# Locate the executable and configuration files directory.
|
4823
|
-
global APP_FILE,APP_DIR,USER_DIR
|
4875
|
+
global APP_FILE,APP_DIR,CONF_DIR,USER_DIR
|
4824
4876
|
APP_FILE = os.path.realpath(sys.argv[0])
|
4825
4877
|
APP_DIR = os.path.dirname(APP_FILE)
|
4878
|
+
CONF_DIR = APP_DIR
|
4826
4879
|
USER_DIR = os.environ.get('HOME')
|
4827
4880
|
if USER_DIR is not None:
|
4828
4881
|
USER_DIR = os.path.join(USER_DIR,'.asciidoc')
|