mdoc 0.0.3 → 0.0.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/.rubocop.yml +2 -0
- data/README.md +134 -47
- data/bin/mdoc +11 -32
- data/lib/mdoc/document/kramdown.rb +25 -0
- data/lib/mdoc/document.rb +87 -0
- data/lib/mdoc/meta.rb +14 -0
- data/lib/mdoc/options.rb +104 -0
- data/lib/mdoc/pipeline.rb +59 -0
- data/lib/mdoc/processor/add_title.rb +15 -0
- data/lib/mdoc/processor/add_toc.rb +11 -0
- data/lib/mdoc/processor/smart_code_block.rb +37 -0
- data/lib/mdoc/processor.rb +21 -0
- data/lib/mdoc/version.rb +3 -4
- data/lib/mdoc/writer.rb +18 -0
- data/lib/mdoc.rb +143 -2
- data/mdoc.gemspec +19 -19
- data/spec/add_title_spec.rb +10 -0
- data/spec/add_toc_spec.rb +12 -0
- data/spec/document_spec.rb +34 -0
- data/spec/execute_spec.rb +12 -0
- data/spec/find_doc_type_spec.rb +14 -0
- data/spec/fixtures/README.md +135 -0
- data/spec/fixtures/config/mdoc_a.cnf +1 -0
- data/spec/fixtures/config/mdoc_b.cnf +1 -0
- data/spec/fixtures/executes/a +0 -0
- data/spec/fixtures/executes/b +0 -0
- data/spec/fixtures/executes/c +0 -0
- data/spec/fixtures/general.txt +10 -0
- data/spec/fixtures/multikeys.html +18 -0
- data/{examples → spec/fixtures}/multikeys.md +10 -8
- data/{examples → spec/fixtures}/original.md +10 -10
- data/{examples → spec/fixtures}/pandoc.md +7 -7
- data/spec/fixtures/process.test.md +11 -0
- data/spec/fixtures/templates/default.html.erb +0 -0
- data/spec/fixtures/templates/pandoc.html.erb +0 -0
- data/spec/get_class_spec.rb +35 -0
- data/spec/kramdown_spec.rb +10 -0
- data/spec/meta_spec.rb +6 -0
- data/spec/options_spec.rb +66 -0
- data/spec/pipeline_spec.rb +95 -0
- data/spec/smart_code_block_spec.rb +10 -0
- data/spec/spec_helper.rb +40 -7
- data/spec/tpl_out_spec.rb +19 -0
- data/templates/default.html.erb +17 -0
- metadata +63 -25
- data/ROADMAP +0 -24
- data/config/members.yml +0 -16
- data/docs/css/jsgantt.css +0 -53
- data/docs/gantt.html +0 -237
- data/docs/js/jsgantt.js +0 -1681
- data/lib/mdoc/convert.rb +0 -92
- data/lib/mdoc/parser.rb +0 -80
- data/spec/parser_spec.rb +0 -32
data/lib/mdoc.rb
CHANGED
@@ -1,2 +1,143 @@
|
|
1
|
-
require 'mdoc/
|
2
|
-
require 'mdoc/
|
1
|
+
require 'mdoc/version'
|
2
|
+
require 'mdoc/options'
|
3
|
+
require 'mdoc/meta'
|
4
|
+
require 'mdoc/document'
|
5
|
+
require 'mdoc/document/kramdown'
|
6
|
+
require 'mdoc/processor'
|
7
|
+
require 'mdoc/processor/smart_code_block'
|
8
|
+
require 'mdoc/processor/add_title'
|
9
|
+
require 'mdoc/processor/add_toc'
|
10
|
+
require 'mdoc/pipeline'
|
11
|
+
require 'mdoc/writer'
|
12
|
+
|
13
|
+
# individual processors
|
14
|
+
|
15
|
+
module Mdoc
|
16
|
+
extend self # act as a class
|
17
|
+
|
18
|
+
# entry point of the application, for each source files
|
19
|
+
# read, process and write out to converted file
|
20
|
+
def execute!
|
21
|
+
load_defaults unless @opts
|
22
|
+
|
23
|
+
opts.s_files.each do |sname|
|
24
|
+
Dir[sname].each { |fname| convert!(fname) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
## convert single file
|
29
|
+
def convert!(fname, doc_type = nil)
|
30
|
+
doc = prepare_doc(fname, doc_type)
|
31
|
+
|
32
|
+
# apply pipeline of processors
|
33
|
+
pli = default_pipeline(doc)
|
34
|
+
yield pli if block_given? # receive user supplied processors
|
35
|
+
|
36
|
+
pli.writer = find_writer(doc) unless pli.writer
|
37
|
+
pli.apply!(doc)
|
38
|
+
doc # return doc
|
39
|
+
end
|
40
|
+
|
41
|
+
# attr accessor for opts
|
42
|
+
def opts
|
43
|
+
load_defaults unless @opts
|
44
|
+
@opts
|
45
|
+
end
|
46
|
+
|
47
|
+
def prepare_doc(fname, doc_type)
|
48
|
+
doc_type = find_doc_type(fname) unless doc_type
|
49
|
+
doc = doc_type.new(fname)
|
50
|
+
# template
|
51
|
+
doc.tpl_file = find_tpl_file
|
52
|
+
|
53
|
+
# output file
|
54
|
+
doc.out_file = find_out_file(fname) unless opts.no_output
|
55
|
+
doc
|
56
|
+
end
|
57
|
+
|
58
|
+
# from several directory
|
59
|
+
# rubocop:disable MethodLength
|
60
|
+
def find_tpl_file
|
61
|
+
# add default search directory
|
62
|
+
ipath = File.expand_path(File.dirname(__FILE__) + '/../templates')
|
63
|
+
opts.tpl_directories << ipath unless opts.tpl_directories.include?(ipath)
|
64
|
+
rpath = File.expand_path('./templates')
|
65
|
+
opts.tpl_directories << rpath unless opts.tpl_directories.include?(rpath)
|
66
|
+
|
67
|
+
opts.template = 'default.' + opts.template unless opts.template =~ /\./
|
68
|
+
cand, buf = [], nil
|
69
|
+
opts.template.split('.').reverse.each do |b|
|
70
|
+
buf = buf ? b + '.' + buf : b
|
71
|
+
cand.unshift buf
|
72
|
+
end
|
73
|
+
|
74
|
+
cand.each do |pt|
|
75
|
+
opts.tpl_directories.each do |d|
|
76
|
+
tpl = d + '/' + pt + '.erb'
|
77
|
+
return tpl if File.exists?(tpl)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
raise 'no template file found for ' + opts.template
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
# rubocop:enable MethodLength
|
85
|
+
|
86
|
+
def find_out_file(fname)
|
87
|
+
return opts.output if opts.output
|
88
|
+
ext = '.' + opts.template.split('.')[-1]
|
89
|
+
fname =~ /\.\w{2,5}$/ ? fname.gsub(/\.\w+$/, ext) : fname + ext
|
90
|
+
end
|
91
|
+
|
92
|
+
# get class from keyword and module under Mdoc name space
|
93
|
+
def get_class(cname, mdl = Processor)
|
94
|
+
begin
|
95
|
+
mdl.const_get(cname.split(/[\,\_]/).map { |p| p.capitalize }.join)
|
96
|
+
rescue NameError
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def get_processor(pn)
|
102
|
+
pname = pn.is_a?(String) ? pn : pn.class
|
103
|
+
pn = get_class(pn) if pn.is_a?(String) # for string name
|
104
|
+
raise "not a valid class: #{pname.to_s}" unless pn
|
105
|
+
raise "not a processor: #{pname.to_s}" unless pn < Mdoc::Processor
|
106
|
+
|
107
|
+
pn
|
108
|
+
end
|
109
|
+
|
110
|
+
# from file name (esp. extensions), determine source file document type
|
111
|
+
def find_doc_type(f)
|
112
|
+
case f
|
113
|
+
when /\.(md|markdown)/
|
114
|
+
Document::Kramdown
|
115
|
+
else Document
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# get a list of processors into a pipline
|
120
|
+
def default_pipeline(doc)
|
121
|
+
pli = Pipeline.new default_processors
|
122
|
+
opts.processors.each { |p| pli.append p }
|
123
|
+
opts.no_processors.each { |p| pli.remove p }
|
124
|
+
pli
|
125
|
+
end
|
126
|
+
|
127
|
+
def default_processors
|
128
|
+
%w[
|
129
|
+
add_toc
|
130
|
+
add_title
|
131
|
+
smart_code_block
|
132
|
+
]
|
133
|
+
end
|
134
|
+
|
135
|
+
def find_writer(doc)
|
136
|
+
case opts.template
|
137
|
+
when /pandoc\.\w+$/
|
138
|
+
Writer::Pandoc
|
139
|
+
else Writer
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
data/mdoc.gemspec
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
-
require 'mdoc/version'
|
3
|
-
|
4
|
-
Gem::Specification.new 'mdoc', Mdoc::VERSION do |s|
|
5
|
-
s.description =
|
6
|
-
s.summary =
|
7
|
-
s.authors = [
|
8
|
-
s.email =
|
9
|
-
s.homepage =
|
10
|
-
s.files = `git ls-files`.split("\n") - %w[.gitignore]
|
11
|
-
s.executables <<
|
12
|
-
s.test_files = Dir.glob(
|
13
|
-
|
14
|
-
s.add_dependency 'kramdown'
|
15
|
-
s.add_dependency '
|
16
|
-
s.
|
17
|
-
s.add_development_dependency '
|
18
|
-
end
|
19
|
-
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
require 'mdoc/version'
|
3
|
+
|
4
|
+
Gem::Specification.new 'mdoc', Mdoc::VERSION do |s|
|
5
|
+
s.description = 'A tool for convert document between several different formats.'
|
6
|
+
s.summary = 'Convert markdown/reStructure/... of documents to html/docx/pdf/... formats.'
|
7
|
+
s.authors = ['Huang Wei']
|
8
|
+
s.email = 'huangw@pe-po.com'
|
9
|
+
s.homepage = 'https://github.com/7lime/mdoc-gem'
|
10
|
+
s.files = `git ls-files`.split("\n") - %w[.gitignore]
|
11
|
+
s.executables << 'mdoc'
|
12
|
+
s.test_files = Dir.glob('{spec,test}/**/*.rb')
|
13
|
+
|
14
|
+
s.add_dependency 'kramdown'
|
15
|
+
s.add_dependency 'tilt'
|
16
|
+
s.add_development_dependency 'rspec', '~> 2.5'
|
17
|
+
s.add_development_dependency 'simplecov', '~> 2.5'
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc::Processor::AddTitle do
|
4
|
+
it 'delete extra blank lines' do
|
5
|
+
doc = Mdoc::Document::Kramdown.new('spec/fixtures/multikeys.md')
|
6
|
+
doc.body.should match(/^The content inside/)
|
7
|
+
doc.apply!('add_title')
|
8
|
+
doc.body.should match(/^\# The title for our document/)
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc::Processor::AddToc do
|
4
|
+
it 'delete extra blank lines' do
|
5
|
+
doc = Mdoc::Document::Kramdown.new('spec/fixtures/multikeys.md')
|
6
|
+
doc.body.should_not match(/\:toc/)
|
7
|
+
doc.apply!('add_toc')
|
8
|
+
doc.apply!('add_title')
|
9
|
+
doc.body.should match(/\:toc/)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc::Document do
|
4
|
+
context 'pandoc style meta header' do
|
5
|
+
subject { Mdoc::Document.new('spec/fixtures/pandoc.md') }
|
6
|
+
its(:file) { should eq('spec/fixtures/pandoc.md') }
|
7
|
+
its(:title) { should eq('Pandoc Title') }
|
8
|
+
its(:author) { should eq('Author Like Me') }
|
9
|
+
its(:date) { should eq('Date in Some Format') }
|
10
|
+
its(:body) { should match(/^The first line of contents/) }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'original style meta header' do
|
14
|
+
subject(:doc) { Mdoc::Document.new('spec/fixtures/original.md') }
|
15
|
+
its(:title) { should eq('The title for our document') }
|
16
|
+
its(:author) { should eq('unknown person') }
|
17
|
+
it 'has array and date value assigned' do
|
18
|
+
doc.date.strftime('%F').should eq('2009-08-01')
|
19
|
+
doc.meta.category[0].should eq('eo.personal')
|
20
|
+
end
|
21
|
+
its(:body) { should eq("The content inside\n") }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'multikeys style meta header' do
|
25
|
+
subject(:doc) { Mdoc::Document.new('spec/fixtures/multikeys.md') }
|
26
|
+
its(:file) { should eq('spec/fixtures/multikeys.md') }
|
27
|
+
its(:title) { should eq('The title for our document') }
|
28
|
+
its(:author) { should eq('unknown person too') }
|
29
|
+
it 'has array value assigned' do
|
30
|
+
doc.meta.tag[1].should eq('file')
|
31
|
+
end
|
32
|
+
its(:body) { should eq("The content inside\n") }
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc do
|
4
|
+
it 'pick up source files to convert!' do
|
5
|
+
gf = 'spec/fixtures/README.html'
|
6
|
+
File.delete(gf) if File.exists?(gf)
|
7
|
+
Mdoc.load_cli_options(%w[spec/fixtures/README.md])
|
8
|
+
Mdoc.execute!
|
9
|
+
File.exists?('spec/fixtures/README.html').should be_true
|
10
|
+
File.delete(gf)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc do
|
4
|
+
describe '#find_doc_type' do
|
5
|
+
it 'find markdown' do
|
6
|
+
Mdoc.find_doc_type('some.md').should eq(Mdoc::Document::Kramdown)
|
7
|
+
Mdoc.find_doc_type('some.markdown').should eq(Mdoc::Document::Kramdown)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'default to Document' do
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# MDOC: general document converting/management tool
|
2
|
+
|
3
|
+
Mdoc is a swiss-army-knife kind of tool converting documents between many formats.
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
gem install mdoc
|
8
|
+
|
9
|
+
## Features
|
10
|
+
|
11
|
+
- Modularized structure, document will passing through a
|
12
|
+
pre-defined processor pipe-line during the converting process.
|
13
|
+
|
14
|
+
- Easily extensible with custom processors
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
Convert a markdown file (`readme.md`) to html (default template):
|
19
|
+
|
20
|
+
mdoc readme.md
|
21
|
+
|
22
|
+
### Customize with your own template
|
23
|
+
|
24
|
+
mdoc -t custom.html.erb readme.md
|
25
|
+
|
26
|
+
Will use `custom.html.erb` file as template, you can put this file under
|
27
|
+
`/etc/mdoc/templates`, `~/.mdoc/templates/` or `./templates`.
|
28
|
+
|
29
|
+
Mdoc will first try to use `CustomHtmlWriter`, then `HtmlWriter` then
|
30
|
+
`Writer` to write out the output file. Which by default is `readme.html`
|
31
|
+
for the last example, or you can specify your own as:
|
32
|
+
|
33
|
+
mdoc -t custom.html.erb -o README.htm readme.md
|
34
|
+
|
35
|
+
Mdoc use a `tilt` based template handling, by default `meta` and
|
36
|
+
`body` are passed as two local variables. Refer API document of
|
37
|
+
`Mdoc::Document` and `Mdoc::Document::Kramdown` for more information
|
38
|
+
available[^1].
|
39
|
+
|
40
|
+
[^1]: Kramdown Syntax: http://kramdown.rubyforge.org/quickref.html
|
41
|
+
|
42
|
+
### Customize processors
|
43
|
+
|
44
|
+
mdoc -p todo,code -P toc,math readme.md
|
45
|
+
|
46
|
+
Will enable `todo` and `code` processor but disable `math` and `toc` processor.
|
47
|
+
|
48
|
+
## Extend with custom processors:
|
49
|
+
|
50
|
+
Add custom processor is easy
|
51
|
+
|
52
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~ ruby
|
53
|
+
|
54
|
+
require 'mdoc'
|
55
|
+
module Mdoc
|
56
|
+
module Processor
|
57
|
+
class Custom < Processor
|
58
|
+
def process document
|
59
|
+
document.meta.title += ' (draft)' # add postfix to document title
|
60
|
+
document.body.gsub!(/https/, '') # change the source body text
|
61
|
+
end
|
62
|
+
|
63
|
+
def repeatable?
|
64
|
+
true # default is false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Other < Processor
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
Mdoc.convert!('somefile.md') do |pipeline|
|
74
|
+
pipeline.insert :custom
|
75
|
+
pipeline.insert :other, :before => :custom # or :after => :some_processor
|
76
|
+
pipeline.remove :todo
|
77
|
+
end
|
78
|
+
|
79
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
80
|
+
|
81
|
+
By default `insert` will insert the new processor to the very begin of the chain,
|
82
|
+
`append` will add to the last, right before `writer`.
|
83
|
+
|
84
|
+
You can also customize the `writer` by
|
85
|
+
|
86
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ruby
|
87
|
+
|
88
|
+
Mdoc.new.convert('somefile.md') do |pipeline|
|
89
|
+
pipeline.writer :pandoc_markdown
|
90
|
+
end
|
91
|
+
|
92
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
93
|
+
|
94
|
+
Writer and default processor list are listed below. (TODO)
|
95
|
+
|
96
|
+
## Meta information in header
|
97
|
+
|
98
|
+
Three different formats are supported:
|
99
|
+
|
100
|
+
1. pandoc like three line header (max 3 lines)
|
101
|
+
|
102
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
103
|
+
|
104
|
+
% title
|
105
|
+
% author
|
106
|
+
% date
|
107
|
+
|
108
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
109
|
+
|
110
|
+
2. multi-header (first non-blank line with three or more dashes)
|
111
|
+
|
112
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
113
|
+
|
114
|
+
---- #
|
115
|
+
Title: some key
|
116
|
+
Author: some key
|
117
|
+
---- #
|
118
|
+
|
119
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
120
|
+
|
121
|
+
And you can use a optional `%`, so the following is the same as above:
|
122
|
+
|
123
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
124
|
+
|
125
|
+
% ---
|
126
|
+
Title: some key
|
127
|
+
Author: some key
|
128
|
+
% ---
|
129
|
+
|
130
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
131
|
+
|
132
|
+
3. no-header: file directly start with a document header.
|
133
|
+
|
134
|
+
Contents below header (except blank lines) are treated as body.
|
135
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
template: pandoc.md
|
@@ -0,0 +1 @@
|
|
1
|
+
template: pandoc.docx
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset='utf-8'>
|
5
|
+
<title>The title for our document</title>
|
6
|
+
<!--this style include the test_md/css screen.css(first) and base.css -->
|
7
|
+
<style type="text/css">
|
8
|
+
pre code{display:block;background:#fff;color:#4d4d4c;font-family:Menlo, Monaco, Consolas, monospace;font-size:12px;line-height:1.5;border:1px solid #ccc;padding:10px}html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,code,del,dfn,em,img,q,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline}table{border-collapse:separate;border-spacing:0}caption,th,td{text-align:left;font-weight:normal}table,td,th{vertical-align:middle}blockquote:before,blockquote:after,q:before,q:after{content:""}blockquote,q{quotes:"" ""}a img{border:none}body{margin:10px}html{height:100%}body{padding:0;margin:0;font:14px/22px "adelle", Georgia, sans-serif;font-size-adjust:none;font-style:normal;font-variant:normal;font-weight:normal;background:#f4f6ec}a{color:#369}#markdown-toc{float:left;width:230px;margin-right:30px;margin-top:40px}#markdown-toc a{display:block;font-weight:bold;text-decoration:none}#markdown-toc #sections{list-style-type:none;border-bottom:3px solid rgba(0,0,0,0.1);padding-bottom:10px;margin-bottom:10px}#markdown-toc #sections>li>a{padding:5px 0;color:#444;font-size:16px}#markdown-toc #sections ul{margin-bottom:15px}#markdown-toc #sections ul li{list-style-type:none}#markdown-toc #sections ul li a{padding:1px 15px;font-size:13px;font-weight:normal}#markdown-toc .extra{padding:5px 0;min-height:1.4em}#markdown-toc .extra a{color:#555;font-size:14px}#markdown-toc #travis img{margin-top:10px;display:block}#markdown-toc>*:last-child{margin-bottom:20px}#content{padding:30px 30px 20px 30px;min-height:100px;width:600px;background:#fff;float:left;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;margin-top:15px}#content #loader{color:#888;width:300px;height:24px;line-height:24px;position:absolute;top:30px;left:30px;background:url("data:image/gif;base64,R0lGODlhGAAYAPYAAP///5mZmfn5+dvb27i4uKmpqaCgoNra2v39/c/Pz6CgoJmZmfT09K+vr66urvb29qWlpaSkpPPz8/v7+87Ozvj4+NXV1dTU1Li4uKysrJubm52dnaqqqu7u7uPj46Ojo8LCwvb29ra2tqenp7q6utzc3JycnNfX1/Ly8uzs7J6ensbGxs3NzeDg4MvLy9LS0r+/v/r6+qysrOrq6t7e3tnZ2cTExLS0tLOzs6ioqLGxsefn57W1tcvLy7y8vMHBwd7e3qKiovHx8cfHx+Hh4QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAFAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAGAAYAAAHmoAAgoOEhYaHgxUWBA4aCxwkJwKIhBMJBguZmpkqLBOUDw2bo5kKEogMEKSkLYgIoqubK5QJsZsNCIgCCraZBiiUA72ZJZQABMMgxgAFvRyfxpixGx3LANKxHtbNth8hy8i9IssHwwsXxgLYsSYpxrXDz5QIDubKlAwR5q2UErC2poxNoLBukwoX0IxVuIAhQ6YRBC5MskaxUCAAIfkEAAUAAQAsAAAAABgAGAAAB6GAAIKDhIWGh4MVFgQOGhsOGAcxiIQTCQYLmZqZGwkIlA8Nm6OaMgyHDBCkqwsjEoUIoqykNxWFCbOkNoYCCrmaJjWHA7+ZHzOIBMUND5QFvzATlACYsy/TgtWsIpPTz7kyr5TKv8eUB8ULGzSIAtq/CYi46Qswn7AO9As4toUMEfRcHZIgC9wpRBMovNvU6d60ChcwZFigwYGIAwKwaUQUCAAh+QQABQACACwAAAAAGAAYAAAHooAAgoOEhYaHgxUWBA4aCzkkJwKIhBMJBguZmpkqLAiUDw2bo5oyEocMEKSrCxCnhAiirKs3hQmzsy+DAgq4pBogKIMDvpvAwoQExQvHhwW+zYiYrNGU06wNHpSCz746O5TKyzwzhwfLmgQphQLX6D4dhLfomgmwDvQLOoYMEegRyApJkIWLQ0BDEyi426Six4RtgipcwJAhUwQCFypA3IgoEAAh+QQABQADACwAAAAAGAAYAAAHrYAAgoOEhYaHgxUWBA4aCxwkJzGIhBMJBguZmpkGLAiUDw2bo5oZEocMEKSrCxCnhAiirKsZn4MJs7MJgwIKuawqFYIDv7MnggTFozlDLZMABcpBPjUMhpisJiIJKZQA2KwfP0DPh9HFGjwJQobJypoQK0S2B++kF4IC4PbBt/aaPWA5+CdjQiEGEd5FQHFIgqxcHF4dmkBh3yYVLmx5q3ABQ4ZMBUhYEOCtpLdAACH5BAAFAAQALAAAAAAYABgAAAeegACCg4SFhoeDFRYEDhoaDgQWFYiEEwkGC5mamQYJE5QPDZujmg0PhwwQpKsLEAyFCKKsqw0IhAmzswmDAgq5rAoCggO/sxaCBMWsBIIFyqsRgpjPoybS1KMqzdibBcjcmswAB+CZxwAC09gGwoK43LuDCA7YDp+EDBHPEa+GErK5GkigNIGCulEGKNyjBKDCBQwZMmXAcGESw4uUAgEAIfkEAAUABQAsAAAAABgAGAAAB62AAIKDhIWGh4MVFgQOGgscJCcxiIQTCQYLmZqZBiwIlA8Nm6OaGRKHDBCkqwsQp4QIoqyrGZ+DCbOzCYMCCrmsKhWCA7+zJ4IExaM5Qy2TAAXKQT41DIaYrCYiCSmUANisHz9Az4fRxRo8CUKGycqaECtEtgfvpBeCAuD2wbf2mj1gOfgnY0IhBhHeRUBxSIKsXBxeHZpAYd8mFS5seatwAUOGTAVIWBDgraS3QAAh+QQABQAGACwAAAAAGAAYAAAHooAAgoOEhYaHgxUWBA4aCzkkJwKIhBMJBguZmpkqLAiUDw2bo5oyEocMEKSrCxCnhAiirKs3hQmzsy+DAgq4pBogKIMDvpvAwoQExQvHhwW+zYiYrNGU06wNHpSCz746O5TKyzwzhwfLmgQphQLX6D4dhLfomgmwDvQLOoYMEegRyApJkIWLQ0BDEyi426Six4RtgipcwJAhUwQCFypA3IgoEAAh+QQABQAHACwAAAAAGAAYAAAHoYAAgoOEhYaHgxUWBA4aGw4YBzGIhBMJBguZmpkbCQiUDw2bo5oyDIcMEKSrCyMShQiirKQ3FYUJs6Q2hgIKuZomNYcDv5kfM4gExQ0PlAW/MBOUAJizL9OC1awik9PPuTKvlMq/x5QHxQsbNIgC2r8JiLjpCzCfsA70Czi2hQwR9FwdkiAL3ClEEyi829Tp3rQKFzBkWKDBgYgDArBpRBQIADsAAAAAAAAAAAA=") no-repeat center left;padding-left:32px;font-size:18px}#content>p{zoom:1}#content>p:before,#content>p:after{content:"";display:table}#content>p:after{clear:both}#content p{padding:0 0 0.8125em 0;color:#444}#content p img{float:left;margin:0.5em 0.8125em 0.8125em 0;padding:0}#content img{max-width:100%}#content h1,#content h2,#content h3,#content h4,#content h5,#content h6{font-weight:bold;line-height:1.2em}#content h1{font-size:2.125em;margin-bottom:0.4em}#content h2{font-size:1.7em;margin:0.855em 0 0.4em;color:#cc333f}#content h3{font-size:1.3em;margin:0.956em 0 0.4em}#content h4{font-size:1.1em;margin:1.161em 0 0.4em}#content h5,#content h6{font-size:1em;font-weight:bold;margin:1.238em 0 0.4em}#content>h1,#content>h2{margin-top:0}#content ul{list-style-position:outside}#content li ul,#content li ol{margin:0 1.625em}#content ul,#content ol{margin:0 0 1.625em 1.25em}#content dl{margin:0 0 1.625em 0}#content dl dt{font-weight:bold}#content dl dd{margin-left:1.625em}#content a{text-decoration:none}#content a:hover{text-decoration:underline}#content table{margin-bottom:1.625em;border-collapse:collapse}#content th{font-weight:bold}#content tr,#content th,#content td{margin:0;padding:0 1.625em 0 1em;height:26px}#content tfoot{font-style:italic}#content caption{text-align:center;font-family:Georgia, serif}#content abbr,#content acronym{border-bottom:1px dotted #000}#content address{margin-top:1.625em;font-style:italic}#content del{color:#000}#content blockquote{padding:1em 1em 1.625em 1em;font-family:georgia, serif;font-style:italic}#content blockquote:before{content:"\201C";font-size:3em;margin-left:-0.625em;font-family:georgia, serif;color:#aaa;line-height:0}#content blockquote>p{padding:0;margin:0}#content strong{font-weight:bold}#content em,#content dfn{font-style:italic}#content dfn{font-weight:bold}#content pre,#content code{margin:0 0 1.625em;white-space:pre}#content pre,#content code,#content tt{font-size:1em;font-family:Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace;line-height:1.5}#content code{background:#f7f8f1;padding:1px 2px;border:1px solid #ccc}#content pre code{padding:10px 12px;word-wrap:normal;overflow-y:auto}#content tt{display:block;margin:1.625em 0}#content hr{margin-bottom:1.625em}#content table{font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;width:100%}#content th,#content td{padding:5px 10px;border:1px solid #ccc}#content th{background:#eee;padding:7px 10px}#content td{font-size:0.9em;border-color:#ddd}#content tbody tr:nth-child(2n){background:#f5f5f5}@media only screen and (max-width: 480px){#container{width:100%}#markdown-toc{width:100%;margin-top:10px;float:none}#markdown-toc #sections,#markdown-toc #header,#markdown-toc .extra{padding-left:30px;padding-right:30px}#content{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border-width:1px;float:none;margin:0;width:100%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}}@media only screen and (min-device-pixel-ratio: 1.5), only screen and (min-resolution: 1.5dppx){#github-ribbon img{width:100px}}*{margin:0;padding:0}body{margin-left:40px}#markdown-toc{float:right !important;position:fixed;left:745px;height:90%;overflow:auto}#content{float:left !important;filter:progid:DXImageTransform.Microsoft.Shadow(color=#909090,direction=120,strength=4);-moz-box-shadow:2px 2px 10px #909090;-webkit-box-shadow:2px 2px 10px #909090;box-shadow:2px 2px 10px #909090}#markdown-toc{width:auto;max-width:300px !important;top:40px}#markdown-toc>li>ul>li>a{color:#cc333f;margin-top:10px}#markdown-toc>li>ul>li>ul>li>a,h3{color:#009999}#markdown-toc>li>ul>li>ul>li>ul>li>a,h4{color:#669999}#markdown-toc>li>a{margin-bottom:20px;padding-bottom:20px;border-bottom:3px solid rgba(0,0,0,0.1);font-size:20px;color:#000000}#content code{border-radius:3px}
|
9
|
+
</style>
|
10
|
+
</head>
|
11
|
+
|
12
|
+
<body>
|
13
|
+
<div id="content">
|
14
|
+
<p>c</p>
|
15
|
+
|
16
|
+
</div>
|
17
|
+
</body>
|
18
|
+
</html>
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
----
|
2
|
+
id: eo.file.name
|
3
|
+
category: [eo.personal]
|
4
|
+
title: The title for our document
|
5
|
+
date: 2009-08-01
|
6
|
+
tag: [human, file]
|
7
|
+
author: unknown person too
|
8
|
+
----
|
9
|
+
|
10
|
+
The content inside
|
@@ -1,10 +1,10 @@
|
|
1
|
-
% ---
|
2
|
-
id: eo.file.name
|
3
|
-
category: [eo.personal]
|
4
|
-
title: The title for our document
|
5
|
-
date: 2009-08-01
|
6
|
-
tag: [human file]
|
7
|
-
author: unknown person
|
8
|
-
% ----
|
9
|
-
|
10
|
-
The content inside
|
1
|
+
% ---
|
2
|
+
id: eo.file.name
|
3
|
+
category: [eo.personal]
|
4
|
+
title: The title for our document
|
5
|
+
date: 2009-08-01
|
6
|
+
tag: [human file]
|
7
|
+
author: unknown person
|
8
|
+
% ----
|
9
|
+
|
10
|
+
The content inside
|
@@ -1,7 +1,7 @@
|
|
1
|
-
% Pandoc Title
|
2
|
-
% Author Like Me
|
3
|
-
% Date in Some Format
|
4
|
-
|
5
|
-
The first line of contents
|
6
|
-
|
7
|
-
The Third line of contents
|
1
|
+
% Pandoc Title
|
2
|
+
% Author Like Me
|
3
|
+
% Date in Some Format
|
4
|
+
|
5
|
+
The first line of contents
|
6
|
+
|
7
|
+
The Third line of contents
|
File without changes
|
File without changes
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Mdoc
|
4
|
+
class Processor
|
5
|
+
class TestProcessor; end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Writer
|
9
|
+
class DefaultPrinter; end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Mdoc do
|
14
|
+
describe '.get_class' do
|
15
|
+
context 'test_processor for default module' do
|
16
|
+
it 'get TestProcessor' do
|
17
|
+
klass = Mdoc.get_class('test_processor')
|
18
|
+
klass.should eq(Mdoc::Processor::TestProcessor)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'default_printer for writer module' do
|
23
|
+
it 'get DefaultPrinter' do
|
24
|
+
klass = Mdoc.get_class('default_printer', Mdoc::Writer)
|
25
|
+
klass.should eq(Mdoc::Writer::DefaultPrinter)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'non-exists class' do
|
30
|
+
it 'return nil' do
|
31
|
+
Mdoc.get_class('not_exists').should be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc::Document::Kramdown do
|
4
|
+
describe '#kramdown' do
|
5
|
+
subject { Mdoc::Document::Kramdown.new('spec/fixtures/multikeys.md') }
|
6
|
+
its(:kramdown) { should_not be_nil }
|
7
|
+
its(:body_html) { should match(/<p>The content inside<\/p>/) }
|
8
|
+
its(:body_latex) { should match(/The content inside/) }
|
9
|
+
end
|
10
|
+
end
|
data/spec/meta_spec.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdoc do
|
4
|
+
context 'defaults' do
|
5
|
+
subject do
|
6
|
+
Mdoc.load_defaults
|
7
|
+
Mdoc.opts
|
8
|
+
end
|
9
|
+
its(:template) { should eq('html') }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'load files' do
|
13
|
+
subject do
|
14
|
+
f_dir = 'spec/fixtures/config'
|
15
|
+
f_a, f_b = f_dir + '/mdoc_a.cnf', f_dir + '/mdoc_b.cnf'
|
16
|
+
Mdoc.load_conf_files [f_a, f_b]
|
17
|
+
Mdoc.opts
|
18
|
+
end
|
19
|
+
|
20
|
+
its(:template) { should eq('pandoc.docx') }
|
21
|
+
end
|
22
|
+
|
23
|
+
context '--version' do
|
24
|
+
subject { capture_stdout { Mdoc.load_cli_options(%w[-v]) } }
|
25
|
+
it { should eq(Mdoc::VERSION + "\n") }
|
26
|
+
end
|
27
|
+
|
28
|
+
context '--help' do
|
29
|
+
subject { capture_stdout { Mdoc.load_cli_options(%w[-h]) } }
|
30
|
+
it { should match('-h, --help') }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'cli options' do
|
34
|
+
subject(:mopts) do
|
35
|
+
# rubocop:disable LineLength
|
36
|
+
Mdoc.load_defaults
|
37
|
+
Mdoc.load_cli_options(%w[-t xhtml -O -p pa,pb -z na,nb -d de,df fa fb fc])
|
38
|
+
Mdoc.opts
|
39
|
+
# rubocop:enable LineLength
|
40
|
+
end
|
41
|
+
|
42
|
+
its(:no_output) { should be_true }
|
43
|
+
its(:template) { should eq('xhtml') }
|
44
|
+
its(:processors) { should eq(%w[pa pb]) }
|
45
|
+
its(:no_processors) { should eq(%w[na nb]) }
|
46
|
+
describe 'tpl directories' do
|
47
|
+
it 'has four elements' do
|
48
|
+
mopts.tpl_directories.size.should eq(2)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'last elements equals df' do
|
52
|
+
mopts.tpl_directories[-1].should match(/df$/)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'output' do
|
57
|
+
it 'can be specified' do
|
58
|
+
Mdoc.load_defaults
|
59
|
+
Mdoc.load_cli_options(%w[-o specified.html])
|
60
|
+
Mdoc.opts.output.should eq('specified.html')
|
61
|
+
Mdoc.load_defaults
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|