literate_md 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.
Files changed (2) hide show
  1. data/bin/literate_md +107 -0
  2. metadata +106 -0
data/bin/literate_md ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/ruby -rubygems
2
+
3
+ require 'coderay'
4
+ require 'redcarpet'
5
+ require 'trollop'
6
+ require 'fileutils'
7
+
8
+ opts = Trollop::options do
9
+ opt :weave, "Produce documentation", :short => 'w'
10
+ opt :tangle, "Produce code", :short => 't'
11
+ opt :outputdir, "Directory to write files to", :default => Dir.pwd, :short => 'o'
12
+ opt :lang, "Default language of code", :default => "ruby", :short => 'l'
13
+ opt :files, "Files to process", :type => :string, :short => 'f', :required => true
14
+ end
15
+
16
+ $allowed = '(\w| )*|((.*:)?\*)'
17
+ html_opts = {
18
+ :fenced_code_blocks => true,
19
+ :superscript => true,
20
+ :tables => true,
21
+ :lax_html_blocks => true,
22
+ :strikethrough => true
23
+ }
24
+ $ext_for_lang = {
25
+ :ruby => 'rb',
26
+ :c => 'c',
27
+ }
28
+
29
+ class Weave < Redcarpet::Render::XHTML
30
+ attr_accessor :default_lang, :original_text
31
+ def block_code(code, lang)
32
+ l_ang, r_ang, equiv = "__lang__", "__rang__", "__equiv__"
33
+ line_num = @original_text[0,@original_text.index(code)].count("\n")+1
34
+ code = code.
35
+ gsub(/@(#{$allowed})@\s*\+=/,"#{l_ang}\\1#{r_ang}+#{equiv}").
36
+ gsub(/@(#{$allowed})@/,"#{l_ang}\\1#{r_ang}")
37
+ code = CodeRay.
38
+ scan(code, lang.nil? ? @default_lang : lang.to_sym).
39
+ html(
40
+ :wrap => :div,
41
+ :css => :style,
42
+ :line_numbers => :table,
43
+ :line_number_start => line_num)
44
+ code.
45
+ gsub(/#{l_ang}(#{$allowed})#{r_ang}(\s*)\+#{equiv}/,'&lang;\\1&rang;+&equiv;').
46
+ gsub(/#{l_ang}(#{$allowed})#{r_ang}/,'&lang;\\1&rang;')
47
+ end
48
+ def codespan(code); block_code(code,nil) end
49
+ end
50
+
51
+ def write_to path, data
52
+ FileUtils.mkdir_p(File.dirname(path))
53
+ File.open(path, 'w') {|f| f.write(data)}
54
+ end
55
+
56
+ if opts.weave
57
+ r = Redcarpet::Markdown.new(Weave, html_opts)
58
+ r.renderer.default_lang = opts.lang.to_sym
59
+ opts.files.split(',').each{|file|
60
+ code = File.open(file, 'r'){|f|f.read}
61
+ r.renderer.original_text = code
62
+ html = r.render(code)
63
+ write_to("#{opts.outputdir}/#{file}.html", html)
64
+ }
65
+ end
66
+
67
+ class Tangle < Redcarpet::Render::Base
68
+ attr_accessor :default_lang, :links, :file_no_ext
69
+ def block_code(code, lang)
70
+ chunks =
71
+ [{:start => 0, :anchor => '*', :anchor_len => 0}] +
72
+ code.scan(/(@(#{$allowed})@\s*\+=)/).map{|x|
73
+ {:start => code.index(x[0]), :anchor => x[1], :anchor_len => x[0].length}
74
+ } +
75
+ [{:start => code.length}]
76
+ (1..chunks.length-1).each{|index|
77
+ last, this = chunks[index-1], chunks[index]
78
+ @links[normalise(last[:anchor],lang)] << code[last[:start] + last[:anchor_len], this[:start]]
79
+ }
80
+ nil
81
+ end
82
+ def normalise(link_name, lang)
83
+ if link_name == '*'
84
+ "#{@file_no_ext}.#{$ext_for_lang[lang.nil? ? @default_lang : lang.to_sym]}:*"
85
+ else
86
+ link_name
87
+ end
88
+ end
89
+ def codespan(code); block_code(code,nil) end
90
+ end
91
+
92
+ if opts.tangle
93
+ links = Hash.new{|h,k|h[k]=[]}
94
+ r = Redcarpet::Markdown.new(Tangle, html_opts)
95
+ r.renderer.default_lang, r.renderer.links = opts.lang.to_sym, links
96
+ opts.files.split(',').each{|file|
97
+ r.renderer.file_no_ext = file[0,file.rindex('.')]
98
+ r.render(File.open(file, 'r'){|f|f.read})
99
+ }
100
+ resolve = lambda{|parts| parts.join('').gsub(/@(#{$allowed})@/) {|match|resolve.call(links[match[1..-2]])} }
101
+ links.keys.reject{|k|!k.end_with? ':*'}.each{|root|
102
+ write_to(
103
+ "#{opts.outputdir}/#{root[0..-3]}",
104
+ resolve.call(links[root]))
105
+ }
106
+ end
107
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: literate_md
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - remis
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-08 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: redcarpet
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: coderay
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: trollop
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ description: A simple hello world gem
63
+ email:
64
+ executables:
65
+ - literate_md
66
+ extensions: []
67
+
68
+ extra_rdoc_files: []
69
+
70
+ files:
71
+ - bin/literate_md
72
+ homepage: http://remis-thoughts.blogspot.com
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.5
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Convert markdown documents into code or html
105
+ test_files: []
106
+