github-markup 0.7.4 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +3 -1
- data/README.md +4 -4
- data/github-markup.gemspec +4 -4
- data/lib/github-markup.rb +1 -1
- data/lib/github/commands/rest2html +9 -2
- data/lib/github/markups.rb +9 -3
- data/test/markups/README.lhs +10 -0
- data/test/markups/README.lhs.html +11 -0
- data/test/markups/README.org.html +78 -41
- metadata +25 -43
- data/lib/github/commands/asciidoc2html +0 -119
- data/lib/github/commands/asciidocapi.py +0 -240
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,7 @@ Markups
|
|
10
10
|
The following markups are supported. The dependencies listed are required if
|
11
11
|
you wish to run the library.
|
12
12
|
|
13
|
-
* [.markdown](http://daringfireball.net/projects/markdown/) -- `gem install redcarpet` (https://github.com/
|
13
|
+
* [.markdown, .mdown, .md](http://daringfireball.net/projects/markdown/) -- `gem install redcarpet` (https://github.com/vmg/redcarpet)
|
14
14
|
* [.textile](http://www.textism.com/tools/textile/) -- `gem install RedCloth`
|
15
15
|
* [.rdoc](http://rdoc.sourceforge.net/) -- `gem install rdoc -v 3.6.1`
|
16
16
|
* [.org](http://orgmode.org/) -- `gem install org-ruby`
|
@@ -57,7 +57,7 @@ If nothing complains, congratulations!
|
|
57
57
|
### Classes
|
58
58
|
|
59
59
|
If your markup can be translated using a Ruby library, that's
|
60
|
-
great. Check out
|
60
|
+
great. Check out `lib/github/markups.rb` for some
|
61
61
|
examples. Let's look at Markdown:
|
62
62
|
|
63
63
|
markup(:markdown, /md|mkdn?|markdown/) do |content|
|
@@ -111,10 +111,10 @@ Contributing
|
|
111
111
|
2. Create a branch (`git checkout -b my_markup`)
|
112
112
|
3. Commit your changes (`git commit -am "Added Snarkdown"`)
|
113
113
|
4. Push to the branch (`git push origin my_markup`)
|
114
|
-
5.
|
114
|
+
5. Open a [Pull Request][1]
|
115
115
|
6. Enjoy a refreshing Diet Coke and wait
|
116
116
|
|
117
117
|
|
118
118
|
[r2h]: http://github.com/github/markup/tree/master/lib/github/commands/rest2html
|
119
119
|
[r2hc]: http://github.com/github/markup/tree/master/lib/github/markups.rb#L13
|
120
|
-
[1]: http://github.com/github/markup/
|
120
|
+
[1]: http://github.com/github/markup/pulls
|
data/github-markup.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'github-markup'
|
16
|
-
s.version = '0.7.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '0.7.5'
|
17
|
+
s.date = '2012-12-17'
|
18
18
|
s.executables = ['github-markup']
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -62,8 +62,6 @@ desc
|
|
62
62
|
bin/github-markup
|
63
63
|
github-markup.gemspec
|
64
64
|
lib/github-markup.rb
|
65
|
-
lib/github/commands/asciidoc2html
|
66
|
-
lib/github/commands/asciidocapi.py
|
67
65
|
lib/github/commands/rest2html
|
68
66
|
lib/github/markup.rb
|
69
67
|
lib/github/markup/rdoc.rb
|
@@ -73,6 +71,8 @@ desc
|
|
73
71
|
test/markups/README.asciidoc.html
|
74
72
|
test/markups/README.creole
|
75
73
|
test/markups/README.creole.html
|
74
|
+
test/markups/README.lhs
|
75
|
+
test/markups/README.lhs.html
|
76
76
|
test/markups/README.markdown
|
77
77
|
test/markups/README.markdown.html
|
78
78
|
test/markups/README.mediawiki
|
data/lib/github-markup.rb
CHANGED
@@ -61,8 +61,15 @@ def main():
|
|
61
61
|
parts = publish_parts(text, writer=writer, settings_overrides=SETTINGS)
|
62
62
|
if 'html_body' in parts:
|
63
63
|
html = parts['html_body']
|
64
|
-
|
64
|
+
|
65
|
+
# publish_parts() in python 2.x return dict values as Unicode type
|
66
|
+
# in py3k Unicode is unavailable and values are of str type
|
67
|
+
if isinstance(html, str):
|
68
|
+
return html
|
69
|
+
else:
|
70
|
+
return html.encode('utf-8')
|
65
71
|
return ''
|
66
72
|
|
67
73
|
if __name__ == '__main__':
|
68
|
-
|
74
|
+
sys.stdout.write("%s%s" % (main(), "\n"))
|
75
|
+
sys.stdout.flush()
|
data/lib/github/markups.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
MD_FILES = /md|mkdn?|mdown|markdown/
|
1
|
+
MD_FILES = /md|mkdn?|mdwn|mdown|markdown/
|
2
2
|
|
3
3
|
if markup('github/markdown', MD_FILES) do |content|
|
4
4
|
GitHub::Markdown.render(content)
|
@@ -40,9 +40,15 @@ markup(:wikicloth, /mediawiki|wiki/) do |content|
|
|
40
40
|
WikiCloth::WikiCloth.new(:data => content).to_html(:noedit => true)
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
markup(:literati, /lhs/) do |content|
|
44
|
+
Literati.render(content)
|
45
|
+
end
|
44
46
|
|
45
|
-
|
47
|
+
markup(:asciidoctor, /asc|adoc|asciidoc/) do |content|
|
48
|
+
Asciidoctor::Document.new(content).render
|
49
|
+
end
|
50
|
+
|
51
|
+
command(:rest2html, /re?st(\.txt)?/)
|
46
52
|
|
47
53
|
# pod2html is nice enough to generate a full-on HTML document for us,
|
48
54
|
# so we return the favor by ripping out the good parts.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<h1>Markdown</h1>
|
2
|
+
|
3
|
+
<p>Except with more magic added.</p>
|
4
|
+
|
5
|
+
<pre><code class="haskell">isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
|
6
|
+
isPrefixOf [] _ = True
|
7
|
+
isPrefixOf _ [] = False
|
8
|
+
isPrefixOf (x:xs) (y:ys)= x == y && isPrefixOf xs ys
|
9
|
+
</code></pre>
|
10
|
+
|
11
|
+
<p>And Haskell. A lot of Haskell.</p>
|
@@ -9,75 +9,108 @@
|
|
9
9
|
<h1><span class="heading-number heading-number-1">2 </span>History</h1>
|
10
10
|
<h2><span class="heading-number heading-number-2">2.1 </span>2009-12-30: Version 0.5.1</h2>
|
11
11
|
<ul>
|
12
|
-
<li>Minor enhancement: Recognize lines starting with “:” as examples
|
13
|
-
|
14
|
-
<li>Minor enhancement:
|
12
|
+
<li>Minor enhancement: Recognize lines starting with “:” as examples.
|
13
|
+
</li>
|
14
|
+
<li>Minor enhancement: Recognize #+BEGIN_SRC as source blocks
|
15
|
+
</li>
|
16
|
+
<li>Minor enhancement: Add “src” and “example” classes to <pre> blocks.
|
17
|
+
</li>
|
15
18
|
</ul>
|
16
19
|
<h2><span class="heading-number heading-number-2">2.2 </span>2009-12-30: Version 0.5.0</h2>
|
17
20
|
<ul>
|
18
|
-
<li>Parse (but not necessarily <b>use</b>) in-buffer settings. The following in-buffer settings <b>are</b> used
|
21
|
+
<li>Parse (but not necessarily <b>use</b>) in-buffer settings. The following in-buffer settings <b>are</b> used:
|
19
22
|
<ul>
|
20
|
-
<li>Understand the #+TITLE: directive
|
21
|
-
|
22
|
-
<li>
|
23
|
-
|
24
|
-
<li>
|
25
|
-
|
26
|
-
<li>
|
23
|
+
<li>Understand the #+TITLE: directive.
|
24
|
+
</li>
|
25
|
+
<li>Exporting todo keywords (option todo:t)
|
26
|
+
</li>
|
27
|
+
<li>Numbering headlines (option num:t)
|
28
|
+
</li>
|
29
|
+
<li>Skipping text before the first headline (option skip:t)
|
30
|
+
</li>
|
31
|
+
<li>Skipping tables (option |:nil)
|
32
|
+
</li>
|
33
|
+
<li>Custom todo keywords
|
34
|
+
</li>
|
35
|
+
<li>EXPORT_SELECT_TAGS and EXPORT_EXLUDE_TAGS for controlling parts of the tree to export
|
36
|
+
</li>
|
27
37
|
</ul>
|
28
|
-
|
29
|
-
<li>
|
30
|
-
|
38
|
+
</li>
|
39
|
+
<li>Rewrite “file:(blah).org” links to “http:(blah).html” links. This makes the inter-links to other org-mode files work.
|
40
|
+
</li>
|
41
|
+
<li>Uses <th> tags inside table rows that precede table separators.
|
42
|
+
</li>
|
43
|
+
<li>Bugfixes:
|
31
44
|
<ul>
|
32
|
-
<li>Headings now have HTML escaped
|
45
|
+
<li>Headings now have HTML escaped.
|
46
|
+
</li>
|
33
47
|
</ul>
|
48
|
+
</li>
|
34
49
|
</ul>
|
35
50
|
<h2><span class="heading-number heading-number-2">2.3 </span>2009-12-29: Version 0.4.2</h2>
|
36
51
|
<ul>
|
37
|
-
<li>Got rid of the extraneous newline at the start of code blocks
|
38
|
-
|
39
|
-
<li>
|
52
|
+
<li>Got rid of the extraneous newline at the start of code blocks.
|
53
|
+
</li>
|
54
|
+
<li>Everything now shows up in code blocks, even org-mode metadata.
|
55
|
+
</li>
|
56
|
+
<li>Fixed bugs:
|
40
57
|
<ul>
|
41
|
-
<li>Regressed smart double quotes with HTML escaping. Added a test case and fixed the regression
|
58
|
+
<li>Regressed smart double quotes with HTML escaping. Added a test case and fixed the regression.
|
59
|
+
</li>
|
42
60
|
</ul>
|
61
|
+
</li>
|
43
62
|
</ul>
|
44
63
|
<h2><span class="heading-number heading-number-2">2.4 </span>2009-12-29: Version 0.4.1</h2>
|
45
64
|
<ul>
|
46
|
-
<li>HTML is now escaped by default
|
47
|
-
|
65
|
+
<li>HTML is now escaped by default
|
66
|
+
</li>
|
67
|
+
<li>org-mode comments will show up in a code block.
|
68
|
+
</li>
|
48
69
|
</ul>
|
49
70
|
<h2><span class="heading-number heading-number-2">2.5 </span>2009-12-29: Version 0.4</h2>
|
50
71
|
<ul>
|
51
|
-
<li>The first thing output in HTML gets the class “title”
|
52
|
-
|
53
|
-
<li>
|
72
|
+
<li>The first thing output in HTML gets the class “title”
|
73
|
+
</li>
|
74
|
+
<li>HTML output is now indented
|
75
|
+
</li>
|
76
|
+
<li>Proper support for multi-paragraph list items.
|
54
77
|
<p>See? This paragraph is part of the last bullet.</p>
|
55
|
-
|
78
|
+
</li>
|
79
|
+
<li>Fixed bugs:
|
56
80
|
<ul>
|
57
|
-
<li>“rake spec” wouldn’t work on Linux. Needed “require ‘rubygems’”
|
81
|
+
<li>“rake spec” wouldn’t work on Linux. Needed “require ‘rubygems’”.
|
82
|
+
</li>
|
58
83
|
</ul>
|
84
|
+
</li>
|
59
85
|
</ul>
|
60
86
|
<h2><span class="heading-number heading-number-2">2.6 </span>2009-12-27: Version 0.3</h2>
|
61
87
|
<ul>
|
62
|
-
<li>Uses rubypants to get better typography (smart quotes, elipses, etc…)
|
63
|
-
|
88
|
+
<li>Uses rubypants to get better typography (smart quotes, elipses, etc…).
|
89
|
+
</li>
|
90
|
+
<li>Fixed bugs:
|
64
91
|
<ul>
|
65
|
-
<li>Tables and lists did not get properly closed at the end of file
|
66
|
-
|
67
|
-
<li>
|
92
|
+
<li>Tables and lists did not get properly closed at the end of file
|
93
|
+
</li>
|
94
|
+
<li>You couldn’t do inline formatting inside table cells
|
95
|
+
</li>
|
96
|
+
<li>Characters in PRE blocks were not HTML escaped.
|
97
|
+
</li>
|
68
98
|
</ul>
|
99
|
+
</li>
|
69
100
|
</ul>
|
70
101
|
<h2><span class="heading-number heading-number-2">2.7 </span>2009-12-26: Version 0.2</h2>
|
71
102
|
<ul>
|
72
|
-
<li>Added <code>to_html</code> output on the parser
|
73
|
-
|
74
|
-
<li>
|
103
|
+
<li>Added <code>to_html</code> output on the parser.
|
104
|
+
</li>
|
105
|
+
<li>Added support for the full range of inline markup: <b>bold</b>, <i>italic</i>, <code>code</code>, <code>verbatim</code>, <span style="text-decoration:underline;">underline</span>, <del>strikethrough</del>.
|
106
|
+
</li>
|
107
|
+
<li>Lots of refactoring to make the code more maintainable.
|
108
|
+
</li>
|
75
109
|
</ul>
|
76
110
|
<h2><span class="heading-number heading-number-2">2.8 </span>2009-12-23: Version 0.1</h2>
|
77
111
|
<ul>
|
78
|
-
<li>Added support for block code, like this
|
79
|
-
|
80
|
-
<pre class="example">
|
112
|
+
<li>Added support for block code, like this:
|
113
|
+
<pre class="example">
|
81
114
|
def flush!
|
82
115
|
@logger.debug "FLUSH ==========> #{@output_type}"
|
83
116
|
if (@output_type == :blank) then
|
@@ -92,8 +125,12 @@
|
|
92
125
|
end
|
93
126
|
@buffer = ""
|
94
127
|
end
|
95
|
-
</pre>
|
96
|
-
|
97
|
-
<
|
98
|
-
|
128
|
+
</pre>
|
129
|
+
</li>
|
130
|
+
<ul>
|
131
|
+
<li>Major code cleanup: Created the <code>OutputBuffer</code> class that greatly simplified a lot of the messiness of <code>textile</code> conversion.
|
132
|
+
</li>
|
133
|
+
<li>Added support for line breaks within list items.
|
134
|
+
</li>
|
135
|
+
</ul>
|
99
136
|
</ul>
|
metadata
CHANGED
@@ -1,34 +1,26 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-markup
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.5
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
- 4
|
10
|
-
version: 0.7.4
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Chris Wanstrath
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2012-07-19 00:00:00 +02:00
|
19
|
-
default_executable:
|
12
|
+
date: 2012-12-17 00:00:00.000000000 Z
|
20
13
|
dependencies: []
|
21
|
-
|
22
|
-
|
14
|
+
description: ! " This gem is used by GitHub to render any fancy markup such as\n
|
15
|
+
\ Markdown, Textile, Org-Mode, etc. Fork it and add your own!\n"
|
23
16
|
email: chris@ozmm.org
|
24
|
-
executables:
|
17
|
+
executables:
|
25
18
|
- github-markup
|
26
19
|
extensions: []
|
27
|
-
|
28
|
-
extra_rdoc_files:
|
20
|
+
extra_rdoc_files:
|
29
21
|
- README.md
|
30
22
|
- LICENSE
|
31
|
-
files:
|
23
|
+
files:
|
32
24
|
- Gemfile
|
33
25
|
- HISTORY.md
|
34
26
|
- LICENSE
|
@@ -37,8 +29,6 @@ files:
|
|
37
29
|
- bin/github-markup
|
38
30
|
- github-markup.gemspec
|
39
31
|
- lib/github-markup.rb
|
40
|
-
- lib/github/commands/asciidoc2html
|
41
|
-
- lib/github/commands/asciidocapi.py
|
42
32
|
- lib/github/commands/rest2html
|
43
33
|
- lib/github/markup.rb
|
44
34
|
- lib/github/markup/rdoc.rb
|
@@ -48,6 +38,8 @@ files:
|
|
48
38
|
- test/markups/README.asciidoc.html
|
49
39
|
- test/markups/README.creole
|
50
40
|
- test/markups/README.creole.html
|
41
|
+
- test/markups/README.lhs
|
42
|
+
- test/markups/README.lhs.html
|
51
43
|
- test/markups/README.markdown
|
52
44
|
- test/markups/README.markdown.html
|
53
45
|
- test/markups/README.mediawiki
|
@@ -68,39 +60,29 @@ files:
|
|
68
60
|
- test/markups/README.textile.html
|
69
61
|
- test/markups/README.txt
|
70
62
|
- test/markups/README.txt.html
|
71
|
-
has_rdoc: true
|
72
63
|
homepage: https://github.com/github/markup
|
73
64
|
licenses: []
|
74
|
-
|
75
65
|
post_install_message:
|
76
|
-
rdoc_options:
|
66
|
+
rdoc_options:
|
77
67
|
- --charset=UTF-8
|
78
|
-
require_paths:
|
68
|
+
require_paths:
|
79
69
|
- lib
|
80
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
71
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
|
86
|
-
|
87
|
-
- 0
|
88
|
-
version: "0"
|
89
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
77
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
segments:
|
96
|
-
- 0
|
97
|
-
version: "0"
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
98
82
|
requirements: []
|
99
|
-
|
100
83
|
rubyforge_project:
|
101
|
-
rubygems_version: 1.
|
84
|
+
rubygems_version: 1.8.23
|
102
85
|
signing_key:
|
103
86
|
specification_version: 2
|
104
87
|
summary: The code GitHub uses to render README.markup
|
105
88
|
test_files: []
|
106
|
-
|
@@ -1,119 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
|
3
|
-
"""A small wrapper file for parsing AsciiDoc files at Github."""
|
4
|
-
|
5
|
-
__author__ = "Devin Weaver"
|
6
|
-
__copyright__ = "Copyright (C) 2009 Devin Weaver"
|
7
|
-
__license__ = "Public Domain"
|
8
|
-
__version__ = "0.1"
|
9
|
-
|
10
|
-
"""
|
11
|
-
github_asciidoc.py
|
12
|
-
------------------
|
13
|
-
|
14
|
-
This is a wrapper file for parsing AsciiDoc files at github. It wraps the
|
15
|
-
current AsciiDoc API.
|
16
|
-
|
17
|
-
AsciiDoc specifications suggest using the file extension of `.txt` however this
|
18
|
-
causes conflict because there is no way to determine if a text file is an
|
19
|
-
AsciiDoc or not without pre-processing the file. This gives us two simple
|
20
|
-
options:
|
21
|
-
|
22
|
-
1. **Parse all text files**. We could have all files ending in `.txt` or
|
23
|
-
``README.txt`` be parsed through AsciiDoc. It will print pretty text fine
|
24
|
-
even if it isn't formatted as such. However this could be *not what the user
|
25
|
-
expects*.
|
26
|
-
2. **Pick a unique extension**. We could pick a unique extension (i.e.
|
27
|
-
`.asciidoc`) to prevent clashing. Although not directly suggested by the
|
28
|
-
author of AsciiDoc there is no standard or practice to the contrary.
|
29
|
-
|
30
|
-
Option two is recommended by myself.
|
31
|
-
|
32
|
-
Requirements
|
33
|
-
~~~~~~~~~~~~
|
34
|
-
|
35
|
-
The AsciiDoc API comes in two parts. The first is the system installation of
|
36
|
-
AsciiDoc which has a simple install_. The second part is the API script. You
|
37
|
-
can either copy this to the current directory or the application's lib folder.
|
38
|
-
There is more information on the `API page`_
|
39
|
-
|
40
|
-
The `re` package is imported here for the purpose to accomplish E-Mail address
|
41
|
-
cloaking. AsciiDoc does not offer it's own cloaking algorithm like docutils
|
42
|
-
does. So I made a simple one here to do the same. **If the expense of regex's
|
43
|
-
is too high it can be easily commented out.**
|
44
|
-
|
45
|
-
.. tip::
|
46
|
-
AsciiDoc by default runs in *safe mode* which means it will not include
|
47
|
-
external files that are **not** in the same directory as the `infile`.
|
48
|
-
However since we use a StringIO through the API it should be based on the
|
49
|
-
current working directory.
|
50
|
-
|
51
|
-
.. _install: http://www.methods.co.nz/asciidoc/userguide.html
|
52
|
-
.. _API page: http://www.methods.co.nz/asciidoc/asciidocapi.html
|
53
|
-
"""
|
54
|
-
|
55
|
-
try:
|
56
|
-
import locale
|
57
|
-
locale.setlocale(locale.LC_ALL, '')
|
58
|
-
except:
|
59
|
-
pass
|
60
|
-
|
61
|
-
import sys
|
62
|
-
import cStringIO # faster then StringIO
|
63
|
-
from asciidocapi import AsciiDocAPI
|
64
|
-
from asciidocapi import AsciiDocError
|
65
|
-
import re # only needed to simulate cloak_email_addresses
|
66
|
-
|
67
|
-
def main():
|
68
|
-
"""
|
69
|
-
Parses the given AsciiDoc file or the redirected string input and returns
|
70
|
-
the HTML body.
|
71
|
-
|
72
|
-
Usage: asciidoc2html < README.rst
|
73
|
-
asciidoc2html README.rst
|
74
|
-
"""
|
75
|
-
try:
|
76
|
-
text = open(sys.argv[1], 'r').read()
|
77
|
-
except IOError: # given filename could not be found
|
78
|
-
return ''
|
79
|
-
except IndexError: # no filename given
|
80
|
-
text = sys.stdin.read()
|
81
|
-
|
82
|
-
infile = cStringIO.StringIO(text)
|
83
|
-
outfile = cStringIO.StringIO()
|
84
|
-
asciidoc = AsciiDocAPI()
|
85
|
-
asciidoc.options('-s')
|
86
|
-
|
87
|
-
try:
|
88
|
-
asciidoc.execute(infile, outfile, 'xhtml11')
|
89
|
-
except AsciiDocError, strerror:
|
90
|
-
str = "%s" % (strerror)
|
91
|
-
str = str.replace("&", "&") # Must be done first
|
92
|
-
str = str.replace("<", "%lt;")
|
93
|
-
str = str.replace(">", "%gt;")
|
94
|
-
outfile.write ("<blockquote><strong>AsciiDoc ERROR: %s</strong></blockquote>" % (str))
|
95
|
-
|
96
|
-
"""
|
97
|
-
Cloak email addresses
|
98
|
-
|
99
|
-
AsciiDoc API does not have a `cloak_email_addresses` option. We can do the
|
100
|
-
same with a set of regex but that can be expensive. Keep section commented
|
101
|
-
to disable. So ``abc@mail.example.com`` becomes:
|
102
|
-
|
103
|
-
-----------
|
104
|
-
<a class="reference" href="mailto:abc%40mail.example.org">
|
105
|
-
abc<span>@</span>mail<span>.</span>example<span>.</span>org</a>
|
106
|
-
-----------
|
107
|
-
"""
|
108
|
-
def mangleEmail(matches):
|
109
|
-
email1 = "%s%40%s" % (matches.group(1), matches.group(2))
|
110
|
-
email1 = email1.replace(".", ".")
|
111
|
-
email2 = "%s<span>@</span>%s" % (matches.group(1), matches.group(2))
|
112
|
-
email2 = email2.replace(".", "<span>.</span>")
|
113
|
-
return "<a class=\"reference\" href=\"mailto:%s\">%s</a>" % (email1, email2)
|
114
|
-
|
115
|
-
return re.sub(r'<a href="mailto:([^@]+)@([^@]+)">([^@]+)@([^@]+)</a>', mangleEmail, outfile.getvalue())
|
116
|
-
#return outfile.getvalue()
|
117
|
-
|
118
|
-
if __name__ == '__main__':
|
119
|
-
print main()
|
@@ -1,240 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
"""
|
3
|
-
asciidocapi - AsciiDoc API wrapper class.
|
4
|
-
|
5
|
-
The AsciiDocAPI class provides an API for executing asciidoc. Minimal example
|
6
|
-
compiles `mydoc.txt` to `mydoc.html`:
|
7
|
-
|
8
|
-
import asciidocapi
|
9
|
-
asciidoc = asciidocapi.AsciiDocAPI()
|
10
|
-
asciidoc.execute('mydoc.txt')
|
11
|
-
|
12
|
-
- Full documentation in asciidocapi.txt.
|
13
|
-
- See the doctests below for more examples.
|
14
|
-
|
15
|
-
Doctests:
|
16
|
-
|
17
|
-
1. Check execution:
|
18
|
-
|
19
|
-
>>> import StringIO
|
20
|
-
>>> infile = StringIO.StringIO('Hello *{author}*')
|
21
|
-
>>> outfile = StringIO.StringIO()
|
22
|
-
>>> asciidoc = AsciiDocAPI()
|
23
|
-
>>> asciidoc.options('--no-header-footer')
|
24
|
-
>>> asciidoc.attributes['author'] = 'Joe Bloggs'
|
25
|
-
>>> asciidoc.execute(infile, outfile, backend='html4')
|
26
|
-
>>> print outfile.getvalue()
|
27
|
-
<p>Hello <strong>Joe Bloggs</strong></p>
|
28
|
-
|
29
|
-
>>> asciidoc.attributes['author'] = 'Bill Smith'
|
30
|
-
>>> infile = StringIO.StringIO('Hello _{author}_')
|
31
|
-
>>> outfile = StringIO.StringIO()
|
32
|
-
>>> asciidoc.execute(infile, outfile, backend='docbook')
|
33
|
-
>>> print outfile.getvalue()
|
34
|
-
<simpara>Hello <emphasis>Bill Smith</emphasis></simpara>
|
35
|
-
|
36
|
-
2. Check error handling:
|
37
|
-
|
38
|
-
>>> import StringIO
|
39
|
-
>>> asciidoc = AsciiDocAPI()
|
40
|
-
>>> infile = StringIO.StringIO('---------')
|
41
|
-
>>> outfile = StringIO.StringIO()
|
42
|
-
>>> asciidoc.execute(infile, outfile)
|
43
|
-
Traceback (most recent call last):
|
44
|
-
File "<stdin>", line 1, in <module>
|
45
|
-
File "asciidocapi.py", line 189, in execute
|
46
|
-
raise AsciiDocError(self.messages[-1])
|
47
|
-
AsciiDocError: ERROR: <stdin>: line 1: [blockdef-listing] missing closing delimiter
|
48
|
-
|
49
|
-
|
50
|
-
Copyright (C) 2009 Stuart Rackham. Free use of this software is granted
|
51
|
-
under the terms of the GNU General Public License (GPL).
|
52
|
-
|
53
|
-
"""
|
54
|
-
|
55
|
-
import sys,os,re
|
56
|
-
|
57
|
-
API_VERSION = '0.1.1'
|
58
|
-
MIN_ASCIIDOC_VERSION = '8.4.1' # Minimum acceptable AsciiDoc version.
|
59
|
-
|
60
|
-
|
61
|
-
def find_in_path(fname, path=None):
|
62
|
-
"""
|
63
|
-
Find file fname in paths. Return None if not found.
|
64
|
-
"""
|
65
|
-
if path is None:
|
66
|
-
path = os.environ.get('PATH', '')
|
67
|
-
for dir in path.split(os.pathsep):
|
68
|
-
fpath = os.path.join(dir, fname)
|
69
|
-
if os.path.isfile(fpath):
|
70
|
-
return fpath
|
71
|
-
else:
|
72
|
-
return None
|
73
|
-
|
74
|
-
|
75
|
-
class AsciiDocError(Exception):
|
76
|
-
pass
|
77
|
-
|
78
|
-
|
79
|
-
class Options(object):
|
80
|
-
"""
|
81
|
-
Stores asciidoc(1) command options.
|
82
|
-
"""
|
83
|
-
def __init__(self, values=[]):
|
84
|
-
self.values = values[:]
|
85
|
-
def __call__(self, name, value=None):
|
86
|
-
"""Shortcut for append method."""
|
87
|
-
self.append(name, value)
|
88
|
-
def append(self, name, value=None):
|
89
|
-
if type(value) in (int,float):
|
90
|
-
value = str(value)
|
91
|
-
self.values.append((name,value))
|
92
|
-
|
93
|
-
|
94
|
-
class Version(object):
|
95
|
-
"""
|
96
|
-
Parse and compare AsciiDoc version numbers. Instance attributes:
|
97
|
-
|
98
|
-
string: String version number '<major>.<minor>[.<micro>][suffix]'.
|
99
|
-
major: Integer major version number.
|
100
|
-
minor: Integer minor version number.
|
101
|
-
micro: Integer micro version number.
|
102
|
-
suffix: Suffix (begins with non-numeric character) is ignored when
|
103
|
-
comparing.
|
104
|
-
|
105
|
-
Doctest examples:
|
106
|
-
|
107
|
-
>>> Version('8.2.5') < Version('8.3 beta 1')
|
108
|
-
True
|
109
|
-
>>> Version('8.3.0') == Version('8.3. beta 1')
|
110
|
-
True
|
111
|
-
>>> Version('8.2.0') < Version('8.20')
|
112
|
-
True
|
113
|
-
>>> Version('8.20').major
|
114
|
-
8
|
115
|
-
>>> Version('8.20').minor
|
116
|
-
20
|
117
|
-
>>> Version('8.20').micro
|
118
|
-
0
|
119
|
-
>>> Version('8.20').suffix
|
120
|
-
''
|
121
|
-
>>> Version('8.20 beta 1').suffix
|
122
|
-
'beta 1'
|
123
|
-
|
124
|
-
"""
|
125
|
-
def __init__(self, version):
|
126
|
-
self.string = version
|
127
|
-
reo = re.match(r'^(\d+)\.(\d+)(\.(\d+))?\s*(.*?)\s*$', self.string)
|
128
|
-
if not reo:
|
129
|
-
raise ValueError('invalid version number: %s' % self.string)
|
130
|
-
groups = reo.groups()
|
131
|
-
self.major = int(groups[0])
|
132
|
-
self.minor = int(groups[1])
|
133
|
-
self.micro = int(groups[3] or '0')
|
134
|
-
self.suffix = groups[4] or ''
|
135
|
-
def __cmp__(self, other):
|
136
|
-
result = cmp(self.major, other.major)
|
137
|
-
if result == 0:
|
138
|
-
result = cmp(self.minor, other.minor)
|
139
|
-
if result == 0:
|
140
|
-
result = cmp(self.micro, other.micro)
|
141
|
-
return result
|
142
|
-
|
143
|
-
|
144
|
-
class AsciiDocAPI(object):
|
145
|
-
"""
|
146
|
-
AsciiDoc API class.
|
147
|
-
"""
|
148
|
-
def __init__(self, asciidoc_py=None):
|
149
|
-
"""
|
150
|
-
Locate and import asciidoc.py.
|
151
|
-
Initialize instance attributes.
|
152
|
-
"""
|
153
|
-
self.options = Options()
|
154
|
-
self.attributes = {}
|
155
|
-
self.messages = []
|
156
|
-
# Search for the asciidoc command file.
|
157
|
-
# Try ASCIIDOC_PY environment variable first.
|
158
|
-
cmd = os.environ.get('ASCIIDOC_PY')
|
159
|
-
if cmd:
|
160
|
-
if not os.path.isfile(cmd):
|
161
|
-
raise AsciiDocError('missing ASCIIDOC_PY file: %s' % cmd)
|
162
|
-
elif asciidoc_py:
|
163
|
-
# Next try path specified by caller.
|
164
|
-
cmd = asciidoc_py
|
165
|
-
if not os.path.isfile(cmd):
|
166
|
-
raise AsciiDocError('missing file: %s' % cmd)
|
167
|
-
else:
|
168
|
-
# Try shell search paths.
|
169
|
-
for fname in ['asciidoc.py','asciidoc.pyc','asciidoc']:
|
170
|
-
cmd = find_in_path(fname)
|
171
|
-
if cmd: break
|
172
|
-
else:
|
173
|
-
# Finally try current working directory.
|
174
|
-
for cmd in ['asciidoc.py','asciidoc.pyc','asciidoc']:
|
175
|
-
if os.path.isfile(cmd): break
|
176
|
-
else:
|
177
|
-
raise AsciiDocError('failed to locate asciidoc.py[c]')
|
178
|
-
cmd = os.path.realpath(cmd)
|
179
|
-
if os.path.splitext(cmd)[1] not in ['.py','.pyc']:
|
180
|
-
raise AsciiDocError('invalid Python module name: %s' % cmd)
|
181
|
-
sys.path.insert(0, os.path.dirname(cmd))
|
182
|
-
try:
|
183
|
-
try:
|
184
|
-
import asciidoc
|
185
|
-
except ImportError:
|
186
|
-
raise AsciiDocError('failed to import asciidoc')
|
187
|
-
finally:
|
188
|
-
del sys.path[0]
|
189
|
-
if Version(asciidoc.VERSION) < Version(MIN_ASCIIDOC_VERSION):
|
190
|
-
raise AsciiDocError(
|
191
|
-
'asciidocapi %s requires asciidoc %s or better'
|
192
|
-
% (API_VERSION, MIN_ASCIIDOC_VERSION))
|
193
|
-
self.asciidoc = asciidoc
|
194
|
-
self.cmd = cmd
|
195
|
-
|
196
|
-
def execute(self, infile, outfile=None, backend=None):
|
197
|
-
"""
|
198
|
-
Compile infile to outfile using backend format.
|
199
|
-
infile can outfile can be file path strings or file like objects.
|
200
|
-
"""
|
201
|
-
self.messages = []
|
202
|
-
opts = Options(self.options.values)
|
203
|
-
if outfile is not None:
|
204
|
-
opts('--out-file', outfile)
|
205
|
-
if backend is not None:
|
206
|
-
opts('--backend', backend)
|
207
|
-
for k,v in self.attributes.items():
|
208
|
-
if v == '' or k[-1] in '!@':
|
209
|
-
s = k
|
210
|
-
elif v is None: # A None value undefines the attribute.
|
211
|
-
s = k + '!'
|
212
|
-
else:
|
213
|
-
s = '%s=%s' % (k,v)
|
214
|
-
opts('--attribute', s)
|
215
|
-
args = [infile]
|
216
|
-
sys.path.insert(0, os.path.dirname(self.cmd))
|
217
|
-
try:
|
218
|
-
# The AsciiDoc command was designed to process source text then
|
219
|
-
# exit, there are globals and statics in asciidoc.py that have
|
220
|
-
# to be reinitialized before each run -- hence the reload.
|
221
|
-
reload(self.asciidoc)
|
222
|
-
finally:
|
223
|
-
del sys.path[0]
|
224
|
-
try:
|
225
|
-
try:
|
226
|
-
self.asciidoc.execute(self.cmd, opts.values, args)
|
227
|
-
finally:
|
228
|
-
self.messages = self.asciidoc.messages[:]
|
229
|
-
except SystemExit, e:
|
230
|
-
if e.code:
|
231
|
-
raise AsciiDocError(self.messages[-1])
|
232
|
-
|
233
|
-
|
234
|
-
if __name__ == "__main__":
|
235
|
-
"""
|
236
|
-
Run module doctests.
|
237
|
-
"""
|
238
|
-
import doctest
|
239
|
-
options = doctest.NORMALIZE_WHITESPACE + doctest.ELLIPSIS
|
240
|
-
doctest.testmod(optionflags=options)
|