pretty_doc 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9a96928b9bcc0dc2d0df55c7f54bd07e97090475
4
+ data.tar.gz: 3b3f486f6295ba4caab0da163bd00d039ef4a5ee
5
+ SHA512:
6
+ metadata.gz: ebb692c94a6fe4f77a6105adf11df6dc597c93b4b1e5a31edfed9ad1a958dc8cd520a4bf1d9fb959cfe3a46443d956f2f800e838f7bd8ccf889f675c66256a47
7
+ data.tar.gz: 82f2a8399bdf5028ee6828e8ff75127ede856a8f29442faf7a7db417874bf3eff25486e790d8bd47edaf33eec559399ff923024bb91541b01603496a47856bf1
data/.gitignore ADDED
@@ -0,0 +1,37 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
36
+
37
+ .sass-cache
data/CHANGES.md ADDED
@@ -0,0 +1,3 @@
1
+ 1.0.0
2
+ -----------
3
+ - Initial release!
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,88 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pretty_doc (1.0.0)
5
+ bootstrap-sass (~> 3.3.5)
6
+ compass (~> 1.0.3)
7
+ kramdown (~> 1.8.0)
8
+ nokogiri (~> 1.6.6)
9
+ pygments.rb (~> 0.6.3)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ autoprefixer-rails (5.2.1.1)
15
+ execjs
16
+ json
17
+ bootstrap-sass (3.3.5.1)
18
+ autoprefixer-rails (>= 5.0.0.1)
19
+ sass (>= 3.3.0)
20
+ chunky_png (1.3.4)
21
+ coderay (1.1.0)
22
+ compass (1.0.3)
23
+ chunky_png (~> 1.2)
24
+ compass-core (~> 1.0.2)
25
+ compass-import-once (~> 1.0.5)
26
+ rb-fsevent (>= 0.9.3)
27
+ rb-inotify (>= 0.9)
28
+ sass (>= 3.3.13, < 3.5)
29
+ compass-core (1.0.3)
30
+ multi_json (~> 1.0)
31
+ sass (>= 3.3.0, < 3.5)
32
+ compass-import-once (1.0.5)
33
+ sass (>= 3.2, < 3.5)
34
+ diff-lcs (1.2.5)
35
+ execjs (2.5.2)
36
+ ffi (1.9.10)
37
+ json (1.8.3)
38
+ kramdown (1.8.0)
39
+ method_source (0.8.2)
40
+ mini_portile (0.6.2)
41
+ multi_json (1.11.2)
42
+ nokogiri (1.6.6.2)
43
+ mini_portile (~> 0.6.0)
44
+ posix-spawn (0.3.11)
45
+ pry (0.10.1)
46
+ coderay (~> 1.1.0)
47
+ method_source (~> 0.8.1)
48
+ slop (~> 3.4)
49
+ pygments.rb (0.6.3)
50
+ posix-spawn (~> 0.3.6)
51
+ yajl-ruby (~> 1.2.0)
52
+ rake (10.4.2)
53
+ rb-fsevent (0.9.5)
54
+ rb-inotify (0.9.5)
55
+ ffi (>= 0.5.0)
56
+ rspec (3.3.0)
57
+ rspec-core (~> 3.3.0)
58
+ rspec-expectations (~> 3.3.0)
59
+ rspec-mocks (~> 3.3.0)
60
+ rspec-core (3.3.2)
61
+ rspec-support (~> 3.3.0)
62
+ rspec-expectations (3.3.1)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.3.0)
65
+ rspec-its (1.2.0)
66
+ rspec-core (>= 3.0.0)
67
+ rspec-expectations (>= 3.0.0)
68
+ rspec-mocks (3.3.2)
69
+ diff-lcs (>= 1.2.0, < 2.0)
70
+ rspec-support (~> 3.3.0)
71
+ rspec-support (3.3.0)
72
+ sass (3.4.16)
73
+ slop (3.6.0)
74
+ yajl-ruby (1.2.1)
75
+
76
+ PLATFORMS
77
+ ruby
78
+
79
+ DEPENDENCIES
80
+ bundler (>= 1.0.0)
81
+ pretty_doc!
82
+ pry
83
+ rake
84
+ rspec (>= 3.0.0)
85
+ rspec-its (>= 1.0.0)
86
+
87
+ BUNDLED WITH
88
+ 1.10.5
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Felix Liu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ Pretty Doc
2
+ ==========
3
+
4
+ Pretty Doc is quick and convenient markdown to html converter with beautiful templates, aiming to provide a simple tool to generate beautiful docs for common use.
5
+
6
+ [TOC]
7
+
8
+ ## Features
9
+
10
+ + Beautiful built-in templates: `default`, `bootstrap`, `parallel`
11
+ + Code highlight
12
+ + Markdown TOC supports
13
+ + Easy to customize template
14
+ + Support GFM( GitHub Flavored Markdown ) syntax
15
+
16
+ ## Examples
17
+
18
+ + [Template Default](https://lyfeyaj.github.io/pretty_doc/examples/default/README.html)
19
+ + [Template Bootstrap](https://lyfeyaj.github.io/pretty_doc/examples/bootstrap/README.html)
20
+ + [Template Parallel](https://lyfeyaj.github.io/pretty_doc/examples/parallel/README.html)
21
+
22
+ ## Installation
23
+
24
+ Pretty Doc is relied on `ruby` environment. Please make sure that your system has `ruby` installed.
25
+
26
+ ```bash
27
+ gem install pretty_doc
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ``` bash
33
+ # Usage: pretty_doc [options] files
34
+ #
35
+ # Options:
36
+ #
37
+ # -o, --output [path] output to a given folder
38
+ # -t, --template [folder] choose a template
39
+ # -l, --line-numbers enable line numbers for codes
40
+ # -v, --version output the version number
41
+ # -h, --help output usage information
42
+ ```
43
+
44
+ ## Create a custom template
45
+
46
+ template structure
47
+
48
+ ```
49
+ ├── init.rb
50
+ ├── style.scss
51
+ └── template.html.erb
52
+ ```
53
+
54
+ ## TODO
55
+
56
+ + Add docs for how to create a custom template
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/pretty_doc ADDED
@@ -0,0 +1,8 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ lib_path = File.expand_path('../../lib', __FILE__)
4
+ $:.unshift(lib_path)
5
+
6
+ require 'pretty_doc/cli'
7
+
8
+ PrettyDoc::Cli.run!(ARGV)
data/build.sh ADDED
@@ -0,0 +1,7 @@
1
+ pretty_doc -t default -o ./examples/default README.md
2
+ pretty_doc -t bootstrap -o ./examples/bootstrap README.md
3
+ pretty_doc -t parallel -o ./examples/parallel README.md
4
+
5
+ pretty_doc -t parallel README.md
6
+
7
+ mv README.html index.html
@@ -0,0 +1,64 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+ require 'pretty_doc'
4
+
5
+ module PrettyDoc
6
+ class Cli
7
+ class << self
8
+ def run!(args)
9
+ options = OpenStruct.new
10
+ options.template = 'default'
11
+ options.output = File.expand_path('.')
12
+ options.files = []
13
+ options.enable_line_numbers = false
14
+
15
+ opts_parser = OptionParser.new do |opts|
16
+ opts.banner = 'Pretty document empowered by markup language.'
17
+ opts.separator ''
18
+ opts.separator 'Usage: pretty_doc [options] files'
19
+ opts.separator ''
20
+ opts.separator 'Options:'
21
+ opts.separator ''
22
+
23
+ opts.on_tail('-v', '--version', 'output the version number') do
24
+ puts PrettyDoc::VERSION
25
+ exit
26
+ end
27
+
28
+ opts.on_tail('-h', '--help', 'output usage information') do
29
+ puts opts
30
+ exit
31
+ end
32
+
33
+ opts.on('-o', '--output [path]', 'output to a given folder') do |o|
34
+ options.output = File.expand_path(o || '.')
35
+ if !Dir.exist? options.output
36
+ puts "Directory #{options.output} is not exists, creating new..."
37
+ FileUtils.mkdir_p(options.output)
38
+ end
39
+ end
40
+
41
+ opts.on('-t', '--template [folder]', 'choose a template') do |tmpl|
42
+ options.template = tmpl
43
+ end
44
+
45
+ opts.on('-l', '--line-numbers', 'enable line numbers for codes') do
46
+ options.enable_line_numbers = true
47
+ end
48
+ end
49
+
50
+ opts_parser.parse!(args)
51
+
52
+ options.files = args
53
+ options.files = Dir.glob('./*.md') if options.files.length == 0
54
+ if options.files.length == 0
55
+ puts opts_parser
56
+ exit
57
+ end
58
+
59
+ options.template = PrettyDoc.template(options.template)
60
+ PrettyDoc::Resource::Source.build(options)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,25 @@
1
+ module PrettyDoc
2
+ # Common Converter Class that will be inherited
3
+ class Converter
4
+ attr_accessor :content, :options
5
+
6
+ def as_html
7
+ convert
8
+ end
9
+
10
+ def self.perfer_exts
11
+ []
12
+ end
13
+
14
+ # load all descendants
15
+ def self.descendants
16
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
17
+ end
18
+
19
+ private
20
+
21
+ # Convert Markdown to Html, implement this method to convert content
22
+ def convert
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,108 @@
1
+ require 'kramdown'
2
+ require 'nokogiri'
3
+ require 'pygments'
4
+ require 'pretty_doc/converter'
5
+
6
+ module PrettyDoc
7
+ # Markdown Converter
8
+ class Markdown < Converter
9
+ def self.perfer_exts
10
+ ['.md', '.markdown', '.mdown', '.txt']
11
+ end
12
+
13
+ def before_convert
14
+ self.content = content
15
+ .gsub(/\[NO_TOC\]\n/, "{:.no_toc}\n")
16
+ .gsub(/\[TOC\]\n/, "+ __toc_line__\n{:toc}\n")
17
+ end
18
+
19
+ private
20
+
21
+ def convert
22
+ before_convert
23
+ html = Kramdown::Document.new(
24
+ content,
25
+ input: :GFM,
26
+ enable_coderay: false,
27
+ transliterated_header_ids: true
28
+ ).to_html
29
+ doc = Nokogiri::HTML::DocumentFragment.parse(html)
30
+ figure_role(doc)
31
+ code_block(doc)
32
+ doc.to_html
33
+ end
34
+
35
+ def code_block(doc)
36
+ doc.css('pre > code[class^=language]').each do |code_node|
37
+ lang = (code_node['class'].scan(/language-([^\s]+)/).first || []).first
38
+ highlight_code_block(code_node, lang)
39
+ end
40
+
41
+ doc.css('pre[lang] > code').each do |code_node|
42
+ lang = code_node.parent['lang']
43
+ highlight_code_block(code_node, lang)
44
+ end
45
+ end
46
+
47
+ def highlight_code_block(code_node, lang)
48
+ pre = code_node.parent
49
+ code_output = highlight(code_node.content, lang)
50
+ code_doc = Nokogiri::HTML::DocumentFragment.parse(code_output)
51
+ pre.replace code_doc.children
52
+ end
53
+
54
+ def highlight(content, lang)
55
+ highlighted_code = Pygments.highlight(
56
+ content,
57
+ lexer: lang,
58
+ formatter: 'html',
59
+ options: { encoding: 'utf-8' }
60
+ )
61
+ str = highlighted_code.match(/<pre>(.+)<\/pre>/m)[1].to_s.gsub(/ *$/, '')
62
+ tableize_code(str, lang)
63
+ end
64
+
65
+ def tableize_code (str, lang = '')
66
+ line_numbers = ''
67
+ code = ''
68
+ str.lines.each_with_index do |line, index|
69
+ line_numbers += "<span class='line-number'>#{index + 1}</span>\n" if options.enable_line_numbers
70
+ code += "<span class='line'>#{line}</span>"
71
+ end
72
+
73
+ if options.enable_line_numbers
74
+ line_numbers = <<-HTML
75
+ <td class="lines">
76
+ <pre class="line-numbers">#{line_numbers}</pre>
77
+ </td>
78
+ HTML
79
+ end
80
+
81
+ no_line_numbers_class = options.enable_line_numbers ? '' : 'no-lines'
82
+
83
+ table = <<-HTML
84
+ <div class="highlight #{no_line_numbers_class}">
85
+ <table>
86
+ <tr>
87
+ #{line_numbers}
88
+ <td class="code">
89
+ <pre><code>#{code}</code></pre>
90
+ </td>
91
+ </tr>
92
+ </table>
93
+ </div>
94
+ HTML
95
+ table
96
+ end
97
+
98
+ def figure_role(doc)
99
+ doc.css('p[role=figure]').each do |p|
100
+ p.remove_attribute 'role'
101
+ p.name = 'figure'
102
+ p['class'] = 'thumbnail'
103
+ p.css('em').each { |s| s.name = 'figcaption' }
104
+ p.css('strong').each { |s| s.name = 'figcaption' }
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,11 @@
1
+ require 'fileutils'
2
+
3
+ module PrettyDoc
4
+ # Base Resource Class
5
+ class Resource
6
+ attr_accessor :file
7
+
8
+ def write(file_dir, options = {})
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,37 @@
1
+ require 'tempfile'
2
+ require 'compass'
3
+ require 'compass/exec'
4
+ require 'pretty_doc/resource'
5
+
6
+ module PrettyDoc
7
+ class Resource
8
+ # Scss resource
9
+ class Scss < Resource
10
+ attr_accessor :scss_pathname
11
+
12
+ def initialize(scss_pathname)
13
+ self.scss_pathname = scss_pathname
14
+ end
15
+
16
+ def write(dir, options = {})
17
+ PrettyDoc.mktmpdir do |tmppath|
18
+ tmpdir = Pathname.new(tmppath)
19
+ ::Compass.configuration.sass_path = scss_pathname.to_s
20
+ ::Compass.configuration.css_path = tmpdir.to_s
21
+
22
+ update_project = ::Compass::Commands::UpdateProject.new(
23
+ PrettyDoc.root.join('tmp').to_s,
24
+ quiet: true
25
+ )
26
+
27
+ update_project.perform
28
+
29
+ tmpdir.children.each do |child|
30
+ relative_pathname = child.relative_path_from(tmpdir)
31
+ FileUtils.cp(child, File.join(dir, relative_pathname))
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,46 @@
1
+ require 'pretty_doc/resource'
2
+
3
+ module PrettyDoc
4
+ class Resource
5
+ # Source Resource
6
+ class Source < Resource
7
+ attr_accessor :content, :basename
8
+
9
+ def initialize(file, converter, options)
10
+ self.file = file
11
+ extname = File.extname(file)
12
+ self.basename = File.basename(file, extname)
13
+ converter.content = File.read(self.file)
14
+ converter.options = options
15
+ self.content = converter.as_html
16
+ end
17
+
18
+ def write(target_dir, options = {})
19
+ template = options[:template]
20
+ result = template.render(content: content)
21
+ target = File.join(target_dir, "#{basename}.html")
22
+ File.open(target, 'w') { |f| f << result }
23
+ template.write_assets(target_dir)
24
+ puts "Create File: #{target}"
25
+ end
26
+
27
+ def self.build(options)
28
+ puts 'Converting files ...'
29
+ output_dir = options.output
30
+ options.files.each do |file|
31
+ extname = File.extname(file)
32
+ converter_class = PrettyDoc::Converter.descendants.find do |klass|
33
+ klass.perfer_exts.include?(extname)
34
+ end
35
+ if converter_class
36
+ converter = converter_class.new
37
+ result = new(file, converter, options)
38
+ result.write(output_dir, options)
39
+ else
40
+ puts 'No corresponding converter found!'
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,44 @@
1
+ require 'pretty_doc/resources/scss'
2
+ require 'erb'
3
+
4
+ module PrettyDoc
5
+ # Base Template class
6
+ class Template
7
+ attr_accessor :dir
8
+
9
+ class << self
10
+ def register(name, theme)
11
+ @pool ||= {}
12
+ @pool[name] = theme
13
+ end
14
+
15
+ def get(name)
16
+ @pool ||= {}
17
+ @pool[name]
18
+ end
19
+ end
20
+
21
+ def theme_file_pathname(file)
22
+ dir.join(file)
23
+ end
24
+
25
+ def assets
26
+ [Resource::Scss.new(dir)]
27
+ end
28
+
29
+ def render(hash)
30
+ erb_file = theme_file_pathname('template.html.erb')
31
+ template = ERB.new(erb_file.read)
32
+
33
+ @content = hash[:content]
34
+ @title = hash[:title]
35
+ template.result(binding)
36
+ end
37
+
38
+ def write_assets(dir)
39
+ assets.each do |asset|
40
+ asset.write(dir)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module PrettyDoc
2
+ VERSION = '1.0.0'
3
+ end
data/lib/pretty_doc.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ module PrettyDoc
5
+ end
6
+
7
+ require 'pretty_doc/version'
8
+ require 'pretty_doc/template'
9
+ require 'pretty_doc/converters/markdown'
10
+ require 'pretty_doc/resources/source'
11
+
12
+ # PrettyDoc Module
13
+ module PrettyDoc
14
+ def self.template(name)
15
+ @template_loaded = false
16
+ try_load_template_from_gem name
17
+ try_load_template_from_dir name
18
+ try_load_template_from_defaults name
19
+ tmpl = Template.get(File.basename(name))
20
+ if @template_loaded && tmpl
21
+ tmpl
22
+ else
23
+ puts "No valid template '#{name}' found"
24
+ exit
25
+ end
26
+ end
27
+
28
+ def self.try_load_template_from_gem(name = '')
29
+ unless @template_loaded
30
+ begin
31
+ require name
32
+ @template_loaded = true
33
+ rescue LoadError
34
+ @template_loaded = false
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.try_load_template_from_dir(name = '')
40
+ if !@template_loaded && Dir.exist?(File.expand_path(name))
41
+ begin
42
+ require File.join(File.expand_path(name), 'init.rb')
43
+ @template_loaded = true
44
+ rescue LoadError
45
+ @template_loaded = false
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.try_load_template_from_defaults(name = '')
51
+ unless @template_loaded
52
+ begin
53
+ require PrettyDoc.root.join('templates', name, 'init.rb')
54
+ @template_loaded = true
55
+ rescue LoadError
56
+ @template_loaded = false
57
+ end
58
+ end
59
+ end
60
+
61
+ def self.root
62
+ Pathname.new(File.expand_path('../../', __FILE__))
63
+ end
64
+
65
+ def self.tmpdir
66
+ PrettyDoc.root.join('tmp')
67
+ end
68
+
69
+ def self.mktmpdir
70
+ FileUtils.mkdir_p(tmpdir)
71
+ Dir.mktmpdir(nil, tmpdir) do |tmpdir|
72
+ yield(tmpdir)
73
+ end
74
+ end
75
+ end