mdoc 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|