kui-md 0.0.1

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.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *~
19
+ .rbenv-version
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in md.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Keiichiro Ui
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ kui-md
2
+ ====================================
3
+
4
+ 自分向けの markdown 変換器。Graphviz によるグラフ作成や、Pygments.rb による
5
+ コードのシンタックスハイライトもできる。
6
+
7
+
8
+ インストール
9
+ ----------------------------------
10
+
11
+ 下記のコマンドを実行する。
12
+
13
+ ~~~~~~~~~~~~~~~~~sh
14
+ $ gem install kui-md
15
+ ~~~~~~~~~~~~~~~~~
16
+
17
+
18
+ 使い方
19
+ ----------------------------------
20
+
21
+ こんな感じで markdown の変換ができる。
22
+
23
+ ~~~~~~~~~~~~~~~~~sh
24
+ $ md -h
25
+ $ md foo.markdown
26
+ $ md foo.markdown output.html
27
+ ~~~~~~~~~~~~~~~~~
28
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ # -*- coding:utf-8-unix; mode:ruby; -*-
3
+
4
+ require "bundler/gem_tasks"
5
+ require "rspec/core"
6
+ require "rspec/core/rake_task"
7
+
8
+ desc "Run all specs in spec/*_spec.rb"
9
+ RSpec::Core::RakeTask.new :spec
10
+
11
+ task :build => :spec
12
+ task :default => :spec
data/bin/md ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding:utf-8-unix; mode:ruby; -*-
3
+
4
+ require 'rubygems'
5
+ require 'md'
6
+
7
+ Md::CLI::run *ARGV
@@ -0,0 +1,26 @@
1
+ # -*- coding:utf-8; mode:ruby; -*-
2
+
3
+ title_format "%s - メモ"
4
+
5
+ # see https://github.com/tanoku/redcarpet
6
+ enable_markdown_opts :fenced_code_blocks, :tables, :no_intra_emphasis, :autolink,
7
+ :strikethrough, :space_after_headers, :superscript
8
+ enable_html_opts
9
+
10
+ # see `pygmentize -H formatter html`
11
+ pygments_opts({
12
+ :cssclass => 'hll',
13
+ :classprefix => 'pyg',
14
+ #:linenos => 'table',
15
+ #:linenos => 'inline',
16
+ :linenos => nil,
17
+ :style => 'native',
18
+ })
19
+
20
+ css <<EOS
21
+ h1, h2, h3, h4, h5, h6, p, ul, ol, pre, div {
22
+ color: #333;
23
+ }
24
+ EOS
25
+
26
+ script "// foo"
@@ -0,0 +1,12 @@
1
+ # -*- coding:utf-8-unix; mode:ruby; -*-
2
+
3
+ require 'md/version'
4
+ require 'md/configure'
5
+ require 'md/renderer'
6
+ require 'md/cli'
7
+
8
+ module Md
9
+ USAGE = <<EOS
10
+ Usage: #{$0} SOURCE_FILE [ DEST_FILE ]
11
+ EOS
12
+ end
@@ -0,0 +1,110 @@
1
+ # -*- coding:utf-8-unix; mode:ruby; -*-
2
+
3
+ require 'optparse'
4
+
5
+ module Md
6
+
7
+ # a command line interface
8
+ class CLI
9
+
10
+ DEFAULT_CONFIG_NAME = ".md/config.rb"
11
+ DEFAULT_CONFIG_PATH = File.join ENV['HOME'], DEFAULT_CONFIG_NAME
12
+
13
+ def self.run *args
14
+ new.run *args
15
+ end
16
+
17
+ # a configure file path
18
+ attr_reader :config_file
19
+
20
+ # a render options
21
+ attr_reader :opts
22
+
23
+ # a command which will be executed
24
+ attr_reader :cmd
25
+
26
+ # a usage message
27
+ attr_reader :usage
28
+
29
+ def initialize
30
+ @config_file = DEFAULT_CONFIG_PATH
31
+ @cmd = :render
32
+ @usage = USAGE
33
+ @opts = {}
34
+ end
35
+
36
+ def run *args
37
+ load_config
38
+ parse_opts args
39
+ begin
40
+ method(@cmd).call(args[0], args[1])
41
+ rescue Exception => e
42
+ if $DEBUG
43
+ raise e
44
+ else
45
+ err 1, "ERROR: #{e.message}"
46
+ end
47
+ end
48
+ end
49
+
50
+ def parse_opts args
51
+ opt = OptionParser.new USAGE
52
+
53
+ opt.on('-c VAL', '--config VAL',
54
+ "specify a configure file. (default: '#{DEFAULT_CONFIG_PATH}')") do |v|
55
+ @config_file = v
56
+ end
57
+
58
+ opt.on('--with-wrapping-html',
59
+ 'wrap the converted html with html and body elements') do
60
+ @opts[:wrapping_html] = true
61
+ end
62
+ opt.on('--without-wrapping-html',
63
+ 'do not wrap the converted html with html and body elements') do
64
+ @opts[:wrapping_html] = false
65
+ end
66
+
67
+ opt.parse! args
68
+ @usage = opt.help
69
+ end
70
+
71
+ def err code = 1, msg = nil
72
+ puts msg if msg
73
+ puts @usage
74
+ exit code
75
+ end
76
+
77
+ def load_config
78
+ if not File.exists? @config_file
79
+ require 'fileutils'
80
+ FileUtils.mkdir_p File.dirname @config_file
81
+ FileUtils.touch @config_file
82
+ end
83
+ config = Configure.new(@config_file)
84
+ @opts.merge! config[:html]
85
+
86
+ [:markdown, :pygments, :css, :script, :wrapping_html, :title_format].each do |s|
87
+ @opts[s] = config[s] if config[s]
88
+ end
89
+ end
90
+
91
+ # a default command
92
+ def render src, dest
93
+ if not src
94
+ raise ArgumentError, "expect to specify a src file"
95
+ end
96
+
97
+ renderer = Md::Renderer.new @opts
98
+ open src do |f|
99
+ result = Redcarpet::Markdown.new(renderer, @opts[:markdown]).render f.read
100
+ if dest
101
+ open dest, 'w' do |w|
102
+ w.write result
103
+ end
104
+ else
105
+ print result
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,143 @@
1
+ # -*- coding:utf-8-unix; mode:ruby; -*-
2
+
3
+ require 'forwardable'
4
+
5
+ module Md
6
+
7
+ # a config DSL parser
8
+ class Configure
9
+
10
+ # options for Redcarpet::Render::HTML
11
+ KNOWN_HTML_OPTS = [
12
+ :filter_html,
13
+ :no_images,
14
+ :no_links,
15
+ :no_styles,
16
+ :safe_links_only,
17
+ :with_toc_data,
18
+ :hard_wrap,
19
+ :xhtml,
20
+ ]
21
+
22
+ # options for Redcarpet::Markdown
23
+ KNOWN_MARKDOWN_OPTS = [
24
+ :no_intra_emphasis,
25
+ :tables,
26
+ :fenced_code_blocks,
27
+ :autolink,
28
+ :strikethrough,
29
+ :lax_html_blocks,
30
+ :space_after_headers ,
31
+ :superscript,
32
+ ]
33
+
34
+ KNOWN_PYGMENTS_OPTS = [
35
+ # specify a formatter
36
+ # see `pygmentize -L formatters`
37
+ #:formatter,
38
+
39
+ # options for HtmlFormatter
40
+ # see `pygmentize -H formatter html`
41
+ :nowrap,
42
+ :full,
43
+ :title,
44
+ :style,
45
+ :noclasses,
46
+ :classprefix,
47
+ :cssclass,
48
+ :cssstyles,
49
+ :prestyles,
50
+ :cssfile,
51
+ :noclobber_cssfile,
52
+ :linenos,
53
+ :hl_lines,
54
+ :linenostart,
55
+ :linenostep,
56
+ :linenospecial,
57
+ :nobackground,
58
+ :lineseparator,
59
+ :lineanchors,
60
+ :anchorlinenos,
61
+ ]
62
+
63
+ extend Forwardable
64
+ def_delegators :@map, :[]
65
+
66
+ def initialize file_path = nil
67
+ @map = {}
68
+ @map[:html] = Hash[*KNOWN_HTML_OPTS.map{|o|[o,false]}.flatten]
69
+ @map[:markdown] = Hash[*KNOWN_MARKDOWN_OPTS.map{|o|[o,false]}.flatten]
70
+ @map[:pygments] = {}
71
+ @map[:css] = []
72
+ @map[:script] = []
73
+ @renderer = nil
74
+ include file_path if file_path
75
+ end
76
+
77
+ def include file_path
78
+ open file_path do |f|
79
+ eval f.read
80
+ end
81
+ end
82
+
83
+ def wrapping_html bool
84
+ @map[:wrapping_html] = bool
85
+ end
86
+
87
+ def css style
88
+ raise "expect a String" if not style.kind_of? String
89
+ @map[:css].push style
90
+ end
91
+
92
+ def script src
93
+ raise "expect a String" if not src.kind_of? String
94
+ @map[:script].push src
95
+ end
96
+
97
+ def title_format format
98
+ if not format.kind_of? String
99
+ raise "expect a String"
100
+ end
101
+ @map[:title_format] = format
102
+ end
103
+
104
+ def enable_html_opts *opts
105
+ opts.each {|o| html_opt o, true }
106
+ end
107
+
108
+ def disable_html_opts *opts
109
+ opts.each {|o| html_opt o, false }
110
+ end
111
+
112
+ def enable_markdown_opts *opts
113
+ opts.each {|o| markdown_opt o, true}
114
+ end
115
+
116
+ def disable_markdown_opts *opts
117
+ opts.each {|o| markdown_opt o, false}
118
+ end
119
+
120
+ def pygments_opts *args
121
+ if args.first.kind_of? Hash
122
+ @map[:pygments].merge! args.first
123
+ else
124
+ if args.length != 2
125
+ raise 'expect a hash or a pair with an option name and a value'
126
+ end
127
+ o, v = args
128
+ raise "unknown pygments option (#{o})" if not KNOWN_PYGMENTS_OPTS.include? o
129
+ @map[:pygments][o] = v
130
+ end
131
+ end
132
+
133
+ def html_opt o, v
134
+ raise "unknown html option (#{o})" if not KNOWN_HTML_OPTS.include? o
135
+ @map[:html][o] = v
136
+ end
137
+
138
+ def markdown_opt o, v
139
+ raise "unknown markdown option (#{o})" if not KNOWN_MARKDOWN_OPTS.include? o
140
+ @map[:markdown][o] = v
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,114 @@
1
+ # -*- coding:utf-8; mode:ruby; -*-
2
+
3
+ require 'redcarpet'
4
+ require 'pygments'
5
+ require 'graphviz'
6
+
7
+ module Md
8
+ class Renderer < Redcarpet::Render::HTML
9
+
10
+ attr_accessor :opts
11
+
12
+ def initialize opts = {}
13
+ super
14
+ @opts = opts
15
+ @opts[:pygments] ||= {}
16
+ @opts[:graphviz] ||= {
17
+ :format => :svg
18
+ }
19
+ @opts[:graphviz][:format] ||= :svg
20
+ @opts[:wrapping_html] = true if not @opts.key? :wrapping_html
21
+ @opts[:css] ||= []
22
+ @opts[:script] ||= []
23
+ @opts[:title_format] ||= "%s"
24
+
25
+ @opts[:css].push Pygments.css @opts[:pygments]
26
+ end
27
+
28
+ def block_code code, lang
29
+ if lang.casecmp('graphviz') == 0
30
+ block_code_graphviz code
31
+ elsif lang.casecmp('graph') == 0
32
+ block_code_graph code
33
+ elsif lang.casecmp('digraph') == 0
34
+ block_code_digraph code
35
+ else
36
+ block_code_default code, lang
37
+ end
38
+ end
39
+
40
+ def block_code_default code, lang
41
+ @opts[:pygments][:full] = false
42
+ opts = {:lexer => lang, :options => @opts[:pygments]}
43
+ return Pygments.highlight code, opts
44
+ end
45
+
46
+ def block_code_digraph code
47
+ block_code_digraph "digraph g { #{code} }"
48
+ end
49
+
50
+ def block_code_graph code
51
+ block_code_graphviz "graph g { #{code} }"
52
+ end
53
+
54
+ def block_code_graphviz code
55
+ opts = {:svg => String}
56
+ block_code_svg GraphViz.parse_string(code).output(opts)
57
+ end
58
+
59
+ def block_code_svg code
60
+ remove_doctype_declaration remove_xml_declaration code
61
+ end
62
+
63
+ def remove_doctype_declaration code
64
+ code.sub(/<!DOCTYPE .+?>/im,'')
65
+ end
66
+
67
+ def remove_xml_declaration code
68
+ code.sub(/<\?xml .+?\?>/im,'')
69
+ end
70
+
71
+ def postprocess html
72
+ html = wrapp_with_html html if @opts[:wrapping_html]
73
+ return html
74
+ end
75
+
76
+ def wrapp_with_html html
77
+ return "<!DOCTYPE html>\n" +
78
+ "<html><head>\n" +
79
+ head_element_content(html) +
80
+ "</head>\n"+
81
+ "<body>#{html}</body></html>\n"
82
+ end
83
+
84
+ def head_element_content html
85
+ content = ""
86
+
87
+ content << %{<meta charset="utf-8" />\n}
88
+
89
+ title = scrape_title html
90
+ content << "<title>#{@opts[:title_format]}</title>\n" % title if title
91
+
92
+ @opts[:css].each do |style|
93
+ content << "<style>#{minify_css style}</style>\n"
94
+ end if @opts[:css]
95
+
96
+ @opts[:script].each do |src|
97
+ content << "<script>\n#{src}\n</script>\n"
98
+ end if @opts[:script]
99
+
100
+ return content
101
+ end
102
+
103
+ # get first h1, h2 or h3 element content
104
+ def scrape_title html
105
+ m = html.match(/<h[1-3][^>]*>(.+?)<\/h[1-3]>/)
106
+ return (m and m[1])
107
+ end
108
+
109
+ # remove space and new line code
110
+ def minify_css text
111
+ text.gsub(%r{/\*.+?\*/}, '').gsub(/\s+/,'')
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,3 @@
1
+ module Md
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ # -*- coding:utf-8-unix; mode:ruby; -*-
2
+
3
+ require File.expand_path('../lib/md/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ["Keiichiro Ui"]
7
+ gem.email = ["keiichiro.ui@gmail.com"]
8
+ gem.summary = "a markdown engine which makes you to describe a graph with Graphviz and highlight codes"
9
+ gem.description = nil
10
+ gem.homepage = "http://k-ui.jp/"
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
+ gem.name = "kui-md"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = Md::VERSION
18
+
19
+ gem.add_runtime_dependency 'redcarpet', '>= 2'
20
+ gem.add_runtime_dependency 'pygments.rb'
21
+ gem.add_runtime_dependency 'ruby-graphviz'
22
+ gem.add_development_dependency 'rake'
23
+ gem.add_development_dependency 'rspec'
24
+ gem.add_development_dependency 'bundler'
25
+ end
@@ -0,0 +1,20 @@
1
+ # -*- coding:utf-8-unix; mode:ruby; -*-
2
+
3
+ require 'md'
4
+
5
+ include Md
6
+
7
+ describe CLI do
8
+
9
+ before do
10
+ @src_file_path = 'foo'
11
+ @src_file_content = 'foo content'
12
+ @src_file = mock File
13
+
14
+ @renderer = mock Renderer
15
+ Renderer.stub(:new){ @renderer }
16
+
17
+ @cli = CLI.new
18
+ end
19
+
20
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kui-md
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Keiichiro Ui
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redcarpet
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: pygments.rb
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: ruby-graphviz
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: bundler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: ''
111
+ email:
112
+ - keiichiro.ui@gmail.com
113
+ executables:
114
+ - md
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - Gemfile
120
+ - LICENSE
121
+ - README.md
122
+ - Rakefile
123
+ - bin/md
124
+ - example/config.rb
125
+ - lib/md.rb
126
+ - lib/md/cli.rb
127
+ - lib/md/configure.rb
128
+ - lib/md/renderer.rb
129
+ - lib/md/version.rb
130
+ - md.gemspec
131
+ - spec/cli_spec.rb
132
+ homepage: http://k-ui.jp/
133
+ licenses: []
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 1.8.23
153
+ signing_key:
154
+ specification_version: 3
155
+ summary: a markdown engine which makes you to describe a graph with Graphviz and highlight
156
+ codes
157
+ test_files:
158
+ - spec/cli_spec.rb