RbST 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +1 -1
- data/.gitignore +1 -0
- data/README.markdown +21 -20
- data/Rakefile +2 -1
- data/RbST.gemspec +11 -4
- data/VERSION +1 -1
- data/lib/rbst.rb +53 -12
- data/lib/rst2parts/__init__.py +0 -0
- data/lib/rst2parts/rst2html.py +16 -0
- data/lib/rst2parts/rst2latex.py +17 -0
- data/lib/rst2parts/transform.py +40 -0
- data/test/files/test.latex +572 -0
- data/test/test_rbst.rb +14 -5
- metadata +18 -4
- data/lib/rst2parts.py +0 -43
data/.document
CHANGED
data/.gitignore
CHANGED
data/README.markdown
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
# RbST
|
2
2
|
|
3
|
-
A simple Ruby wrapper for processing reStructuredText via
|
4
|
-
Python's Docutils.
|
3
|
+
A simple Ruby wrapper for processing reStructuredText via Python's Docutils.
|
5
4
|
|
6
5
|
## Installation
|
7
6
|
|
8
7
|
Python 2.3+ is required.
|
9
8
|
|
10
|
-
RbST is available on gemcutter.
|
9
|
+
RbST is available on [gemcutter](http://gemcutter.org/gems/RbST).
|
11
10
|
|
12
11
|
gem install gemcutter
|
13
12
|
gem tumble
|
@@ -18,35 +17,40 @@ RbST is available on gemcutter.
|
|
18
17
|
require 'RbST'
|
19
18
|
...
|
20
19
|
@html = RbST.new('/some/file.rst').to_html
|
20
|
+
# or
|
21
|
+
@latex = RbST.new('*hello*').to_latex
|
21
22
|
|
22
|
-
This takes the reStructuredText formatted file and converts it to
|
23
|
-
HTML. The first argument can be either a file or a string.
|
23
|
+
This takes the reStructuredText formatted file and converts it to either HTML or LaTeX. The first argument can be either a file or a string.
|
24
24
|
|
25
25
|
You can also use the `#convert` class method:
|
26
26
|
|
27
27
|
puts RbST.convert('/some/file.rst')
|
28
28
|
|
29
|
-
When no options are passed, the default behavior converts
|
30
|
-
reStructuredText to html. Options supported include
|
31
|
-
`:cloak_email_addresses` and `:strip_comments`, either of which can
|
32
|
-
be simply included as additional arguments.
|
29
|
+
When no options are passed, the default behavior converts reStructuredText to html using the default settings. Other arguments are simply converted into command line options, accepting symbols or strings for options without arguments and hashes of strings or symbols for options with arguments.
|
33
30
|
|
34
|
-
puts RbST.convert(".. a comment",
|
31
|
+
puts RbST.convert(".. a comment", 'strip-comments')
|
32
|
+
# => '<div class="document">\n</div>'
|
33
|
+
|
34
|
+
Options passed as string use hyphens while symbols use underscores. For instance, the above could also be written as:
|
35
|
+
|
36
|
+
puts RbST.convert(".. a comment", :strip_comments)
|
37
|
+
# => '<div class="document">\n</div>'
|
35
38
|
|
36
39
|
Document parts can also be specified with the `:parts` option.
|
37
40
|
|
38
|
-
puts RbST.convert("hello world", :part => :fragment)
|
41
|
+
puts RbST.convert("hello world", :part => :fragment)
|
42
|
+
# => '<p>hello world</p>'
|
43
|
+
|
44
|
+
By default, RbST uses the `html_body` part for HTML and the `whole` part for LaTeX.
|
39
45
|
|
40
|
-
|
46
|
+
Available options can be viewed using the `RbST.html_options` and `RbST.latex_options` class methods.
|
41
47
|
|
42
48
|
For more information on reStructuredText, see the
|
43
49
|
[ReST documentation](http://docutils.sourceforge.net/rst.html).
|
44
50
|
|
45
51
|
## Caveats
|
46
52
|
|
47
|
-
- Docutils is very slow. On my 2.5 GHz Core 2 Duo it takes over
|
48
|
-
half a second to convert the test file to HTML, including about 0.2s
|
49
|
-
to start up and 0.38s to process the input data.
|
53
|
+
- Docutils is very slow. On my 2.5 GHz Core 2 Duo it takes over half a second to convert the test file to HTML, including about 0.2s to start up and 0.38s to process the input data. In other words, this isn't the sort of thing you'd want to be using directly in a Rails view helper.
|
50
54
|
- This has only been tested on \*nix systems.
|
51
55
|
- Python 3 has not been tested.
|
52
56
|
|
@@ -54,11 +58,8 @@ For more information on reStructuredText, see the
|
|
54
58
|
|
55
59
|
- Fork the project.
|
56
60
|
- Make your feature addition or bug fix.
|
57
|
-
- Add tests for it. This is important so I don't break it in a
|
58
|
-
|
59
|
-
- Commit, do not mess with rakefile, version, or history. (if you
|
60
|
-
want to have your own version, that is fine but bump version in a
|
61
|
-
commit by itself I can ignore when I pull)
|
61
|
+
- Add tests for it. This is important so I don't break it in a future version unintentionally.
|
62
|
+
- Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
62
63
|
- Send me a pull request. Bonus points for topic branches.
|
63
64
|
|
64
65
|
## Copyright
|
data/Rakefile
CHANGED
@@ -8,9 +8,10 @@ begin
|
|
8
8
|
gem.summary = %Q{A simple Ruby wrapper for processing reStructuredText via Python's Docutils}
|
9
9
|
gem.description = %Q{A simple Ruby wrapper for processing reStructuredText via Python's Docutils}
|
10
10
|
gem.email = "wmelody@gmail.com"
|
11
|
-
gem.homepage = "http://
|
11
|
+
gem.homepage = "http://rdoc.info/projects/autodata/rbst"
|
12
12
|
gem.authors = ["William Melody"]
|
13
13
|
gem.add_development_dependency "thoughtbot-shoulda"
|
14
|
+
gem.add_development_dependency "mocha"
|
14
15
|
gem.add_dependency "open4"
|
15
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
17
|
end
|
data/RbST.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{RbST}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["William Melody"]
|
12
|
-
s.date = %q{2009-11-
|
12
|
+
s.date = %q{2009-11-04}
|
13
13
|
s.description = %q{A simple Ruby wrapper for processing reStructuredText via Python's Docutils}
|
14
14
|
s.email = %q{wmelody@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -25,13 +25,17 @@ Gem::Specification.new do |s|
|
|
25
25
|
"RbST.gemspec",
|
26
26
|
"VERSION",
|
27
27
|
"lib/rbst.rb",
|
28
|
-
"lib/rst2parts.py",
|
28
|
+
"lib/rst2parts/__init__.py",
|
29
|
+
"lib/rst2parts/rst2html.py",
|
30
|
+
"lib/rst2parts/rst2latex.py",
|
31
|
+
"lib/rst2parts/transform.py",
|
29
32
|
"test/files/test.html",
|
33
|
+
"test/files/test.latex",
|
30
34
|
"test/files/test.rst",
|
31
35
|
"test/test_helper.rb",
|
32
36
|
"test/test_rbst.rb"
|
33
37
|
]
|
34
|
-
s.homepage = %q{http://
|
38
|
+
s.homepage = %q{http://rdoc.info/projects/autodata/rbst}
|
35
39
|
s.rdoc_options = ["--charset=UTF-8"]
|
36
40
|
s.require_paths = ["lib"]
|
37
41
|
s.rubygems_version = %q{1.3.5}
|
@@ -47,13 +51,16 @@ Gem::Specification.new do |s|
|
|
47
51
|
|
48
52
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
49
53
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
54
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
50
55
|
s.add_runtime_dependency(%q<open4>, [">= 0"])
|
51
56
|
else
|
52
57
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
58
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
53
59
|
s.add_dependency(%q<open4>, [">= 0"])
|
54
60
|
end
|
55
61
|
else
|
56
62
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
63
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
57
64
|
s.add_dependency(%q<open4>, [">= 0"])
|
58
65
|
end
|
59
66
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/rbst.rb
CHANGED
@@ -1,30 +1,66 @@
|
|
1
1
|
require 'open4'
|
2
2
|
|
3
3
|
class RbST
|
4
|
-
|
4
|
+
|
5
|
+
# Takes a string or file path plus any additional options and converts the input.
|
5
6
|
def self.convert(*args)
|
6
7
|
new(*args).convert
|
7
8
|
end
|
8
|
-
|
9
|
+
|
10
|
+
# Print LaTeX-Specific Options, General Docutils Options and reStructuredText Parser Options.
|
11
|
+
def self.latex_options
|
12
|
+
new.print_options(:latex)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Print HTML-Specific Options, General Docutils Options and reStructuredText Parser Options.
|
16
|
+
def self.html_options
|
17
|
+
new.print_options(:html)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Takes a string or file path plus any additional options and creates a new converter object.
|
9
21
|
def initialize(*args)
|
10
22
|
target = args.shift
|
11
23
|
@target = File.exists?(target) ? File.read(target) : target rescue target
|
12
24
|
@options = args
|
13
25
|
end
|
14
26
|
|
15
|
-
def convert
|
16
|
-
|
17
|
-
execute "python #{executable}" + convert_options
|
27
|
+
def convert(writer = :html) # :nodoc:
|
28
|
+
execute "python #{RbST.executable(writer)}" + convert_options
|
18
29
|
end
|
19
30
|
alias_method :to_s, :convert
|
20
31
|
|
32
|
+
# Converts the object's input to HTML.
|
21
33
|
def to_html
|
22
|
-
|
23
|
-
|
34
|
+
convert(:html)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Converts the object's input to LaTeX.
|
38
|
+
def to_latex
|
39
|
+
convert(:latex)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Formats and prints the options from the docutils help in the way they'd be specified in RbST: strings, symbols and hashes.
|
43
|
+
def print_options(format)
|
44
|
+
help = execute("python #{RbST.executable(format)} --help")
|
45
|
+
# non-hyphenated long options to symbols
|
46
|
+
help.gsub!(/(\-\-)([A-Za-z0-9]+)([=|\s])/, ':\2\3')
|
47
|
+
# hyphenated long options to quoted strings
|
48
|
+
help.gsub!(/(\-\-)([\w|\-]+)(\n)?[^$|^=|\]]?/, '\'\2\'\3')
|
49
|
+
# equal to hashrocket
|
50
|
+
help.gsub!(/\=/, ' => ')
|
51
|
+
# hort options to symbols
|
52
|
+
help.gsub!(/([^\w])\-(\w)([^\w])/, '\1:\2\1')
|
53
|
+
# short options with args get a hashrocket
|
54
|
+
help.gsub!(/(:\w) </, '\1 => <')
|
55
|
+
puts help
|
24
56
|
end
|
25
57
|
|
26
58
|
private
|
27
|
-
|
59
|
+
|
60
|
+
def self.executable(writer = :html)
|
61
|
+
File.join(File.dirname(__FILE__), "rst2parts", "rst2#{writer}.py")
|
62
|
+
end
|
63
|
+
|
28
64
|
def execute(command)
|
29
65
|
output = ''
|
30
66
|
Open4::popen4(command) do |pid, stdin, stdout, stderr|
|
@@ -38,12 +74,17 @@ private
|
|
38
74
|
def convert_options
|
39
75
|
@options.inject('') do |string, opt|
|
40
76
|
string + if opt.respond_to?(:each_pair)
|
41
|
-
opt
|
42
|
-
s + (flag.to_s.length == 1 ? " -#{flag} #{val}" : " --#{flag}=#{val}")
|
43
|
-
end
|
77
|
+
convert_opts_with_args(opt)
|
44
78
|
else
|
45
|
-
opt.to_s.length == 1 ? " -#{opt}" : " --#{opt}"
|
79
|
+
opt.to_s.length == 1 ? " -#{opt}" : " --#{opt.to_s.gsub(/_/, '-')}"
|
46
80
|
end
|
47
81
|
end
|
48
82
|
end
|
83
|
+
|
84
|
+
def convert_opts_with_args(opt)
|
85
|
+
opt.inject('') do |string, (flag, val)|
|
86
|
+
flag = flag.to_s.gsub(/_/, '-')
|
87
|
+
string + (flag.length == 1 ? " -#{flag} #{val}" : " --#{flag}=#{val}")
|
88
|
+
end
|
89
|
+
end
|
49
90
|
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
try:
|
4
|
+
import locale
|
5
|
+
locale.setlocale(locale.LC_ALL, '')
|
6
|
+
except:
|
7
|
+
pass
|
8
|
+
|
9
|
+
from transform import transform
|
10
|
+
from docutils.writers.html4css1 import Writer
|
11
|
+
|
12
|
+
def main():
|
13
|
+
return transform(writer=Writer(), part='html_body')
|
14
|
+
|
15
|
+
if __name__ == '__main__':
|
16
|
+
print(main())
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
|
3
|
+
try:
|
4
|
+
import locale
|
5
|
+
locale.setlocale(locale.LC_ALL, '')
|
6
|
+
except:
|
7
|
+
pass
|
8
|
+
|
9
|
+
from transform import transform
|
10
|
+
from docutils.writers.latex2e import Writer
|
11
|
+
|
12
|
+
def main():
|
13
|
+
return transform(writer=Writer(), part='whole')
|
14
|
+
|
15
|
+
if __name__ == '__main__':
|
16
|
+
print(main())
|
17
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import sys
|
2
|
+
from docutils.core import publish_parts
|
3
|
+
from optparse import OptionParser
|
4
|
+
from docutils.frontend import OptionParser as DocutilsOptionParser
|
5
|
+
from docutils.parsers.rst import Parser
|
6
|
+
|
7
|
+
def transform(writer=None, part=None):
|
8
|
+
p = OptionParser(add_help_option=False)
|
9
|
+
|
10
|
+
# Collect all the command line options
|
11
|
+
docutils_parser = DocutilsOptionParser(components=(writer, Parser()))
|
12
|
+
for group in docutils_parser.option_groups:
|
13
|
+
p.add_option_group(group.title, None).add_options(group.option_list)
|
14
|
+
|
15
|
+
p.add_option('--part', default=part)
|
16
|
+
|
17
|
+
opts, args = p.parse_args()
|
18
|
+
|
19
|
+
settings = dict({
|
20
|
+
'file_insertion_enabled': False,
|
21
|
+
'raw_enabled': False,
|
22
|
+
}, **opts.__dict__)
|
23
|
+
|
24
|
+
if len(args) == 1:
|
25
|
+
try:
|
26
|
+
content = open(args[0], 'r').read()
|
27
|
+
except IOError:
|
28
|
+
content = args[0]
|
29
|
+
else:
|
30
|
+
content = sys.stdin.read()
|
31
|
+
|
32
|
+
parts = publish_parts(
|
33
|
+
source=content,
|
34
|
+
settings_overrides=settings,
|
35
|
+
writer=writer,
|
36
|
+
)
|
37
|
+
|
38
|
+
if opts.part in parts:
|
39
|
+
return parts[opts.part]
|
40
|
+
return ''
|
@@ -0,0 +1,572 @@
|
|
1
|
+
\documentclass[10pt,a4paper,english]{article}
|
2
|
+
\usepackage{babel}
|
3
|
+
\usepackage{ae}
|
4
|
+
\usepackage{aeguill}
|
5
|
+
\usepackage{shortvrb}
|
6
|
+
\usepackage{ucs}
|
7
|
+
\usepackage[utf8x]{inputenc}
|
8
|
+
\usepackage{tabularx}
|
9
|
+
\usepackage{longtable}
|
10
|
+
\setlength{\extrarowheight}{2pt}
|
11
|
+
\usepackage{amsmath}
|
12
|
+
\usepackage{graphicx}
|
13
|
+
\usepackage{color}
|
14
|
+
\usepackage{multirow}
|
15
|
+
\usepackage{ifthen}
|
16
|
+
\usepackage[DIV12]{typearea}
|
17
|
+
% generated by Docutils <http://docutils.sourceforge.net/>
|
18
|
+
\newlength{\admonitionwidth}
|
19
|
+
\setlength{\admonitionwidth}{0.9\textwidth}
|
20
|
+
\newlength{\docinfowidth}
|
21
|
+
\setlength{\docinfowidth}{0.9\textwidth}
|
22
|
+
\newlength{\locallinewidth}
|
23
|
+
\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
|
24
|
+
\newenvironment{optionlist}[1]
|
25
|
+
{\begin{list}{}
|
26
|
+
{\setlength{\labelwidth}{#1}
|
27
|
+
\setlength{\rightmargin}{1cm}
|
28
|
+
\setlength{\leftmargin}{\rightmargin}
|
29
|
+
\addtolength{\leftmargin}{\labelwidth}
|
30
|
+
\addtolength{\leftmargin}{\labelsep}
|
31
|
+
\renewcommand{\makelabel}{\optionlistlabel}}
|
32
|
+
}{\end{list}}
|
33
|
+
\newlength{\lineblockindentation}
|
34
|
+
\setlength{\lineblockindentation}{2.5em}
|
35
|
+
\newenvironment{lineblock}[1]
|
36
|
+
{\begin{list}{}
|
37
|
+
{\setlength{\partopsep}{\parskip}
|
38
|
+
\addtolength{\partopsep}{\baselineskip}
|
39
|
+
\topsep0pt\itemsep0.15\baselineskip\parsep0pt
|
40
|
+
\leftmargin#1}
|
41
|
+
\raggedright}
|
42
|
+
{\end{list}}
|
43
|
+
% begin: floats for footnotes tweaking.
|
44
|
+
\setlength{\floatsep}{0.5em}
|
45
|
+
\setlength{\textfloatsep}{\fill}
|
46
|
+
\addtolength{\textfloatsep}{3em}
|
47
|
+
\renewcommand{\textfraction}{0.5}
|
48
|
+
\renewcommand{\topfraction}{0.5}
|
49
|
+
\renewcommand{\bottomfraction}{0.5}
|
50
|
+
\setcounter{totalnumber}{50}
|
51
|
+
\setcounter{topnumber}{50}
|
52
|
+
\setcounter{bottomnumber}{50}
|
53
|
+
% end floats for footnotes
|
54
|
+
% some commands, that could be overwritten in the style file.
|
55
|
+
\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}}
|
56
|
+
\newcommand{\titlereference}[1]{\textsl{#1}}
|
57
|
+
% end of "some commands"
|
58
|
+
\ifthenelse{\isundefined{\hypersetup}}{
|
59
|
+
\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
|
60
|
+
}{}
|
61
|
+
\title{The reStructuredText Cheat Sheet: Syntax Reminders}
|
62
|
+
\author{}
|
63
|
+
\date{}
|
64
|
+
\hypersetup{
|
65
|
+
pdftitle={The reStructuredText Cheat Sheet: Syntax Reminders},
|
66
|
+
pdfauthor={David Goodger {\textless}goodger@python.org{\textgreater}}
|
67
|
+
}
|
68
|
+
\raggedbottom
|
69
|
+
\begin{document}
|
70
|
+
\maketitle
|
71
|
+
%___________________________________________________________________________
|
72
|
+
\begin{center}
|
73
|
+
\begin{tabularx}{\docinfowidth}{lX}
|
74
|
+
\textbf{Info}: &
|
75
|
+
See {\textless}http://docutils.sf.net/rst.html{\textgreater} for introductory docs. \\
|
76
|
+
\textbf{Author}: &
|
77
|
+
David Goodger {\textless}\href{mailto:goodger@python.org}{goodger@python.org}{\textgreater} \\
|
78
|
+
\textbf{Date}: &
|
79
|
+
2006-01-23 \\
|
80
|
+
\textbf{Revision}: &
|
81
|
+
4321 \\
|
82
|
+
\textbf{Description}: &
|
83
|
+
This is a ``docinfo block'', or bibliographic field list \\
|
84
|
+
\end{tabularx}
|
85
|
+
\end{center}
|
86
|
+
|
87
|
+
\setlength{\locallinewidth}{\linewidth}
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
%___________________________________________________________________________
|
93
|
+
|
94
|
+
\hypertarget{section-structure}{}
|
95
|
+
\pdfbookmark[0]{Section Structure}{section-structure}
|
96
|
+
\section*{Section Structure}
|
97
|
+
\label{section-structure}
|
98
|
+
|
99
|
+
Section titles are underlined or overlined {\&} underlined.
|
100
|
+
|
101
|
+
|
102
|
+
%___________________________________________________________________________
|
103
|
+
|
104
|
+
\hypertarget{body-elements}{}
|
105
|
+
\pdfbookmark[0]{Body Elements}{body-elements}
|
106
|
+
\section*{Body Elements}
|
107
|
+
\label{body-elements}
|
108
|
+
|
109
|
+
Grid table:
|
110
|
+
|
111
|
+
\leavevmode
|
112
|
+
\begin{longtable}[c]{|p{0.389\locallinewidth}|p{0.424\locallinewidth}|}
|
113
|
+
\hline
|
114
|
+
|
115
|
+
Paragraphs are flush-left,
|
116
|
+
separated by blank lines.
|
117
|
+
\begin{quote}
|
118
|
+
|
119
|
+
Block quotes are indented.
|
120
|
+
\end{quote}
|
121
|
+
& \multirow{2}{0.42\locallinewidth}{
|
122
|
+
Literal block, preceded by ``::'':
|
123
|
+
|
124
|
+
{\ttfamily \raggedright \noindent
|
125
|
+
Indented
|
126
|
+
}
|
127
|
+
|
128
|
+
or:
|
129
|
+
|
130
|
+
{\ttfamily \raggedright \noindent
|
131
|
+
>~Quoted
|
132
|
+
}
|
133
|
+
} \\
|
134
|
+
\cline{1-1}
|
135
|
+
\begin{verbatim}>>> print 'Doctest block'
|
136
|
+
Doctest block\end{verbatim}
|
137
|
+
& \\
|
138
|
+
\hline
|
139
|
+
\multicolumn{2}{|l|}{
|
140
|
+
\begin{lineblock}{0em}
|
141
|
+
\item[] Line blocks preserve line breaks {\&} indents. {[}new in 0.3.6{]}
|
142
|
+
\item[]
|
143
|
+
\begin{lineblock}{\lineblockindentation}
|
144
|
+
\item[] Useful for addresses, verse, and adornment-free lists; long
|
145
|
+
lines can be wrapped with continuation lines.
|
146
|
+
\end{lineblock}
|
147
|
+
\end{lineblock}
|
148
|
+
} \\
|
149
|
+
\hline
|
150
|
+
\end{longtable}
|
151
|
+
|
152
|
+
Simple tables:
|
153
|
+
|
154
|
+
\leavevmode
|
155
|
+
\begin{longtable}[c]{|p{0.203\locallinewidth}|p{0.714\locallinewidth}|}
|
156
|
+
\hline
|
157
|
+
\textbf{
|
158
|
+
List Type
|
159
|
+
} & \textbf{
|
160
|
+
Examples
|
161
|
+
} \\
|
162
|
+
\hline
|
163
|
+
\endhead
|
164
|
+
|
165
|
+
Bullet list
|
166
|
+
& \begin{itemize}
|
167
|
+
\item {}
|
168
|
+
items begin with ``-'', ``+'', or ``*''
|
169
|
+
|
170
|
+
\end{itemize}
|
171
|
+
\\
|
172
|
+
\hline
|
173
|
+
|
174
|
+
Enumerated list
|
175
|
+
& \newcounter{listcnt0}
|
176
|
+
\begin{list}{\arabic{listcnt0}.}
|
177
|
+
{
|
178
|
+
\usecounter{listcnt0}
|
179
|
+
\setlength{\rightmargin}{\leftmargin}
|
180
|
+
}
|
181
|
+
\item {}
|
182
|
+
items use any variation of ``1.'', ``A)'', and ``(i)''
|
183
|
+
|
184
|
+
\item {}
|
185
|
+
also auto-enumerated
|
186
|
+
|
187
|
+
\end{list}
|
188
|
+
\\
|
189
|
+
\hline
|
190
|
+
|
191
|
+
Definition list
|
192
|
+
& \begin{description}
|
193
|
+
\item[{Term is flush-left}] \leavevmode (\textbf{optional classifier})
|
194
|
+
|
195
|
+
Definition is indented, no blank line between
|
196
|
+
|
197
|
+
\end{description}
|
198
|
+
\\
|
199
|
+
\hline
|
200
|
+
|
201
|
+
Field list
|
202
|
+
& \begin{quote}
|
203
|
+
\begin{description}
|
204
|
+
\item [field name:]
|
205
|
+
field body
|
206
|
+
|
207
|
+
|
208
|
+
\end{description}
|
209
|
+
\end{quote}
|
210
|
+
\\
|
211
|
+
\hline
|
212
|
+
|
213
|
+
Option list
|
214
|
+
& \begin{optionlist}{3cm}
|
215
|
+
\item [-o]
|
216
|
+
at least 2 spaces between option {\&} description
|
217
|
+
\end{optionlist}
|
218
|
+
\\
|
219
|
+
\hline
|
220
|
+
\end{longtable}
|
221
|
+
|
222
|
+
\leavevmode
|
223
|
+
\begin{longtable}[c]{|p{0.203\locallinewidth}|p{0.714\locallinewidth}|}
|
224
|
+
\hline
|
225
|
+
\textbf{
|
226
|
+
Explicit Markup
|
227
|
+
} & \textbf{
|
228
|
+
Examples (visible in the \href{cheatsheet.txt}{text source})
|
229
|
+
} \\
|
230
|
+
\hline
|
231
|
+
\endhead
|
232
|
+
|
233
|
+
Footnote
|
234
|
+
& \begin{figure}[b]\hypertarget{id1}$^{1}$
|
235
|
+
Manually numbered or {[}{\#}{]} auto-numbered
|
236
|
+
(even {[}{\#}labelled{]}) or {[}*{]} auto-symbol
|
237
|
+
\end{figure}
|
238
|
+
\\
|
239
|
+
\hline
|
240
|
+
|
241
|
+
Citation
|
242
|
+
& \begin{figure}[b]\hypertarget{cit2002}[CIT2002]
|
243
|
+
A citation.
|
244
|
+
\end{figure}
|
245
|
+
\\
|
246
|
+
\hline
|
247
|
+
|
248
|
+
Hyperlink Target
|
249
|
+
& \hypertarget{internal-target}{} \\
|
250
|
+
\hline
|
251
|
+
|
252
|
+
Anonymous Target
|
253
|
+
& \\
|
254
|
+
\hline
|
255
|
+
|
256
|
+
Directive (``::'')
|
257
|
+
&
|
258
|
+
\includegraphics{images/biohazard.png}
|
259
|
+
\\
|
260
|
+
\hline
|
261
|
+
|
262
|
+
Substitution Def
|
263
|
+
& \\
|
264
|
+
\hline
|
265
|
+
|
266
|
+
Comment
|
267
|
+
& % is anything else
|
268
|
+
\\
|
269
|
+
\hline
|
270
|
+
|
271
|
+
Empty Comment
|
272
|
+
&
|
273
|
+
(``..'' on a line by itself, with blank lines before {\&} after,
|
274
|
+
used to separate indentation contexts)
|
275
|
+
\\
|
276
|
+
\hline
|
277
|
+
\end{longtable}
|
278
|
+
|
279
|
+
|
280
|
+
%___________________________________________________________________________
|
281
|
+
|
282
|
+
\hypertarget{inline-markup}{}
|
283
|
+
\pdfbookmark[0]{Inline Markup}{inline-markup}
|
284
|
+
\section*{Inline Markup}
|
285
|
+
\label{inline-markup}
|
286
|
+
|
287
|
+
\emph{emphasis}; \textbf{strong emphasis}; \titlereference{interpreted text}; \emph{interpreted text
|
288
|
+
with role}; \texttt{inline literal text}; standalone hyperlink,
|
289
|
+
\href{http://docutils.sourceforge.net}{http://docutils.sourceforge.net}; named reference, \href{http://docutils.sf.net/rst.html}{reStructuredText};
|
290
|
+
\href{http://docutils.sf.net/docs/ref/rst/restructuredtext.html}{anonymous reference}; footnote reference,\raisebox{.5em}[0em]{\scriptsize\hyperlink{id1}{1}}; citation reference,
|
291
|
+
[\hyperlink{cit2002}{CIT2002}]; like an inline directive; \hypertarget{inline-internal-target}{inline internal target}.
|
292
|
+
|
293
|
+
|
294
|
+
%___________________________________________________________________________
|
295
|
+
|
296
|
+
\hypertarget{directive-quick-reference}{}
|
297
|
+
\pdfbookmark[0]{Directive Quick Reference}{directive-quick-reference}
|
298
|
+
\section*{Directive Quick Reference}
|
299
|
+
\label{directive-quick-reference}
|
300
|
+
|
301
|
+
See {\textless}\href{http://docutils.sf.net/docs/ref/rst/directives.html}{http://docutils.sf.net/docs/ref/rst/directives.html}{\textgreater} for full info.
|
302
|
+
|
303
|
+
\leavevmode
|
304
|
+
\begin{longtable}[c]{|p{0.203\locallinewidth}|p{0.714\locallinewidth}|}
|
305
|
+
\hline
|
306
|
+
\textbf{
|
307
|
+
Directive Name
|
308
|
+
} & \textbf{
|
309
|
+
Description (Docutils version added to, in {[}brackets{]})
|
310
|
+
} \\
|
311
|
+
\hline
|
312
|
+
\endhead
|
313
|
+
|
314
|
+
attention
|
315
|
+
&
|
316
|
+
Specific admonition; also ``caution'', ``danger'',
|
317
|
+
``error'', ``hint'', ``important'', ``note'', ``tip'', ``warning''
|
318
|
+
\\
|
319
|
+
\hline
|
320
|
+
|
321
|
+
admonition
|
322
|
+
&
|
323
|
+
Generic titled admonition: \texttt{.. admonition:: By The Way}
|
324
|
+
\\
|
325
|
+
\hline
|
326
|
+
|
327
|
+
image
|
328
|
+
&
|
329
|
+
\texttt{.. image:: picture.png}; many options possible
|
330
|
+
\\
|
331
|
+
\hline
|
332
|
+
|
333
|
+
figure
|
334
|
+
&
|
335
|
+
Like ``image'', but with optional caption and legend
|
336
|
+
\\
|
337
|
+
\hline
|
338
|
+
|
339
|
+
topic
|
340
|
+
&
|
341
|
+
\texttt{.. topic:: Title}; like a mini section
|
342
|
+
\\
|
343
|
+
\hline
|
344
|
+
|
345
|
+
sidebar
|
346
|
+
&
|
347
|
+
\texttt{.. sidebar:: Title}; like a mini parallel document
|
348
|
+
\\
|
349
|
+
\hline
|
350
|
+
|
351
|
+
parsed-literal
|
352
|
+
&
|
353
|
+
A literal block with parsed inline markup
|
354
|
+
\\
|
355
|
+
\hline
|
356
|
+
|
357
|
+
rubric
|
358
|
+
&
|
359
|
+
\texttt{.. rubric:: Informal Heading}
|
360
|
+
\\
|
361
|
+
\hline
|
362
|
+
|
363
|
+
epigraph
|
364
|
+
&
|
365
|
+
Block quote with class=``epigraph''
|
366
|
+
\\
|
367
|
+
\hline
|
368
|
+
|
369
|
+
highlights
|
370
|
+
&
|
371
|
+
Block quote with class=``highlights''
|
372
|
+
\\
|
373
|
+
\hline
|
374
|
+
|
375
|
+
pull-quote
|
376
|
+
&
|
377
|
+
Block quote with class=``pull-quote''
|
378
|
+
\\
|
379
|
+
\hline
|
380
|
+
|
381
|
+
compound
|
382
|
+
&
|
383
|
+
Compound paragraphs {[}0.3.6{]}
|
384
|
+
\\
|
385
|
+
\hline
|
386
|
+
|
387
|
+
container
|
388
|
+
&
|
389
|
+
Generic block-level container element {[}0.3.10{]}
|
390
|
+
\\
|
391
|
+
\hline
|
392
|
+
|
393
|
+
table
|
394
|
+
&
|
395
|
+
Create a titled table {[}0.3.1{]}
|
396
|
+
\\
|
397
|
+
\hline
|
398
|
+
|
399
|
+
list-table
|
400
|
+
&
|
401
|
+
Create a table from a uniform two-level bullet list {[}0.3.8{]}
|
402
|
+
\\
|
403
|
+
\hline
|
404
|
+
|
405
|
+
csv-table
|
406
|
+
&
|
407
|
+
Create a table from CSV data (requires Python 2.3+) {[}0.3.4{]}
|
408
|
+
\\
|
409
|
+
\hline
|
410
|
+
|
411
|
+
contents
|
412
|
+
&
|
413
|
+
Generate a table of contents
|
414
|
+
\\
|
415
|
+
\hline
|
416
|
+
|
417
|
+
sectnum
|
418
|
+
&
|
419
|
+
Automatically number sections, subsections, etc.
|
420
|
+
\\
|
421
|
+
\hline
|
422
|
+
|
423
|
+
header, footer
|
424
|
+
&
|
425
|
+
Create document decorations {[}0.3.8{]}
|
426
|
+
\\
|
427
|
+
\hline
|
428
|
+
|
429
|
+
target-notes
|
430
|
+
&
|
431
|
+
Create an explicit footnote for each external target
|
432
|
+
\\
|
433
|
+
\hline
|
434
|
+
|
435
|
+
meta
|
436
|
+
&
|
437
|
+
HTML-specific metadata
|
438
|
+
\\
|
439
|
+
\hline
|
440
|
+
|
441
|
+
include
|
442
|
+
&
|
443
|
+
Read an external reST file as if it were inline
|
444
|
+
\\
|
445
|
+
\hline
|
446
|
+
|
447
|
+
raw
|
448
|
+
&
|
449
|
+
Non-reST data passed untouched to the Writer
|
450
|
+
\\
|
451
|
+
\hline
|
452
|
+
|
453
|
+
replace
|
454
|
+
&
|
455
|
+
Replacement text for substitution definitions
|
456
|
+
\\
|
457
|
+
\hline
|
458
|
+
|
459
|
+
unicode
|
460
|
+
&
|
461
|
+
Unicode character code conversion for substitution defs
|
462
|
+
\\
|
463
|
+
\hline
|
464
|
+
|
465
|
+
date
|
466
|
+
&
|
467
|
+
Generates today's date; for substitution defs
|
468
|
+
\\
|
469
|
+
\hline
|
470
|
+
|
471
|
+
class
|
472
|
+
&
|
473
|
+
Set a ``class'' attribute on the next element
|
474
|
+
\\
|
475
|
+
\hline
|
476
|
+
|
477
|
+
role
|
478
|
+
&
|
479
|
+
Create a custom interpreted text role {[}0.3.2{]}
|
480
|
+
\\
|
481
|
+
\hline
|
482
|
+
|
483
|
+
default-role
|
484
|
+
&
|
485
|
+
Set the default interpreted text role {[}0.3.10{]}
|
486
|
+
\\
|
487
|
+
\hline
|
488
|
+
|
489
|
+
title
|
490
|
+
&
|
491
|
+
Set the metadata document title {[}0.3.10{]}
|
492
|
+
\\
|
493
|
+
\hline
|
494
|
+
\end{longtable}
|
495
|
+
|
496
|
+
|
497
|
+
%___________________________________________________________________________
|
498
|
+
|
499
|
+
\hypertarget{interpreted-text-role-quick-reference}{}
|
500
|
+
\pdfbookmark[0]{Interpreted Text Role Quick Reference}{interpreted-text-role-quick-reference}
|
501
|
+
\section*{Interpreted Text Role Quick Reference}
|
502
|
+
\label{interpreted-text-role-quick-reference}
|
503
|
+
|
504
|
+
See {\textless}\href{http://docutils.sf.net/docs/ref/rst/roles.html}{http://docutils.sf.net/docs/ref/rst/roles.html}{\textgreater} for full info.
|
505
|
+
|
506
|
+
\leavevmode
|
507
|
+
\begin{longtable}[c]{|p{0.203\locallinewidth}|p{0.726\locallinewidth}|}
|
508
|
+
\hline
|
509
|
+
\textbf{
|
510
|
+
Role Name
|
511
|
+
} & \textbf{
|
512
|
+
Description
|
513
|
+
} \\
|
514
|
+
\hline
|
515
|
+
\endhead
|
516
|
+
|
517
|
+
emphasis
|
518
|
+
&
|
519
|
+
Equivalent to \emph{emphasis}
|
520
|
+
\\
|
521
|
+
\hline
|
522
|
+
|
523
|
+
literal
|
524
|
+
&
|
525
|
+
Equivalent to \texttt{literal} but processes backslash escapes
|
526
|
+
\\
|
527
|
+
\hline
|
528
|
+
|
529
|
+
PEP
|
530
|
+
&
|
531
|
+
Reference to a numbered Python Enhancement Proposal
|
532
|
+
\\
|
533
|
+
\hline
|
534
|
+
|
535
|
+
RFC
|
536
|
+
&
|
537
|
+
Reference to a numbered Internet Request For Comments
|
538
|
+
\\
|
539
|
+
\hline
|
540
|
+
|
541
|
+
raw
|
542
|
+
&
|
543
|
+
For non-reST data; cannot be used directly (see docs) {[}0.3.6{]}
|
544
|
+
\\
|
545
|
+
\hline
|
546
|
+
|
547
|
+
strong
|
548
|
+
&
|
549
|
+
Equivalent to \textbf{strong}
|
550
|
+
\\
|
551
|
+
\hline
|
552
|
+
|
553
|
+
sub
|
554
|
+
&
|
555
|
+
Subscript
|
556
|
+
\\
|
557
|
+
\hline
|
558
|
+
|
559
|
+
sup
|
560
|
+
&
|
561
|
+
Superscript
|
562
|
+
\\
|
563
|
+
\hline
|
564
|
+
|
565
|
+
title
|
566
|
+
&
|
567
|
+
Title reference (book, etc.); standard default role
|
568
|
+
\\
|
569
|
+
\hline
|
570
|
+
\end{longtable}
|
571
|
+
|
572
|
+
\end{document}
|
data/test/test_rbst.rb
CHANGED
@@ -3,13 +3,17 @@ require 'mocha'
|
|
3
3
|
|
4
4
|
class TestRbST < Test::Unit::TestCase
|
5
5
|
def setup
|
6
|
-
|
7
|
-
|
6
|
+
[:rst, :html, :latex].each do |f|
|
7
|
+
instance_variable_set(
|
8
|
+
:"@#{f}_file",
|
9
|
+
File.join(File.dirname(__FILE__), 'files', "test.#{f}")
|
10
|
+
)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
should "call bare rest2parts when passed no options" do
|
11
15
|
converter = RbST.new(@rst_file)
|
12
|
-
converter.expects(:execute).with('python ./test/../lib/rst2parts.py').returns(true)
|
16
|
+
converter.expects(:execute).with('python ./test/../lib/rst2parts/rst2html.py').returns(true)
|
13
17
|
assert converter.convert
|
14
18
|
end
|
15
19
|
|
@@ -18,17 +22,22 @@ class TestRbST < Test::Unit::TestCase
|
|
18
22
|
assert_equal html, File.read(@html_file)
|
19
23
|
end
|
20
24
|
|
25
|
+
should "convert ReST to LaTeX" do
|
26
|
+
latex = RbST.new(@rst_file).to_latex
|
27
|
+
assert_equal latex, File.read(@latex_file)
|
28
|
+
end
|
29
|
+
|
21
30
|
should "recognize strip_comments option" do
|
22
31
|
html_with_comment = RbST.convert(".. comment")
|
23
32
|
assert_equal html_with_comment, %Q{<div class="document">\n<!-- comment -->\n</div>}
|
24
|
-
html_without_comment = RbST.convert(".. comment",
|
33
|
+
html_without_comment = RbST.convert(".. comment", 'strip-comments')
|
25
34
|
assert_equal html_without_comment, %Q{<div class="document">\n</div>}
|
26
35
|
end
|
27
36
|
|
28
37
|
should "recognize cloak_email_addresses option" do
|
29
38
|
html_with_uncloaked_email = RbST.convert("steve@mac.com")
|
30
39
|
assert_equal %Q{<div class="document">\n<p><a class="reference external" href="mailto:steve@mac.com">steve@mac.com</a></p>\n</div>}, html_with_uncloaked_email
|
31
|
-
html_with_cloaked_email = RbST.convert("steve@mac.com",
|
40
|
+
html_with_cloaked_email = RbST.convert("steve@mac.com", 'cloak-email-addresses')
|
32
41
|
assert_equal %Q{<div class="document">\n<p><a class="reference external" href="mailto:steve%40mac.com">steve<span>@</span>mac<span>.</span>com</a></p>\n</div>}, html_with_cloaked_email
|
33
42
|
end
|
34
43
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: RbST
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Melody
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-07 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mocha
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
36
|
name: open4
|
27
37
|
type: :runtime
|
@@ -50,13 +60,17 @@ files:
|
|
50
60
|
- RbST.gemspec
|
51
61
|
- VERSION
|
52
62
|
- lib/rbst.rb
|
53
|
-
- lib/rst2parts.py
|
63
|
+
- lib/rst2parts/__init__.py
|
64
|
+
- lib/rst2parts/rst2html.py
|
65
|
+
- lib/rst2parts/rst2latex.py
|
66
|
+
- lib/rst2parts/transform.py
|
54
67
|
- test/files/test.html
|
68
|
+
- test/files/test.latex
|
55
69
|
- test/files/test.rst
|
56
70
|
- test/test_helper.rb
|
57
71
|
- test/test_rbst.rb
|
58
72
|
has_rdoc: true
|
59
|
-
homepage: http://
|
73
|
+
homepage: http://rdoc.info/projects/autodata/rbst
|
60
74
|
licenses: []
|
61
75
|
|
62
76
|
post_install_message:
|
data/lib/rst2parts.py
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
|
3
|
-
import sys
|
4
|
-
from optparse import OptionParser
|
5
|
-
from docutils.core import publish_parts
|
6
|
-
|
7
|
-
def main():
|
8
|
-
p = OptionParser()
|
9
|
-
|
10
|
-
p.add_option('--cloak_email_addresses', action="store_true", default=False)
|
11
|
-
p.add_option('--strip_comments', action="store_true", default=False)
|
12
|
-
p.add_option('--writer_name', default="html")
|
13
|
-
p.add_option('--part', default="html_body")
|
14
|
-
|
15
|
-
opts, args = p.parse_args()
|
16
|
-
|
17
|
-
settings = {
|
18
|
-
'file_insertion_enabled': False,
|
19
|
-
'raw_enabled': False,
|
20
|
-
'cloak_email_addresses': opts.cloak_email_addresses,
|
21
|
-
'strip_comments': opts.strip_comments,
|
22
|
-
}
|
23
|
-
|
24
|
-
if len(args) == 1:
|
25
|
-
try:
|
26
|
-
content = open(args[0], 'r').read()
|
27
|
-
except IOError:
|
28
|
-
content = args[0]
|
29
|
-
else:
|
30
|
-
content = sys.stdin.read()
|
31
|
-
|
32
|
-
parts = publish_parts(
|
33
|
-
source=content,
|
34
|
-
settings_overrides=settings,
|
35
|
-
writer_name=opts.writer_name,
|
36
|
-
)
|
37
|
-
|
38
|
-
if opts.part in parts:
|
39
|
-
return parts[opts.part]
|
40
|
-
return ''
|
41
|
-
|
42
|
-
if __name__ == '__main__':
|
43
|
-
print(main())
|