guides 0.6.5 → 0.6.6
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.
- data/Rakefile +71 -1
- data/guides.gemspec +1 -0
- data/lib/guides.rb +2 -0
- data/lib/guides/generator.rb +35 -41
- data/lib/guides/markdown_extensions.rb +77 -0
- data/lib/guides/textile_extensions.rb +2 -18
- data/lib/guides/version.rb +1 -1
- metadata +23 -7
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 :
|
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
data/lib/guides/generator.rb
CHANGED
@@ -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
|
-
|
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
|
190
|
-
|
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
|
-
|
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])
|
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
|
218
|
-
view.content_tag(:a, :href => k[:id])
|
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
|
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)[.:](
|
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
|
data/lib/guides/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 6
|
8
|
-
-
|
9
|
-
version: 0.6.
|
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-
|
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:
|
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: *
|
109
|
+
version_requirements: *id006
|
95
110
|
- !ruby/object:Gem::Dependency
|
96
111
|
name: thin
|
97
112
|
prerelease: false
|
98
|
-
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: *
|
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
|