guides 0.6.5 → 0.6.6

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,3 +1,7 @@
1
+ require "bundler/setup"
2
+ require "guides/version"
3
+ require "erb"
4
+
1
5
  file "Guides/local/guides/bundle" => "Gemfile" do
2
6
  require "rbconfig"
3
7
 
@@ -43,13 +47,79 @@ file "Guides/bin/guides" => "bin/guides" do
43
47
 
44
48
  sh "mkdir -p Guides/bin"
45
49
  File.open("Guides/bin/guides", "w") { |file| file.puts guides }
50
+ File.chmod 0755, "Guides/bin/guides"
46
51
  end
47
52
 
48
53
  desc "Prep the release for PackageMaker"
49
- task :pkg => ["Guides/local/guides/bundle", "Guides/local/guides/lib", "Guides/bin/guides"]
54
+ task :make_pkg => ["Guides/local/guides/bundle", "Guides/local/guides/lib", "Guides/bin/guides"]
50
55
 
51
56
  task :rm do
52
57
  rm_rf "Guides"
53
58
  end
54
59
 
60
+ directory "guides-pkg/Resources"
61
+ directory "guides-pkg/guides.pkg"
62
+
63
+ pkg_dependencies = [:make_pkg, "guides-pkg/Resources", "guides-pkg/guides.pkg",
64
+ "guides-pkg/Distribution", "guides-pkg/guides.pkg/Bom",
65
+ "guides-pkg/guides.pkg/PackageInfo", "guides-pkg/guides.pkg/Payload"]
66
+
67
+ def details
68
+ @details ||= begin
69
+ total_size, files = 0, 0
70
+
71
+ Dir["Guides/**/*"].each do |file|
72
+ files += 1
73
+
74
+ next if File.directory?(file)
75
+
76
+ total_size += File.size(file)
77
+ end
78
+
79
+ [total_size, files]
80
+ end
81
+ end
82
+
83
+ file "guides-pkg/Distribution" do
84
+ src = File.read File.expand_path("../build/Distribution.erb", __FILE__)
85
+ erb = ERB.new(src)
86
+
87
+ total_size, files = details
88
+
89
+ kbytes = total_size / 1024
90
+ version = Guides::VERSION
91
+
92
+ File.open("guides-pkg/Distribution", "w") do |file|
93
+ file.puts erb.result(binding)
94
+ end
95
+ end
96
+
97
+ file "guides-pkg/guides.pkg/PackageInfo" do
98
+ src = File.read File.expand_path("../build/PackageInfo.erb", __FILE__)
99
+ erb = ERB.new(src)
100
+
101
+ total_size, num_files = details
102
+
103
+ kbytes = total_size / 1024
104
+ version = Guides::VERSION
105
+
106
+ File.open("guides-pkg/guides.pkg/PackageInfo", "w") do |file|
107
+ file.puts erb.result(binding)
108
+ end
109
+ end
110
+
111
+ file "guides-pkg/guides.pkg/Bom" do
112
+ sh "mkbom -s Guides guides-pkg/guides.pkg/Bom"
113
+ end
114
+
115
+ file "guides-pkg/guides.pkg/Payload" do
116
+ sh "cd Guides && pax -wz -x cpio . > ../guides-pkg/guides.pkg/Payload"
117
+ end
118
+
119
+ file "Guides.pkg" => pkg_dependencies do
120
+ sh "pkgutil --flatten guides-pkg Guides.pkg"
121
+ end
122
+
123
+ task :pkg => "Guides.pkg"
124
+
55
125
  task :clean => [:rm, :pkg]
data/guides.gemspec CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.add_dependency "activesupport", "~> 3.0.0"
22
22
  s.add_dependency "rack", "~> 1.2.1"
23
23
  s.add_dependency "RedCloth", "~> 4.1.1"
24
+ s.add_dependency "maruku", "~> 0.6.0"
24
25
  s.add_dependency "thor", "~> 0.14.6"
25
26
  s.add_dependency "thin", "~> 1.2.7"
26
27
 
data/lib/guides.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require "action_pack"
2
2
  require "redcloth"
3
+ require "maruku"
3
4
 
4
5
  require "guides/textile_extensions"
6
+ require "guides/markdown_extensions"
5
7
  require "guides/generator"
6
8
 
7
9
  module Guides
@@ -61,7 +61,7 @@ module Guides
61
61
  class Generator
62
62
  attr_reader :guides_dir, :source_dir, :output_dir, :edge, :warnings, :all
63
63
 
64
- EXTENSIONS = %w(textile html.erb)
64
+ EXTENSIONS = %w(textile md html.erb)
65
65
  GUIDES_RE = /\.(?:#{EXTENSIONS.map{|e| Regexp.escape(e)}.join('|')})$/
66
66
  LOCAL_ASSETS = File.expand_path("../templates/assets", __FILE__)
67
67
 
@@ -86,33 +86,6 @@ module Guides
86
86
  copy_assets
87
87
  end
88
88
 
89
- def generate_guide(guide, output_file)
90
- return unless generate?(guide, output_file)
91
-
92
- puts "Generating #{output_file}"
93
- File.open(File.join(output_dir, output_file), 'w') do |f|
94
- view = ActionView::Base.new(source_dir, :edge => edge)
95
- view.extend(Helpers)
96
-
97
- if guide =~ /\.html\.erb$/
98
- # Generate the special pages like the home.
99
- view.render("sections")
100
- type = @edge ? "edge" : "normal"
101
- result = view.render(:layout => 'layout', :file => guide, :locals => {:guide_type => type})
102
- else
103
- body = File.read(File.join(source_dir, guide))
104
- body = set_header_section(body, view)
105
- body = set_index(body, view)
106
-
107
- result = view.render(:layout => 'layout', :text => textile(body))
108
-
109
- warn_about_broken_links(result) if @warnings
110
- end
111
-
112
- f.write result
113
- end
114
- end
115
-
116
89
  private
117
90
  def generate_guides
118
91
  guides_to_generate.each do |guide|
@@ -165,11 +138,15 @@ module Guides
165
138
  type = @edge ? "edge" : "normal"
166
139
  result = view.render(:layout => 'layout', :file => guide, :locals => {:guide_type => type})
167
140
  else
141
+ processor = (guide =~ /\.md$/) ? :markdown : :textile
142
+
168
143
  body = File.read(File.join(source_dir, guide))
169
- body = set_header_section(body, view)
170
- body = set_index(body, view)
144
+ body = set_header_section(body, view, processor)
145
+ body = set_index(body, view, processor)
171
146
 
172
- result = view.render(:layout => 'layout', :text => textile(body))
147
+ text = (processor == :markdown) ? markdown(body) : textile(body)
148
+
149
+ result = view.render(:layout => 'layout', :text => text)
173
150
 
174
151
  warn_about_broken_links(result) if @warnings
175
152
  end
@@ -178,7 +155,7 @@ module Guides
178
155
  end
179
156
  end
180
157
 
181
- def set_header_section(body, view)
158
+ def set_header_section(body, view, processor)
182
159
  new_body = body.sub(/(.*?)endprologue\./m, '').strip
183
160
  header = $1
184
161
 
@@ -186,20 +163,28 @@ module Guides
186
163
  raise FormatError, "A prologue is required. Use 'endprologue.' to separate the prologue from the main body."
187
164
  end
188
165
 
189
- if header =~ /h2\.(.*)/
190
- page_title = "#{@meta["title"]}: #{$1.strip}"
166
+ if processor == :markdown
167
+ if header =~ /^(.+)\r?\n-+$/ || header =~ /^## (.+)$/
168
+ page_title = "#{@meta["title"]}: #{$1.strip}"
169
+ else
170
+ raise FormatError, "A title is required. Underline the title with '------' or prefix it with '##'"
171
+ end
191
172
  else
192
- raise FormatError, "A title is required. Use the 'h2.' declaration to denote the title."
173
+ if header =~ /h2\.(.*)/
174
+ page_title = "#{@meta["title"]}: #{$1.strip}"
175
+ else
176
+ raise FormatError, "A title is required. Use the 'h2.' declaration to denote the title."
177
+ end
193
178
  end
194
179
 
195
- header = textile(header)
180
+ header = (processor == :markdown) ? markdown(header) : textile(header)
196
181
 
197
182
  view.content_for(:page_title) { page_title.html_safe }
198
183
  view.content_for(:header_section) { header.html_safe }
199
184
  new_body
200
185
  end
201
186
 
202
- def set_index(body, view)
187
+ def set_index(body, view, processor)
203
188
  index = <<-INDEX
204
189
  <div id="subCol">
205
190
  <h3 class="chapter"><img src="images/chapters_icon.gif" alt="" />Chapters</h3>
@@ -211,11 +196,16 @@ module Guides
211
196
 
212
197
  # Set index for 2 levels
213
198
  i.level_hash.each do |key, value|
214
- link = view.content_tag(:a, :href => key[:id]) { textile(key[:title], true).html_safe }
199
+ link = view.content_tag(:a, :href => key[:id]) do
200
+ (processor == :markdown ? markdown(key[:title]) : textile(key[:title], true)).html_safe
201
+ end
215
202
 
216
203
  children = value.keys.map do |k|
217
- view.content_tag(:li,
218
- view.content_tag(:a, :href => k[:id]) { textile(k[:title], true).html_safe })
204
+ view.content_tag :li do
205
+ view.content_tag(:a, :href => k[:id]) do
206
+ (processor == :markdown ? markdown(k[:title]) : textile(k[:title], true)).html_safe
207
+ end
208
+ end
219
209
  end
220
210
 
221
211
  children_ul = children.empty? ? "" : view.content_tag(:ul, children.join(" ").html_safe)
@@ -237,10 +227,14 @@ module Guides
237
227
  t = RedCloth.new(new_body)
238
228
  t.hard_breaks = false
239
229
  t.lite_mode = lite_mode
240
- t.to_html(:notestuff, :plusplus, :code, :tip)
230
+ t.to_html(:notestuff, :plusplus)
241
231
  end
242
232
  end
243
233
 
234
+ def markdown(body)
235
+ Maruku.new(body).to_html
236
+ end
237
+
244
238
  # For some reason the notextile tag does not always turn off textile. See
245
239
  # LH ticket of the security guide (#7). As a temporary workaround we deal
246
240
  # with code blocks by hand.
@@ -0,0 +1,77 @@
1
+ # Hack for buggy method that thinks NOTE is an email header
2
+ class MaRuKu::MDDocument
3
+ def parse_email_headers(s)
4
+ { :data => s}
5
+ end
6
+ end
7
+
8
+
9
+ OpenCodeRegexp = /<(yaml|shell|ruby|erb|html|sql|plain|javascript|css)>/
10
+ CloseCodeRegexp = lambda{|type| /<\/#{type}>/ }
11
+
12
+ NoteRegexp = /^(IMPORTANT|CAUTION|WARNING|NOTE|INFO|TIP)[.:](.*)/
13
+
14
+ Maruku::In::Markdown.register_block_extension(
15
+ :regexp => OpenCodeRegexp,
16
+ :handler => lambda{|doc, src, context|
17
+ # Double check first line to get type
18
+ type = src.shift_line.match(OpenCodeRegexp)[1]
19
+
20
+ # Get all intermediate lines
21
+ body = ""
22
+ while src.cur_line && src.cur_line !~ CloseCodeRegexp.call(type)
23
+ body << src.shift_line + "\n"
24
+ end
25
+
26
+ # Throw away last line
27
+ src.shift_line
28
+
29
+
30
+ brush = case type
31
+ when 'ruby', 'sql', 'javascript', 'css', 'plain'
32
+ type
33
+ when 'erb'
34
+ 'ruby; html-script: true'
35
+ when 'html'
36
+ 'xml' # html is understood, but there are .xml rules in the CSS
37
+ else
38
+ 'plain'
39
+ end
40
+
41
+ context.push doc.md_html(<<HTML
42
+ <div class="code_container">
43
+ <pre class="brush: #{brush}; gutter: false; toolbar: false">
44
+ #{ERB::Util.h(body.strip)}
45
+ </pre>
46
+ </div>
47
+ HTML
48
+ )
49
+ true
50
+ }
51
+ )
52
+
53
+
54
+ Maruku::In::Markdown.register_block_extension(
55
+ :regexp => NoteRegexp,
56
+ :handler => lambda{|doc, src, context|
57
+ # Double check first line to get type and starting text
58
+ type, body = src.shift_line.match(NoteRegexp).captures
59
+
60
+ # Get all intermediate lines
61
+ while src.cur_line && src.cur_line.strip.length > 0
62
+ body << " #{src.shift_line}"
63
+ end
64
+
65
+ css_class = type.downcase
66
+ css_class = 'warning' if ['caution', 'important'].include?(css_class)
67
+ css_class = 'info' if css_class == 'tip'
68
+
69
+ result = "<div class='#{css_class}'><p>"
70
+ result << body.strip
71
+ result << '</p></div>'
72
+
73
+ context.push doc.md_html(result)
74
+ true
75
+ }
76
+ )
77
+
@@ -1,8 +1,9 @@
1
1
  class RedCloth::TextileDoc
2
2
  def notestuff(body)
3
- body.gsub!(/^(IMPORTANT|CAUTION|WARNING|NOTE|INFO)[.:](.*)$/) do |m|
3
+ body.gsub!(/^(IMPORTANT|CAUTION|WARNING|NOTE|INFO|TIP)[.:](.*?)(?=((\r?\n){2}|\z))/m) do |m|
4
4
  css_class = $1.downcase
5
5
  css_class = 'warning' if ['caution', 'important'].include?(css_class)
6
+ css_class = 'info' if css_class == 'tip'
6
7
 
7
8
  result = "<div class='#{css_class}'><p>"
8
9
  result << $2.strip
@@ -11,15 +12,6 @@ class RedCloth::TextileDoc
11
12
  end
12
13
  end
13
14
 
14
- def tip(body)
15
- body.gsub!(/^TIP[.:](.*)$/) do |m|
16
- result = "<div class='info'><p>"
17
- result << $1.strip
18
- result << '</p></div>'
19
- result
20
- end
21
- end
22
-
23
15
  def plusplus(body)
24
16
  body.gsub!(/\+(.*?)\+/) do |m|
25
17
  "<notextile><tt>#{$1}</tt></notextile>"
@@ -28,12 +20,4 @@ class RedCloth::TextileDoc
28
20
  # The real plus sign
29
21
  body.gsub!('<plus>', '+')
30
22
  end
31
-
32
- def code(body)
33
- body.gsub!(%r{<(yaml|shell|ruby|erb|html|sql|plain)>(.*?)</\1>}m) do |m|
34
- es = ERB::Util.h($2)
35
- css_class = ['erb', 'shell'].include?($1) ? 'html' : $1
36
- %{<notextile><div class="code_container"><code class="#{css_class}">#{es}</code></div></notextile>}
37
- end
38
- end
39
23
  end
@@ -1,3 +1,3 @@
1
1
  module Guides
2
- VERSION = "0.6.5"
2
+ VERSION = "0.6.6"
3
3
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 6
8
- - 5
9
- version: 0.6.5
8
+ - 6
9
+ version: 0.6.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Yehuda Katz
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-20 00:00:00 -08:00
17
+ date: 2011-02-02 00:00:00 -08:00
18
18
  default_executable: guides
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -78,9 +78,24 @@ dependencies:
78
78
  type: :runtime
79
79
  version_requirements: *id004
80
80
  - !ruby/object:Gem::Dependency
81
- name: thor
81
+ name: maruku
82
82
  prerelease: false
83
83
  requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ - 6
91
+ - 0
92
+ version: 0.6.0
93
+ type: :runtime
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ name: thor
97
+ prerelease: false
98
+ requirement: &id006 !ruby/object:Gem::Requirement
84
99
  none: false
85
100
  requirements:
86
101
  - - ~>
@@ -91,11 +106,11 @@ dependencies:
91
106
  - 6
92
107
  version: 0.14.6
93
108
  type: :runtime
94
- version_requirements: *id005
109
+ version_requirements: *id006
95
110
  - !ruby/object:Gem::Dependency
96
111
  name: thin
97
112
  prerelease: false
98
- requirement: &id006 !ruby/object:Gem::Requirement
113
+ requirement: &id007 !ruby/object:Gem::Requirement
99
114
  none: false
100
115
  requirements:
101
116
  - - ~>
@@ -106,7 +121,7 @@ dependencies:
106
121
  - 7
107
122
  version: 1.2.7
108
123
  type: :runtime
109
- version_requirements: *id006
124
+ version_requirements: *id007
110
125
  description: A tool for creating version controlled guides for open source projects, based on the Rails Guides framework
111
126
  email:
112
127
  - wycats@gmail.com
@@ -128,6 +143,7 @@ files:
128
143
  - lib/guides/helpers.rb
129
144
  - lib/guides/indexer.rb
130
145
  - lib/guides/levenshtein.rb
146
+ - lib/guides/markdown_extensions.rb
131
147
  - lib/guides/new.rb
132
148
  - lib/guides/preview.rb
133
149
  - lib/guides/templates/assets/images/book_icon.gif