github-markup 0.7.4 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,7 +2,9 @@ source "http://rubygems.org"
2
2
  gem "redcarpet"
3
3
  gem "RedCloth"
4
4
  gem "rdoc", "~>3.6"
5
- gem "org-ruby"
5
+ gem "org-ruby", ">= 0.7.0"
6
6
  gem "creole", "~>0.3.6"
7
7
  gem "wikicloth", "=0.6.0"
8
+ gem "literati", "= 0.0.3"
9
+ gem "asciidoctor", ">= 0.0.5"
8
10
  gem "rake"
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/tanoku/redcarpet)
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 Check `lib/github/markups.rb` for some
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. Create an [Issue][1] with a link to your branch
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/issues
120
+ [1]: http://github.com/github/markup/pulls
@@ -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.4'
17
- s.date = '2012-07-19'
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
@@ -1,6 +1,6 @@
1
1
  module GitHub
2
2
  module Markup
3
- VERSION = '0.7.4'
3
+ VERSION = '0.7.5'
4
4
  Version = VERSION
5
5
  end
6
6
  end
@@ -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
- return html.encode('utf-8')
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
- print main()
74
+ sys.stdout.write("%s%s" % (main(), "\n"))
75
+ sys.stdout.flush()
@@ -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
- command(:rest2html, /re?st(\.txt)?/)
43
+ markup(:literati, /lhs/) do |content|
44
+ Literati.render(content)
45
+ end
44
46
 
45
- command('asciidoc -s --backend=xhtml11 -o - -', /asciidoc/)
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,10 @@
1
+ # Markdown
2
+
3
+ Except with more magic added.
4
+
5
+ > isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
6
+ > isPrefixOf [] _ = True
7
+ > isPrefixOf _ [] = False
8
+ > isPrefixOf (x:xs) (y:ys)= x == y && isPrefixOf xs ys
9
+
10
+ And Haskell. A lot of Haskell.
@@ -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) =&gt; [a] -&gt; [a] -&gt; Bool
6
+ isPrefixOf [] _ = True
7
+ isPrefixOf _ [] = False
8
+ isPrefixOf (x:xs) (y:ys)= x == y &amp;&amp; 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 &#8220;:&#8221; as examples.</li>
13
- <li>Minor enhancement: Recognize #+BEGIN_SRC as source blocks</li>
14
- <li>Minor enhancement: Add &#8220;src&#8221; and &#8220;example&#8221; classes to &lt;pre&gt; blocks.</li>
12
+ <li>Minor enhancement: Recognize lines starting with &#8220;:&#8221; as examples.
13
+ </li>
14
+ <li>Minor enhancement: Recognize #+BEGIN_SRC as source blocks
15
+ </li>
16
+ <li>Minor enhancement: Add &#8220;src&#8221; and &#8220;example&#8221; classes to &lt;pre&gt; 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:</li>
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.</li>
21
- <li>Exporting todo keywords (option todo:t)</li>
22
- <li>Numbering headlines (option num:t)</li>
23
- <li>Skipping text before the first headline (option skip:t)</li>
24
- <li>Skipping tables (option |:nil)</li>
25
- <li>Custom todo keywords</li>
26
- <li>EXPORT_SELECT_TAGS and EXPORT_EXLUDE_TAGS for controlling parts of the tree to export</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
- <li>Rewrite &#8220;file:(blah).org&#8221; links to &#8220;http:(blah).html&#8221; links. This makes the inter-links to other org-mode files work.</li>
29
- <li>Uses &lt;th&gt; tags inside table rows that precede table separators.</li>
30
- <li>Bugfixes:</li>
38
+ </li>
39
+ <li>Rewrite &#8220;file:(blah).org&#8221; links to &#8220;http:(blah).html&#8221; links. This makes the inter-links to other org-mode files work.
40
+ </li>
41
+ <li>Uses &lt;th&gt; tags inside table rows that precede table separators.
42
+ </li>
43
+ <li>Bugfixes:
31
44
  <ul>
32
- <li>Headings now have HTML escaped.</li>
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.</li>
38
- <li>Everything now shows up in code blocks, even org-mode metadata.</li>
39
- <li>Fixed bugs:</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.</li>
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</li>
47
- <li>org-mode comments will show up in a code block.</li>
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 &#8220;title&#8221;</li>
52
- <li>HTML output is now indented</li>
53
- <li>Proper support for multi-paragraph list items.</li>
72
+ <li>The first thing output in HTML gets the class &#8220;title&#8221;
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
- <li>Fixed bugs:</li>
78
+ </li>
79
+ <li>Fixed bugs:
56
80
  <ul>
57
- <li>&#8220;rake spec&#8221; wouldn&#8217;t work on Linux. Needed &#8220;require &#8216;rubygems&#8217;&#8221;.</li>
81
+ <li>&#8220;rake spec&#8221; wouldn&#8217;t work on Linux. Needed &#8220;require &#8216;rubygems&#8217;&#8221;.
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&#8230;).</li>
63
- <li>Fixed bugs:</li>
88
+ <li>Uses rubypants to get better typography (smart quotes, elipses, etc&#8230;).
89
+ </li>
90
+ <li>Fixed bugs:
64
91
  <ul>
65
- <li>Tables and lists did not get properly closed at the end of file</li>
66
- <li>You couldn&#8217;t do inline formatting inside table cells</li>
67
- <li>Characters in PRE blocks were not HTML escaped.</li>
92
+ <li>Tables and lists did not get properly closed at the end of file
93
+ </li>
94
+ <li>You couldn&#8217;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.</li>
73
- <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>.</li>
74
- <li>Lots of refactoring to make the code more maintainable.</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:</li>
79
- </ul>
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 ==========&gt; #{@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
- <ul>
97
- <li>Major code cleanup: Created the <code>OutputBuffer</code> class that greatly simplified a lot of the messiness of <code>textile</code> conversion.</li>
98
- <li>Added support for line breaks within list items.</li>
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
- hash: 11
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
- description: " This gem is used by GitHub to render any fancy markup such as\n Markdown, Textile, Org-Mode, etc. Fork it and add your own!\n"
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
- hash: 3
86
- segments:
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
- hash: 3
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.6.2
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("&", "&amp;") # 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&#37;&#52;&#48;mail&#46;example&#46;org">
105
- abc<span>&#64;</span>mail<span>&#46;</span>example<span>&#46;</span>org</a>
106
- -----------
107
- """
108
- def mangleEmail(matches):
109
- email1 = "%s&#37;&#52;&#48;%s" % (matches.group(1), matches.group(2))
110
- email1 = email1.replace(".", "&#46;")
111
- email2 = "%s<span>&#64;</span>%s" % (matches.group(1), matches.group(2))
112
- email2 = email2.replace(".", "<span>&#46;</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)