fnando-kitabu 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +59 -0
- data/License.txt +20 -0
- data/README.markdown +216 -0
- data/Rakefile +68 -0
- data/TODO.txt +2 -0
- data/app_generators/kitabu/USAGE +5 -0
- data/app_generators/kitabu/kitabu_generator.rb +68 -0
- data/app_generators/kitabu/templates/Rakefile +3 -0
- data/app_generators/kitabu/templates/config.yml +8 -0
- data/app_generators/kitabu/templates/css/active4d.css +114 -0
- data/app_generators/kitabu/templates/css/blackboard.css +88 -0
- data/app_generators/kitabu/templates/css/dawn.css +121 -0
- data/app_generators/kitabu/templates/css/eiffel.css +121 -0
- data/app_generators/kitabu/templates/css/idle.css +62 -0
- data/app_generators/kitabu/templates/css/iplastic.css +80 -0
- data/app_generators/kitabu/templates/css/lazy.css +73 -0
- data/app_generators/kitabu/templates/css/mac_classic.css +123 -0
- data/app_generators/kitabu/templates/css/slush_poppies.css +85 -0
- data/app_generators/kitabu/templates/css/sunburst.css +180 -0
- data/app_generators/kitabu/templates/layouts/boom/layout.css +469 -0
- data/app_generators/kitabu/templates/layouts/boom/layout.html +37 -0
- data/app_generators/kitabu/templates/user.css +0 -0
- data/bin/kitabu +17 -0
- data/kitabu.gemspec +79 -0
- data/lib/kitabu/base.rb +332 -0
- data/lib/kitabu/blackcloth.rb +165 -0
- data/lib/kitabu/redcloth.rb +963 -0
- data/lib/kitabu/tasks.rb +119 -0
- data/lib/kitabu.rb +18 -0
- data/themes/active4d.css +114 -0
- data/themes/all_hallows_eve.css +72 -0
- data/themes/amy.css +147 -0
- data/themes/blackboard.css +88 -0
- data/themes/brilliance_black.css +605 -0
- data/themes/brilliance_dull.css +599 -0
- data/themes/cobalt.css +149 -0
- data/themes/dawn.css +121 -0
- data/themes/eiffel.css +121 -0
- data/themes/espresso_libre.css +109 -0
- data/themes/idle.css +62 -0
- data/themes/iplastic.css +80 -0
- data/themes/lazy.css +73 -0
- data/themes/mac_classic.css +123 -0
- data/themes/magicwb_amiga.css +104 -0
- data/themes/pastels_on_dark.css +188 -0
- data/themes/slush_poppies.css +85 -0
- data/themes/spacecadet.css +51 -0
- data/themes/sunburst.css +180 -0
- data/themes/twilight.css +137 -0
- data/themes/zenburnesque.css +91 -0
- metadata +144 -0
data/kitabu.gemspec
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# WARNING : RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!
|
2
|
+
# RUN : 'rake gem:update_gemspec'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.date = "Fri Aug 01 05:56:29 -0300 2008"
|
6
|
+
s.executables = ["kitabu"]
|
7
|
+
s.authors = ["Nando Vieira"]
|
8
|
+
s.required_rubygems_version = ">= 0"
|
9
|
+
s.version = "0.2.0"
|
10
|
+
s.files = ["Rakefile",
|
11
|
+
"kitabu.gemspec",
|
12
|
+
"History.txt",
|
13
|
+
"License.txt",
|
14
|
+
"README.markdown",
|
15
|
+
"TODO.txt",
|
16
|
+
"app_generators/kitabu",
|
17
|
+
"app_generators/kitabu/kitabu_generator.rb",
|
18
|
+
"app_generators/kitabu/templates",
|
19
|
+
"app_generators/kitabu/templates/config.yml",
|
20
|
+
"app_generators/kitabu/templates/css",
|
21
|
+
"app_generators/kitabu/templates/css/active4d.css",
|
22
|
+
"app_generators/kitabu/templates/css/blackboard.css",
|
23
|
+
"app_generators/kitabu/templates/css/dawn.css",
|
24
|
+
"app_generators/kitabu/templates/css/eiffel.css",
|
25
|
+
"app_generators/kitabu/templates/css/idle.css",
|
26
|
+
"app_generators/kitabu/templates/css/iplastic.css",
|
27
|
+
"app_generators/kitabu/templates/css/lazy.css",
|
28
|
+
"app_generators/kitabu/templates/css/mac_classic.css",
|
29
|
+
"app_generators/kitabu/templates/css/slush_poppies.css",
|
30
|
+
"app_generators/kitabu/templates/css/sunburst.css",
|
31
|
+
"app_generators/kitabu/templates/layouts",
|
32
|
+
"app_generators/kitabu/templates/layouts/boom",
|
33
|
+
"app_generators/kitabu/templates/layouts/boom/layout.css",
|
34
|
+
"app_generators/kitabu/templates/layouts/boom/layout.html",
|
35
|
+
"app_generators/kitabu/templates/Rakefile",
|
36
|
+
"app_generators/kitabu/templates/user.css",
|
37
|
+
"app_generators/kitabu/USAGE",
|
38
|
+
"bin/kitabu",
|
39
|
+
"lib/kitabu",
|
40
|
+
"lib/kitabu/base.rb",
|
41
|
+
"lib/kitabu/blackcloth.rb",
|
42
|
+
"lib/kitabu/redcloth.rb",
|
43
|
+
"lib/kitabu/tasks.rb",
|
44
|
+
"lib/kitabu.rb",
|
45
|
+
"themes/active4d.css",
|
46
|
+
"themes/all_hallows_eve.css",
|
47
|
+
"themes/amy.css",
|
48
|
+
"themes/blackboard.css",
|
49
|
+
"themes/brilliance_black.css",
|
50
|
+
"themes/brilliance_dull.css",
|
51
|
+
"themes/cobalt.css",
|
52
|
+
"themes/dawn.css",
|
53
|
+
"themes/eiffel.css",
|
54
|
+
"themes/espresso_libre.css",
|
55
|
+
"themes/idle.css",
|
56
|
+
"themes/iplastic.css",
|
57
|
+
"themes/lazy.css",
|
58
|
+
"themes/mac_classic.css",
|
59
|
+
"themes/magicwb_amiga.css",
|
60
|
+
"themes/pastels_on_dark.css",
|
61
|
+
"themes/slush_poppies.css",
|
62
|
+
"themes/spacecadet.css",
|
63
|
+
"themes/sunburst.css",
|
64
|
+
"themes/twilight.css",
|
65
|
+
"themes/zenburnesque.css"]
|
66
|
+
s.has_rdoc = false
|
67
|
+
s.requirements = ["Install the Oniguruma RE library and ultraviolet gem to get Syntax Highlighting (only for TextMate users)"]
|
68
|
+
s.email = ["fnando.vieira@gmail.com"]
|
69
|
+
s.name = "kitabu"
|
70
|
+
s.bindir = "bin"
|
71
|
+
s.homepage = "http://github.com/fnando/kitabu"
|
72
|
+
s.summary = "A framework for creating e-books from Markdown/Textile text markup using Ruby."
|
73
|
+
s.description = "A framework for creating e-books from Markdown/Textile text markup using Ruby. Using the Prince PDF generator, you'll be able to get high quality PDFs. Mac users that have Textmate installed can have source code highlighted with his favorite theme."
|
74
|
+
s.add_dependency "rubigen", ">= 0"
|
75
|
+
s.add_dependency "discount", ">= 0"
|
76
|
+
s.add_dependency "hpricot", ">= 0"
|
77
|
+
s.add_dependency "unicode", ">= 0"
|
78
|
+
s.require_paths = ["lib"]
|
79
|
+
end
|
data/lib/kitabu/base.rb
ADDED
@@ -0,0 +1,332 @@
|
|
1
|
+
module Kitabu
|
2
|
+
module Markup
|
3
|
+
def self.content_for(options)
|
4
|
+
source_file = File.join(KITABU_ROOT, 'code', options[:source_file].to_s)
|
5
|
+
code = options[:code]
|
6
|
+
|
7
|
+
if options[:source_file] && File.exists?(source_file)
|
8
|
+
file = File.new(source_file)
|
9
|
+
|
10
|
+
if options[:from_line] && options[:to_line]
|
11
|
+
from_line = options[:from_line].to_i - 1
|
12
|
+
to_line = options[:to_line].to_i
|
13
|
+
offset = to_line - from_line
|
14
|
+
code = file.readlines.slice(from_line, offset).join
|
15
|
+
elsif block_name = options[:block_name]
|
16
|
+
re = %r(# ?begin: ?#{block_name} ?(?:[^\r\n]+)?\r?\n(.*?)\r?\n([^\r\n]+)?# ?end: #{block_name})sim
|
17
|
+
file.read.gsub(re) { |block| code = $1 }
|
18
|
+
else
|
19
|
+
code = file.read
|
20
|
+
code = code.gsub(/</, '<').gsub(/>/, '>').gsub(/&/, '&')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# no code? set to default
|
25
|
+
code ||= options[:code]
|
26
|
+
|
27
|
+
# normalize indentation
|
28
|
+
line = StringIO.new(code).readlines[0]
|
29
|
+
|
30
|
+
if line =~ /^(\t+)/
|
31
|
+
char = "\t"
|
32
|
+
size = $1.length
|
33
|
+
elsif line =~ /^( +)/
|
34
|
+
char = " "
|
35
|
+
size = $1.length
|
36
|
+
end
|
37
|
+
|
38
|
+
code.gsub! %r(^#{char}{#{size}}), "" if size.to_i > 0
|
39
|
+
|
40
|
+
# remove all line stubs
|
41
|
+
code.gsub! %r(^[\t ]*__$), ""
|
42
|
+
|
43
|
+
# return
|
44
|
+
code
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.syntax(code, syntax='plain_text')
|
48
|
+
# get chosen theme
|
49
|
+
theme = Kitabu::Base.config['theme']
|
50
|
+
theme = Kitabu::Base.default_theme unless Kitabu::Base.theme?(theme)
|
51
|
+
|
52
|
+
# get syntax
|
53
|
+
syntax = Kitabu::Base.default_syntax unless Kitabu::Base.syntax?(syntax)
|
54
|
+
|
55
|
+
Uv.parse(code, "xhtml", syntax, false, theme)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module Base
|
60
|
+
DEFAULT_LAYOUT = 'boom'
|
61
|
+
DEFAULT_THEME = 'eiffel'
|
62
|
+
DEFAULT_SYNTAX = 'plain_text'
|
63
|
+
GEM_ROOT = File.expand_path(File.dirname(__FILE__) + "/../../")
|
64
|
+
|
65
|
+
def self.html_path
|
66
|
+
KITABU_ROOT + "/output/#{app_name}.html"
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.pdf_path
|
70
|
+
KITABU_ROOT + "/output/#{app_name}.pdf"
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.template_path
|
74
|
+
KITABU_ROOT + "/templates/layout.html"
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.config_path
|
78
|
+
KITABU_ROOT + "/config.yml"
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.text_dir
|
82
|
+
KITABU_ROOT + "/text"
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.config
|
86
|
+
@config ||= YAML::load_file(config_path)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.parse_layout(contents)
|
90
|
+
template = File.new(template_path).read
|
91
|
+
contents, toc = self.table_of_contents(contents)
|
92
|
+
cfg = config.merge(:contents => contents, :toc => toc)
|
93
|
+
env = OpenStruct.new(cfg)
|
94
|
+
|
95
|
+
ERB.new(template).result env.instance_eval{binding}
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.table_of_contents(contents)
|
99
|
+
return [contents, nil] unless Object.const_defined?('Hpricot') && Object.const_defined?('Unicode')
|
100
|
+
|
101
|
+
doc = Hpricot(contents)
|
102
|
+
counter = {}
|
103
|
+
|
104
|
+
(doc/"h2, h3, h4, h5, h6").each do |node|
|
105
|
+
title = node.inner_text
|
106
|
+
permalink = Kitabu::Base.to_permalink(title)
|
107
|
+
|
108
|
+
# initialize and increment counter
|
109
|
+
counter[permalink] ||= 0
|
110
|
+
counter[permalink] += 1
|
111
|
+
|
112
|
+
# set a incremented permalink if more than one occurrence
|
113
|
+
# is found
|
114
|
+
permalink = "#{permalink}-#{counter[permalink]}" if counter[permalink] > 1
|
115
|
+
|
116
|
+
node.set_attribute(:id, permalink)
|
117
|
+
end
|
118
|
+
|
119
|
+
contents = doc.to_html
|
120
|
+
io = StringIO.new(contents)
|
121
|
+
toc = Toc.new
|
122
|
+
REXML::Document.parse_stream(io, toc)
|
123
|
+
|
124
|
+
[contents, toc.to_s]
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.generate_pdf
|
128
|
+
IO.popen('prince %s -o %s' % [html_path, pdf_path])
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.generate_html
|
132
|
+
# all parsed markdown file holder
|
133
|
+
contents = ""
|
134
|
+
|
135
|
+
# first, get all chapters; then, get all parsed markdown
|
136
|
+
# files from this chapter and group them into a <div class="chapter"> tag
|
137
|
+
Dir.entries(text_dir).sort.each do |dirname|
|
138
|
+
# ignore files and some directories
|
139
|
+
next if %w(. .. .svn .git).include?(dirname) || File.file?(text_dir + "/#{dirname}")
|
140
|
+
|
141
|
+
# gets all parsed markdown files to wrap in a
|
142
|
+
# chapter element
|
143
|
+
chapter = ""
|
144
|
+
|
145
|
+
# merge all markdown and textile files into a single list
|
146
|
+
markup_files = Dir["#{text_dir}/#{dirname}/**/*.markdown"] + Dir["#{text_dir}/#{dirname}/**/*.textile"]
|
147
|
+
|
148
|
+
# no files, so skip it!
|
149
|
+
next if markup_files.empty?
|
150
|
+
|
151
|
+
markup_files.sort.each do |markup_file|
|
152
|
+
# get the file contents
|
153
|
+
markup_contents = File.new(markup_file).read
|
154
|
+
|
155
|
+
# instantiate a markup object
|
156
|
+
begin
|
157
|
+
if markup_file =~ /\.textile$/
|
158
|
+
markup = BlackCloth.new(markup_contents)
|
159
|
+
else
|
160
|
+
markup = Discount.new(markup_contents)
|
161
|
+
end
|
162
|
+
rescue Exception => e
|
163
|
+
puts "Skipping #{markup_file} (#{e.message})"
|
164
|
+
next
|
165
|
+
end
|
166
|
+
|
167
|
+
# convert the markup into html
|
168
|
+
parsed_contents = markup.to_html
|
169
|
+
|
170
|
+
if Object.const_defined?('Uv')
|
171
|
+
if markup.respond_to?(:syntax_blocks)
|
172
|
+
# textile
|
173
|
+
parsed_contents.gsub!(/@syntax:([0-9]+)/m) do |m|
|
174
|
+
syntax, code = markup.syntax_blocks[$1.to_i]
|
175
|
+
Kitabu::Markup.syntax(code, syntax)
|
176
|
+
end
|
177
|
+
else
|
178
|
+
# markdown
|
179
|
+
parsed_contents.gsub! /<pre><code>(.*?)<\/code><\/pre>/m do |block|
|
180
|
+
code = $1.gsub(/</, '<').gsub(/>/, '>').gsub(/&/, '&')
|
181
|
+
code_lines = StringIO.new(code).readlines
|
182
|
+
syntax_settings = code_lines.first
|
183
|
+
|
184
|
+
syntax = 'plain_text'
|
185
|
+
|
186
|
+
if syntax_settings =~ /syntax\(.*?\)\./
|
187
|
+
code = code_lines.slice(1, code_lines.size).join
|
188
|
+
|
189
|
+
# syntax
|
190
|
+
m, syntax = *syntax_settings.match(/syntax\(([^ #]+).*?\)./)
|
191
|
+
|
192
|
+
# file name
|
193
|
+
m, source_file = *syntax_settings.match(/syntax\(.*?\)\. +(.*?)$/)
|
194
|
+
|
195
|
+
# get line interval
|
196
|
+
m, from_line, to_line = *syntax_settings.match(/syntax\(.*? ([0-9]+),([0-9]+)\)/)
|
197
|
+
|
198
|
+
# get block name
|
199
|
+
m, block_name = *syntax_settings.match(/syntax\(.*?#([0-9a-z_]+)\)/)
|
200
|
+
|
201
|
+
code = Kitabu::Markup.content_for({
|
202
|
+
:code => code,
|
203
|
+
:from_line => from_line,
|
204
|
+
:to_line => to_line,
|
205
|
+
:block_name => block_name,
|
206
|
+
:source_file => source_file
|
207
|
+
})
|
208
|
+
|
209
|
+
Kitabu::Markup.syntax(code, syntax)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
chapter << (parsed_contents + "\n\n")
|
216
|
+
end
|
217
|
+
|
218
|
+
contents << '<div class="chapter">%s</div>' % chapter
|
219
|
+
end
|
220
|
+
|
221
|
+
# save html file
|
222
|
+
File.open(html_path, 'w+') do |f|
|
223
|
+
f << Kitabu::Base.parse_layout(contents)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def self.app_name
|
228
|
+
ENV['KITABU_NAME'] || 'kitabu'
|
229
|
+
end
|
230
|
+
|
231
|
+
def self.theme?(theme_name)
|
232
|
+
themes.include?(theme_name)
|
233
|
+
end
|
234
|
+
|
235
|
+
def self.syntax?(syntax_name)
|
236
|
+
syntaxes.include?(syntax_name)
|
237
|
+
end
|
238
|
+
|
239
|
+
def self.default_theme
|
240
|
+
DEFAULT_THEME
|
241
|
+
end
|
242
|
+
|
243
|
+
def self.default_syntax
|
244
|
+
DEFAULT_SYNTAX
|
245
|
+
end
|
246
|
+
|
247
|
+
def self.default_layout
|
248
|
+
DEFAULT_LAYOUT
|
249
|
+
end
|
250
|
+
|
251
|
+
def self.syntaxes
|
252
|
+
Uv.syntaxes
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.layouts
|
256
|
+
@layouts ||= begin
|
257
|
+
dir = File.join(GEM_ROOT, "app_generators/kitabu/templates/layouts/")
|
258
|
+
Dir.entries(dir).reject{|p| p =~ /^\.+$/ }.sort
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def self.themes
|
263
|
+
@themes ||= begin
|
264
|
+
filter = File.join(GEM_ROOT, "app_generators/kitabu/templates/css/*.css")
|
265
|
+
Dir[filter].collect{|path| File.basename(path).gsub(/\.css$/, '') }.sort
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def self.to_permalink(str)
|
270
|
+
str = Unicode.normalize_KD(str).gsub(/[^\x00-\x7F]/n,'')
|
271
|
+
str = str.gsub(/[^-_\s\w]/, ' ').downcase.squeeze(' ').tr(' ', '-')
|
272
|
+
str = str.gsub(/-+/, '-').gsub(/^-+/, '').gsub(/-+$/, '')
|
273
|
+
str
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
class Toc
|
278
|
+
include REXML::StreamListener
|
279
|
+
|
280
|
+
def initialize
|
281
|
+
@toc = ""
|
282
|
+
@previous_level = 0
|
283
|
+
@tag = nil
|
284
|
+
@stack = []
|
285
|
+
end
|
286
|
+
|
287
|
+
def header?(tag=nil)
|
288
|
+
tag ||= @tag_name
|
289
|
+
return false unless tag.to_s =~ /h[2-6]/
|
290
|
+
@tag_name = tag
|
291
|
+
return true
|
292
|
+
end
|
293
|
+
|
294
|
+
def in_header?
|
295
|
+
@in_header
|
296
|
+
end
|
297
|
+
|
298
|
+
def tag_start(name, attrs)
|
299
|
+
@tag_name = name
|
300
|
+
return unless header?(name)
|
301
|
+
@in_header = true
|
302
|
+
@current_level = name.gsub!(/[^2-6]/, '').to_i
|
303
|
+
@stack << @current_level
|
304
|
+
@id = attrs["id"]
|
305
|
+
|
306
|
+
@toc << %(<ul class="level#{@current_level}">) if @current_level > @previous_level
|
307
|
+
@toc << %(</li></ul>) * (@previous_level - @current_level) if @current_level < @previous_level
|
308
|
+
@toc << %(</li>) if @current_level <= @previous_level
|
309
|
+
@toc << %(<li>)
|
310
|
+
end
|
311
|
+
|
312
|
+
def tag_end(name)
|
313
|
+
return unless header?(name)
|
314
|
+
@in_header = false
|
315
|
+
@previous_level = @current_level
|
316
|
+
end
|
317
|
+
|
318
|
+
def text(str)
|
319
|
+
return unless in_header?
|
320
|
+
@toc << %(<a href="##{@id}"><span>#{str}</span></a>)
|
321
|
+
end
|
322
|
+
|
323
|
+
def method_missing(*args)
|
324
|
+
end
|
325
|
+
|
326
|
+
def to_s
|
327
|
+
@toc + (%(</li></ul>) * (@stack.last - 1))
|
328
|
+
rescue
|
329
|
+
""
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
class BlackCloth < RedCloth
|
2
|
+
@@syntax_blocks = []
|
3
|
+
|
4
|
+
FN_RE = /
|
5
|
+
(\s+)? # getting spaces
|
6
|
+
%\{ # opening
|
7
|
+
(.*?) # footnote
|
8
|
+
\}# # closing
|
9
|
+
/x
|
10
|
+
|
11
|
+
# Usage: Writing some text with a footnote %{this is a footnote}
|
12
|
+
def inline_textile_fn(text)
|
13
|
+
text.gsub!( FN_RE ) do |m|
|
14
|
+
%(<span class="footnote">#{$2}</span>)
|
15
|
+
end
|
16
|
+
|
17
|
+
text
|
18
|
+
end
|
19
|
+
|
20
|
+
FN_URL_LINK = /
|
21
|
+
<
|
22
|
+
((?:https?|ftp):\/\/.*?)
|
23
|
+
>
|
24
|
+
/x
|
25
|
+
|
26
|
+
# Usage: <http://google.com>
|
27
|
+
def inline_textile_url_link(text)
|
28
|
+
text.gsub!( FN_URL_LINK ) do |m|
|
29
|
+
%(<a href="#{$1}">#{$1}</a>)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Usage:
|
34
|
+
# syntax(ruby). Some code
|
35
|
+
#
|
36
|
+
# getting from line 100 to 200 of file.rb
|
37
|
+
# syntax(ruby 100,200). file.rb
|
38
|
+
#
|
39
|
+
# getting block 'sample' from file.rb
|
40
|
+
# syntax(ruby#sample). file.rb
|
41
|
+
#
|
42
|
+
# to create a block:
|
43
|
+
# #begin: sample
|
44
|
+
# some code
|
45
|
+
# #end: sample
|
46
|
+
def textile_syntax(tag, attrs, cite, content)
|
47
|
+
# get syntax
|
48
|
+
m, syntax = *attrs.match(/class="(.*?)([# ].*?)?"/)
|
49
|
+
syntax = 'plain_text' if tag == "pre"
|
50
|
+
|
51
|
+
# set source
|
52
|
+
source_file = content
|
53
|
+
|
54
|
+
# get block name
|
55
|
+
m, block_name = *attrs.match(/id="(.*?)"/ms)
|
56
|
+
|
57
|
+
# get line interval
|
58
|
+
m, from_line, to_line = *attrs.match(/class=".*? ([0-9]+),([0-9]+)"/)
|
59
|
+
|
60
|
+
# code = Kitabu::Markup.syntax({
|
61
|
+
# :code => content,
|
62
|
+
# :syntax => syntax,
|
63
|
+
# :source_file => source_file,
|
64
|
+
# :block_name => block_name,
|
65
|
+
# :from_line => from_line,
|
66
|
+
# :to_line => to_line
|
67
|
+
# })
|
68
|
+
|
69
|
+
content = Kitabu::Markup.content_for({
|
70
|
+
:code => content,
|
71
|
+
:syntax => syntax,
|
72
|
+
:source_file => source_file,
|
73
|
+
:block_name => block_name,
|
74
|
+
:from_line => from_line,
|
75
|
+
:to_line => to_line
|
76
|
+
})
|
77
|
+
@@syntax_blocks << [syntax, content]
|
78
|
+
position = @@syntax_blocks.size - 1
|
79
|
+
%(@syntax:#{position})
|
80
|
+
end
|
81
|
+
|
82
|
+
def syntax_blocks
|
83
|
+
@@syntax_blocks
|
84
|
+
end
|
85
|
+
|
86
|
+
# Usage: pre. Some code
|
87
|
+
def textile_pre(*args)
|
88
|
+
# Should I add the default theme as a class?
|
89
|
+
send(:textile_syntax, *args)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Usage: note. Some text
|
93
|
+
def textile_note(tag, attrs, cite, content)
|
94
|
+
%(<p class="note">#{content}</p>)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Usage: figure(This is the caption). some_image.jpg
|
98
|
+
def textile_figure(tag, attrs, cite, content)
|
99
|
+
m, title = *attrs.match(/class="(.*?)"/)
|
100
|
+
width, height = image_size(content)
|
101
|
+
%(<p class="figure"><img style="width: #{width}px; height: #{height}px" src="../images/#{content}" alt="#{title}" /><br/><span class="caption">#{title}</span></p>)
|
102
|
+
end
|
103
|
+
|
104
|
+
def image_size(img)
|
105
|
+
io = IO.popen("php -r '$info = getimagesize(\"images/#{img}\");echo $info[0].'x'.$info[1];'")
|
106
|
+
io.read.split('x').map{|n| n.to_i}
|
107
|
+
end
|
108
|
+
|
109
|
+
# overriding inline method
|
110
|
+
def inline( text )
|
111
|
+
@rules += [:inline_textile_fn, :inline_textile_url_link]
|
112
|
+
super
|
113
|
+
end
|
114
|
+
|
115
|
+
# overriding to_html method
|
116
|
+
def to_html( *rules )
|
117
|
+
rules = DEFAULT_RULES if rules.empty?
|
118
|
+
# make our working copy
|
119
|
+
text = self.dup
|
120
|
+
|
121
|
+
@urlrefs = {}
|
122
|
+
@shelf = []
|
123
|
+
textile_rules = [:refs_textile, :block_textile_table, :block_textile_lists,
|
124
|
+
:block_textile_prefix, :inline_textile_image, :inline_textile_link,
|
125
|
+
:inline_textile_code, :inline_textile_span, :glyphs_textile]
|
126
|
+
markdown_rules = [:refs_markdown, :block_markdown_setext, :block_markdown_atx, :block_markdown_rule,
|
127
|
+
:block_markdown_bq, :block_markdown_lists,
|
128
|
+
:inline_markdown_reflink, :inline_markdown_link]
|
129
|
+
@rules = rules.collect do |rule|
|
130
|
+
case rule
|
131
|
+
when :markdown
|
132
|
+
markdown_rules
|
133
|
+
when :textile
|
134
|
+
textile_rules
|
135
|
+
else
|
136
|
+
rule
|
137
|
+
end
|
138
|
+
end.flatten
|
139
|
+
|
140
|
+
# standard clean up
|
141
|
+
incoming_entities text
|
142
|
+
clean_white_space text
|
143
|
+
|
144
|
+
# start processor
|
145
|
+
@pre_list = []
|
146
|
+
rip_offtags text
|
147
|
+
no_textile text
|
148
|
+
hard_break text
|
149
|
+
unless @lite_mode
|
150
|
+
refs text
|
151
|
+
blocks text
|
152
|
+
end
|
153
|
+
inline text
|
154
|
+
smooth_offtags text
|
155
|
+
|
156
|
+
retrieve text
|
157
|
+
|
158
|
+
text.gsub!( /<\/?notextile>/, '' )
|
159
|
+
text.gsub!( /x%x%/, '&' )
|
160
|
+
clean_html text if filter_html
|
161
|
+
text.strip!
|
162
|
+
text
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|