pbsimply 2.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.
- checksums.yaml +7 -0
- data/bin/pbsimply +26 -0
- data/bin/pbsimply-testserver +15 -0
- data/lib/pbsimply.rb +1071 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d364901d22b774c9f9aecabde031611aec62d3d3edc49e05b47a34abb83f68c8
|
4
|
+
data.tar.gz: 779d8544a9e359d4ec94562c92dd898b1995b4e66d55796d3e4659b161e4ec7b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 801b0b10d12598699b8cee2c91bff275f7feed4da3433f9499b633742b65d5a589bd6eee80280403f2c08b8e209014eb3b20a9ebf1905c7dfcdb58c452c044f0
|
7
|
+
data.tar.gz: 5f181d1a737bebcc3d28981d8a37ca43e925aab5b08678db20e48272024ab25aaded146e06ac1e5e6026c96dd4bc629a94d67644853dc8f44d0cc77342d01b50
|
data/bin/pbsimply
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'pbsimply'
|
3
|
+
|
4
|
+
config = PBSimply.load_config
|
5
|
+
|
6
|
+
pbs_class = case config["pbsimply_processor"]
|
7
|
+
when "redcarpet"
|
8
|
+
PBSimply::Processor::PbsRedCarpet
|
9
|
+
when "kramdown"
|
10
|
+
PBSimply::Processor::PbsKramdown
|
11
|
+
when "cmark"
|
12
|
+
PBSimply::Processor::PbsCommonMark
|
13
|
+
when "rdoc_markdown"
|
14
|
+
PBSimply::Processor::PbsRMakrdown
|
15
|
+
when "rdoc"
|
16
|
+
PBSimply::Processor::PbsRDoc
|
17
|
+
else
|
18
|
+
PBSimply::Processor::Pandoc
|
19
|
+
end
|
20
|
+
|
21
|
+
# Alias for compatibility.
|
22
|
+
PureBuilder = pbs_class
|
23
|
+
|
24
|
+
pbs = pbs_class.new(config)
|
25
|
+
pbs.treat_cmdline
|
26
|
+
pbs.main
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# -*- mode: ruby; coding: UTF-8 -*-
|
3
|
+
|
4
|
+
require 'webrick'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
File.open(".pbsimply.yaml") do |f|
|
8
|
+
@config = YAML.load(f)
|
9
|
+
end
|
10
|
+
|
11
|
+
srv = WEBrick::HTTPServer.new({ :DocumentRoot => @config["outdir"],
|
12
|
+
:BindAddress => '127.0.0.1',
|
13
|
+
:Port => (@config["testserver_port"] || 8000 )})
|
14
|
+
trap("INT"){ srv.shutdown }
|
15
|
+
srv.start
|
data/lib/pbsimply.rb
ADDED
@@ -0,0 +1,1071 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
require 'yaml'
|
3
|
+
require 'erb'
|
4
|
+
require 'date'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
class PBSimply
|
9
|
+
# Use Oj as JSON library for frontmatter passing if possible.
|
10
|
+
begin
|
11
|
+
require 'oj'
|
12
|
+
JSON_LIB = Oj
|
13
|
+
rescue LoadError
|
14
|
+
require 'json'
|
15
|
+
JSON_LIB = JSON
|
16
|
+
end
|
17
|
+
|
18
|
+
# ACCS namespace.
|
19
|
+
module ACCS
|
20
|
+
DEFINITIONS = {}
|
21
|
+
|
22
|
+
# Built-in Accs index eRuby string.
|
23
|
+
INDEX = <<'EOF'
|
24
|
+
<%= YAML.dump(
|
25
|
+
{
|
26
|
+
"title" => @index["title"],
|
27
|
+
"date" => @index["date"],
|
28
|
+
"author" => @index["author"]
|
29
|
+
}
|
30
|
+
) %>
|
31
|
+
---
|
32
|
+
|
33
|
+
<%
|
34
|
+
articles = Hash.new {|h,k| h[k] = Array.new }
|
35
|
+
|
36
|
+
if @config["accs_across_category"]
|
37
|
+
@indexes.each {|filename, index| articles["default"].push index }
|
38
|
+
else
|
39
|
+
@indexes.each {|filename, index| articles[(index["category"] || "default")].push index }
|
40
|
+
end
|
41
|
+
|
42
|
+
%>
|
43
|
+
|
44
|
+
% articles.keys.sort.each do |catname|
|
45
|
+
% cat = articles[catname]
|
46
|
+
|
47
|
+
% unless articles.length == 1
|
48
|
+
# <%= catname %>
|
49
|
+
% end
|
50
|
+
|
51
|
+
<%
|
52
|
+
sort_method = case @config["accs_sort_by"]
|
53
|
+
when "title"
|
54
|
+
lambda {|i| [i["title"].to_s, i["date"]] }
|
55
|
+
when "name"
|
56
|
+
lambda {|i| [i["_filename"].to_s, i["title"].to_s, i["date"]] }
|
57
|
+
when "serial"
|
58
|
+
lambda {|i| [i["serial"].to_s, i["date"], i["_filename"].to_s] }
|
59
|
+
else
|
60
|
+
lambda {|i| [i["date"], i["title"].to_s, i["_last_update"].to_i] }
|
61
|
+
end
|
62
|
+
|
63
|
+
list = if @config["accs_order"] == "desc"
|
64
|
+
cat.sort_by(&sort_method).reverse
|
65
|
+
else
|
66
|
+
cat.sort_by(&sort_method)
|
67
|
+
end
|
68
|
+
|
69
|
+
list.each do |i|
|
70
|
+
%>* [<%= i["title"] %>](<%= i["page_url"] %>)
|
71
|
+
<% end %>
|
72
|
+
|
73
|
+
% end
|
74
|
+
EOF
|
75
|
+
end
|
76
|
+
|
77
|
+
# Abstruct super class.
|
78
|
+
class DocDB
|
79
|
+
def dump(object)
|
80
|
+
File.open(File.join(@dir, ".indexes.#{@ext}"), "w") do |f|
|
81
|
+
f.write @store_class.dump(object)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def load
|
86
|
+
File.open(File.join(@dir, ".indexes.#{@ext}"), "r") do |f|
|
87
|
+
next @store_class.load(f)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def exist?
|
92
|
+
File.exist?(File.join(@dir, ".indexes.#{@ext}"))
|
93
|
+
end
|
94
|
+
|
95
|
+
def path
|
96
|
+
File.join(@dir, ".indexes.#{@ext}")
|
97
|
+
end
|
98
|
+
|
99
|
+
def cmp_obj(frontmatter)
|
100
|
+
@store_class.load(@store_class.dump(frontmatter))
|
101
|
+
end
|
102
|
+
|
103
|
+
class Marshal < DocDB
|
104
|
+
def initialize(dir)
|
105
|
+
@dir = dir
|
106
|
+
@store_class = ::Marshal
|
107
|
+
@ext = "rbm"
|
108
|
+
end
|
109
|
+
|
110
|
+
def cmp_obj(frontmatter)
|
111
|
+
frontmatter.dup
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class JSON < DocDB
|
116
|
+
def initialize(dir)
|
117
|
+
@dir = dir
|
118
|
+
@store_class = ::JSON
|
119
|
+
@ext = "json"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class Oj < DocDB::JSON
|
124
|
+
def initialize(dir)
|
125
|
+
require 'oj'
|
126
|
+
@dir = dir
|
127
|
+
@ext = "json"
|
128
|
+
@store_class = ::Oj
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class YAML < DocDB
|
133
|
+
def initialize(dir)
|
134
|
+
@dir = dir
|
135
|
+
@store_class = ::YAML
|
136
|
+
@ext = "yaml"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
POST_PROCESSORS = {
|
143
|
+
".rb" => "ruby",
|
144
|
+
".pl" => "perl",
|
145
|
+
".py" => "python",
|
146
|
+
".lua" => "lua",
|
147
|
+
".bash" => "bash",
|
148
|
+
".zsh" => "zsh",
|
149
|
+
".php" => "php",
|
150
|
+
".sed" => ["sed", ->(script, target) { ["-f", script, target] } ]
|
151
|
+
}
|
152
|
+
|
153
|
+
###############################################
|
154
|
+
# SETUP FUNCTIONS #
|
155
|
+
###############################################
|
156
|
+
|
157
|
+
# Load config file.
|
158
|
+
def self.load_config
|
159
|
+
config = nil
|
160
|
+
begin
|
161
|
+
File.open(".pbsimply.yaml") do |f|
|
162
|
+
config = YAML.load(f)
|
163
|
+
end
|
164
|
+
rescue
|
165
|
+
abort "Failed to load config file (./.pbsimply.yaml)"
|
166
|
+
end
|
167
|
+
|
168
|
+
# Required values
|
169
|
+
config["outdir"] or abort "Output directory is not set (outdir)."
|
170
|
+
config["template"] ||= "./template.html"
|
171
|
+
|
172
|
+
config
|
173
|
+
end
|
174
|
+
|
175
|
+
# initialize phase,
|
176
|
+
def setup_config(dir)
|
177
|
+
ENV["pbsimply_outdir"] = @config["outdir"]
|
178
|
+
@docobject[:config] = @config
|
179
|
+
|
180
|
+
if @singlemode
|
181
|
+
outdir = [@config["outdir"], @dir.sub(%r:/[^/]*$:, "")].join("/")
|
182
|
+
else
|
183
|
+
outdir = [@config["outdir"], @dir].join("/")
|
184
|
+
end
|
185
|
+
|
186
|
+
p dir
|
187
|
+
|
188
|
+
# Format for Indexes database
|
189
|
+
@db = case @config["dbstyle"]
|
190
|
+
when "yaml"
|
191
|
+
DocDB::YAML.new(dir)
|
192
|
+
when "json"
|
193
|
+
DocDB::JSON.new(dir)
|
194
|
+
when "oj"
|
195
|
+
DocDB::Oj.new(dir)
|
196
|
+
else
|
197
|
+
DocDB::Marshal.new(dir)
|
198
|
+
end
|
199
|
+
|
200
|
+
@frontmatter.merge!(@config["default_meta"]) if @config["default_meta"]
|
201
|
+
|
202
|
+
# Merge ACCS Frontmatter
|
203
|
+
if @accs_processing && @config["alt_frontmatter"]
|
204
|
+
@frontmatter.merge!(@config["alt_frontmatter"])
|
205
|
+
end
|
206
|
+
|
207
|
+
unless File.exist? outdir
|
208
|
+
STDERR.puts "destination directory is not exist. creating (only one step.)"
|
209
|
+
FileUtils.mkdir_p outdir
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def initialize(config)
|
214
|
+
@config = config
|
215
|
+
@docobject = {}
|
216
|
+
@this_time_processed = []
|
217
|
+
|
218
|
+
# --metadata-file
|
219
|
+
@frontmatter = {}
|
220
|
+
|
221
|
+
@refresh = false # Force generate all documents.
|
222
|
+
@skip_index = false # Don't register to index.
|
223
|
+
@outfile = nil # Fixed output filename
|
224
|
+
@add_meta = nil
|
225
|
+
@accs = nil
|
226
|
+
@accs_index = {}
|
227
|
+
@now = Time.now
|
228
|
+
end
|
229
|
+
|
230
|
+
# Process command-line
|
231
|
+
def treat_cmdline(dir=nil)
|
232
|
+
# Options definition.
|
233
|
+
opts = OptionParser.new
|
234
|
+
opts.on("-f", "--force-refresh") { @refresh = true }
|
235
|
+
opts.on("-X", "--ignore-ext") { @ignore_ext = true }
|
236
|
+
opts.on("-I", "--skip-index") { @skip_index = true }
|
237
|
+
opts.on("-o FILE", "--output") {|v| @outfile = v }
|
238
|
+
opts.on("-m FILE", "--additional-metafile") {|v| @add_meta = YAML.load(File.read(v))}
|
239
|
+
opts.parse!(ARGV)
|
240
|
+
|
241
|
+
if File.exist?(".pbsimply-bless.rb")
|
242
|
+
require "./.pbsimply-bless.rb"
|
243
|
+
end
|
244
|
+
|
245
|
+
# Set target directory.
|
246
|
+
@dir = ARGV.shift unless dir
|
247
|
+
@dir ||= "."
|
248
|
+
ENV["pbsimply_subdir"] = @dir
|
249
|
+
end
|
250
|
+
|
251
|
+
# Load document index database (.indexes.${ext}).
|
252
|
+
def load_index
|
253
|
+
if @db.exist?
|
254
|
+
@indexes = @db.load
|
255
|
+
else
|
256
|
+
@indexes = Hash.new
|
257
|
+
end
|
258
|
+
@docobject[:indexes] = @indexes
|
259
|
+
end
|
260
|
+
|
261
|
+
def target_file_extensions
|
262
|
+
[".md"]
|
263
|
+
end
|
264
|
+
|
265
|
+
# Accessor reader.
|
266
|
+
def doc
|
267
|
+
@docobject
|
268
|
+
end
|
269
|
+
|
270
|
+
attr :indexes
|
271
|
+
|
272
|
+
|
273
|
+
###############################################
|
274
|
+
# PROCESSING FUNCTIONS #
|
275
|
+
###############################################
|
276
|
+
|
277
|
+
# Directory mode's main function.
|
278
|
+
# Read Frontmatters from all documents and proc each documents.
|
279
|
+
def proc_dir
|
280
|
+
draft_articles = []
|
281
|
+
target_docs = []
|
282
|
+
@indexes_orig = {}
|
283
|
+
STDERR.puts "in #{@dir}..."
|
284
|
+
|
285
|
+
STDERR.puts "Checking Frontmatter..."
|
286
|
+
Dir.foreach(@dir) do |filename|
|
287
|
+
next if filename == "." || filename == ".."
|
288
|
+
if filename =~ /^\./ || filename =~ /^draft-/
|
289
|
+
draft_articles.push filename.sub(/^(?:\.|draft-)/, "")
|
290
|
+
next
|
291
|
+
end
|
292
|
+
next unless File.file?([@dir, filename].join("/"))
|
293
|
+
|
294
|
+
if !@ignore_ext and not target_file_extensions.include? File.extname filename
|
295
|
+
next
|
296
|
+
end
|
297
|
+
|
298
|
+
STDERR.puts "Checking frontmatter in #{filename}"
|
299
|
+
frontmatter, pos = read_frontmatter(@dir, filename)
|
300
|
+
frontmatter = @frontmatter.merge frontmatter
|
301
|
+
frontmatter.merge!(@add_meta) if @add_meta
|
302
|
+
|
303
|
+
if frontmatter["draft"]
|
304
|
+
@indexes.delete(filename) if @indexes[filename]
|
305
|
+
draft_articles.push filename
|
306
|
+
next
|
307
|
+
end
|
308
|
+
|
309
|
+
@indexes_orig[filename] = @indexes[filename]
|
310
|
+
@indexes[filename] = frontmatter
|
311
|
+
|
312
|
+
# Push to target documents without checking modification.
|
313
|
+
target_docs.push([filename, frontmatter, pos])
|
314
|
+
end
|
315
|
+
|
316
|
+
# Delete turn to draft article.
|
317
|
+
draft_articles.each do |df|
|
318
|
+
STDERR.puts "#{df} was turn to draft. deleting..."
|
319
|
+
[df, (df + ".html"), File.basename(df, ".*"), (File.basename(df, ".*") + ".html")].each do |tfn|
|
320
|
+
tfp = File.join(@config["outdir"], @dir, tfn)
|
321
|
+
File.delete tfp if File.file?(tfp)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Save index.
|
326
|
+
@db.dump(@indexes) unless @skip_index
|
327
|
+
|
328
|
+
STDERR.puts "Blessing..."
|
329
|
+
|
330
|
+
# Modify frontmatter `BLESSING`
|
331
|
+
target_docs.each do |filename, frontmatter, pos|
|
332
|
+
if @config["bless_style"] == "cmd"
|
333
|
+
bless_cmd(frontmatter)
|
334
|
+
else
|
335
|
+
bless_ruby(frontmatter)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
STDERR.puts "Checking modification..."
|
340
|
+
|
341
|
+
target_docs.delete_if {|filename, frontmatter, pos| !check_modify([@dir, filename], frontmatter)}
|
342
|
+
|
343
|
+
STDERR.puts "Okay, Now ready. Process documents..."
|
344
|
+
|
345
|
+
# Proccess documents
|
346
|
+
target_docs.each do |filename, frontmatter, pos|
|
347
|
+
ext = File.extname filename
|
348
|
+
@index = frontmatter
|
349
|
+
File.open(File.join(@dir, filename)) do |f|
|
350
|
+
f.seek(pos)
|
351
|
+
File.open(".current_document#{ext}", "w") {|fo| fo.write f.read}
|
352
|
+
end
|
353
|
+
|
354
|
+
STDERR.puts "Processing #{filename}"
|
355
|
+
generate(@dir, filename, frontmatter)
|
356
|
+
end
|
357
|
+
|
358
|
+
@db.dump(@indexes) unless @skip_index
|
359
|
+
|
360
|
+
post_plugins
|
361
|
+
|
362
|
+
# ACCS processing
|
363
|
+
if @accs && !target_docs.empty?
|
364
|
+
process_accs
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
# Run PureBuilder Simply.
|
369
|
+
def main
|
370
|
+
# If target file is regular file, run as single mode.
|
371
|
+
@singlemode = true if File.file?(@dir)
|
372
|
+
|
373
|
+
# Check single file mode.
|
374
|
+
if @singlemode
|
375
|
+
# Single file mode
|
376
|
+
if @dir =~ %r:(.*)/([^/]+):
|
377
|
+
dir = $1
|
378
|
+
filename = $2
|
379
|
+
else
|
380
|
+
dir = "."
|
381
|
+
filename = @dir
|
382
|
+
end
|
383
|
+
@dir = dir
|
384
|
+
setup_config(dir)
|
385
|
+
|
386
|
+
load_index
|
387
|
+
|
388
|
+
frontmatter, pos = read_frontmatter(dir, filename)
|
389
|
+
frontmatter = @frontmatter.merge frontmatter
|
390
|
+
@index = frontmatter
|
391
|
+
|
392
|
+
ext = File.extname filename
|
393
|
+
File.open(File.join(dir, filename)) do |f|
|
394
|
+
f.seek(pos)
|
395
|
+
File.open(".current_document#{ext}", "w") {|fo| fo.write f.read}
|
396
|
+
end
|
397
|
+
|
398
|
+
generate(dir, filename, frontmatter)
|
399
|
+
|
400
|
+
post_plugins(frontmatter)
|
401
|
+
|
402
|
+
else
|
403
|
+
# Normal (directory) mode.
|
404
|
+
setup_config(@dir)
|
405
|
+
load_index
|
406
|
+
|
407
|
+
@accs = true if File.exist?(File.join(@dir, ".accs.yaml"))
|
408
|
+
|
409
|
+
# Check existing in indexes.
|
410
|
+
@indexes.delete_if {|k,v| ! File.exist?([@dir, k].join("/")) }
|
411
|
+
|
412
|
+
proc_dir
|
413
|
+
end
|
414
|
+
ensure
|
415
|
+
# Clean up temporary files.
|
416
|
+
Dir.children(".").each do |fn|
|
417
|
+
if fn[0, 22] == ".pbsimply-defaultfiles.yaml" or
|
418
|
+
fn[0, 21] == ".pbsimply-frontmatter" or
|
419
|
+
fn[0, 17] == ".current_document"
|
420
|
+
File.delete fn
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
def pre_plugins(procdoc, frontmatter)
|
426
|
+
if File.directory?(".pre_generate")
|
427
|
+
STDERR.puts("Processing with pre plugins")
|
428
|
+
script_file = File.join(".pre_generate", script_file)
|
429
|
+
Dir.entries(".pre_generate").sort.each do |script_file|
|
430
|
+
next if script_file =~ /^\./
|
431
|
+
STDERR.puts "Running script: #{File.basename script_file}"
|
432
|
+
pre_script_result = nil
|
433
|
+
script_cmdline = case
|
434
|
+
when File.executable?(script_file)
|
435
|
+
[script_file, procdoc]
|
436
|
+
when POST_PROCESSORS[File.extname(script_file)]
|
437
|
+
[POST_PROCESSORS[File.extname(script_file)], script_file, procdoc]
|
438
|
+
else
|
439
|
+
["perl", script_file, procdoc]
|
440
|
+
end
|
441
|
+
IO.popen({"pbsimply_doc_frontmatter" => YAML.dump(frontmatter)}, script_cmdline) do |io|
|
442
|
+
pre_script_result = io.read
|
443
|
+
end
|
444
|
+
File.open(procdoc, "w") {|f| f.write pre_script_result}
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def post_plugins(frontmatter=nil)
|
450
|
+
if File.directory?(".post_generate")
|
451
|
+
|
452
|
+
STDERR.puts("Processing with post plugins")
|
453
|
+
|
454
|
+
@this_time_processed.each do |v|
|
455
|
+
STDERR.puts "Processing #{v[:dest]} (from #{v[:source]})"
|
456
|
+
procdoc = v[:dest]
|
457
|
+
frontmatter ||= @indexes[File.basename v[:source]]
|
458
|
+
File.open(".pbsimply-frontmatter.json", "w") {|f| f.write JSON_LIB.dump(frontmatter)}
|
459
|
+
Dir.entries(".post_generate").sort.each do |script_file|
|
460
|
+
next if script_file =~ /^\./
|
461
|
+
STDERR.puts "Running script: #{script_file}"
|
462
|
+
script_file = File.join(".post_generate", script_file)
|
463
|
+
post_script_result = nil
|
464
|
+
script_cmdline = case
|
465
|
+
when File.executable?(script_file)
|
466
|
+
[script_file, procdoc]
|
467
|
+
when POST_PROCESSORS[File.extname(script_file)]
|
468
|
+
[POST_PROCESSORS[File.extname(script_file)], script_file, procdoc]
|
469
|
+
else
|
470
|
+
["perl", script_file, procdoc]
|
471
|
+
end
|
472
|
+
IO.popen({"pbsimply_frontmatter" => ".pbsimply-frontmatter.json", "pbsimply_indexes" => @db.path}, script_cmdline) do |io|
|
473
|
+
post_script_result = io.read
|
474
|
+
end
|
475
|
+
|
476
|
+
File.open(procdoc, "w") {|f| f.write post_script_result}
|
477
|
+
end
|
478
|
+
end
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
def generate(dir, filename, frontmatter)
|
483
|
+
print_fileproc_msg(filename) # at sub-class
|
484
|
+
|
485
|
+
# Preparing and pre script.
|
486
|
+
orig_filepath = [dir, filename].join("/")
|
487
|
+
ext = File.extname(filename)
|
488
|
+
procdoc = sprintf(".current_document%s", ext)
|
489
|
+
pre_plugins(procdoc, frontmatter)
|
490
|
+
|
491
|
+
doc = process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc) # at sub-class
|
492
|
+
|
493
|
+
##### Post eRuby
|
494
|
+
if @config["post_eruby"]
|
495
|
+
STDERR.puts "Porcessing with eRuby."
|
496
|
+
doc = ERB.new(doc, nil, "%<>").result(binding)
|
497
|
+
end
|
498
|
+
|
499
|
+
# Write out
|
500
|
+
outext = frontmatter["force_ext"] || ".html"
|
501
|
+
outpath = case
|
502
|
+
when @outfile
|
503
|
+
@outfile
|
504
|
+
when @accs_processing
|
505
|
+
File.join(@config["outdir"], @dir, "index") + outext
|
506
|
+
else
|
507
|
+
File.join(@config["outdir"], @dir, File.basename(filename, ".*")) + outext
|
508
|
+
end
|
509
|
+
|
510
|
+
File.open(outpath, "w") do |f|
|
511
|
+
f.write(doc)
|
512
|
+
end
|
513
|
+
|
514
|
+
# Mark processed
|
515
|
+
@this_time_processed.push({source: orig_filepath, dest: outpath})
|
516
|
+
end
|
517
|
+
|
518
|
+
# letsaccs
|
519
|
+
#
|
520
|
+
# This method called on the assumption that processed all documents and run as directory mode.
|
521
|
+
def process_accs
|
522
|
+
STDERR.puts "Processing ACCS index..."
|
523
|
+
if File.exist?(File.join(@dir, ".accsindex.erb"))
|
524
|
+
erbtemplate = File.read(File.join(@dir, ".accsindex.erb"))
|
525
|
+
elsif File.exist?(".accsindex.erb")
|
526
|
+
erbtemplate = File.read(".accsindex.erb")
|
527
|
+
else
|
528
|
+
erbtemplate = ACCS::INDEX
|
529
|
+
end
|
530
|
+
|
531
|
+
# Get infomation
|
532
|
+
@accs_index = YAML.load(File.read([@dir, ".accs.yaml"].join("/")))
|
533
|
+
|
534
|
+
@accs_index["title"] ||= (@config["accs_index_title"] || "Index")
|
535
|
+
@accs_index["date"] ||= Time.now.strftime("%Y-%m-%d")
|
536
|
+
@accs_index["pagetype"] = "accs_index"
|
537
|
+
|
538
|
+
@index = @frontmatter.merge @accs_index
|
539
|
+
|
540
|
+
doc = ERB.new(erbtemplate, trim_mode: "%<>").result(binding)
|
541
|
+
File.open(File.join(@dir, ".index.md"), "w") do |f|
|
542
|
+
f.write doc
|
543
|
+
end
|
544
|
+
|
545
|
+
accsmode
|
546
|
+
@dir = File.join(@dir, ".index.md")
|
547
|
+
main
|
548
|
+
end
|
549
|
+
|
550
|
+
###############################################
|
551
|
+
# PRIVATE METHODS (treat document) #
|
552
|
+
###############################################
|
553
|
+
|
554
|
+
private
|
555
|
+
|
556
|
+
# Turn on ACCS processing mode.
|
557
|
+
def accsmode
|
558
|
+
@accs_processing = true
|
559
|
+
@singlemode = true
|
560
|
+
@skip_index = true
|
561
|
+
end
|
562
|
+
|
563
|
+
# Read Frontmatter from the document.
|
564
|
+
# This method returns frontmatter, pos.
|
565
|
+
# pos means position at end of Frontmatter on the file.
|
566
|
+
def read_frontmatter(dir, filename)
|
567
|
+
frontmatter = nil
|
568
|
+
pos = nil
|
569
|
+
|
570
|
+
if File.exist? File.join(dir, ".meta." + filename)
|
571
|
+
# Load standalone metadata YAML.
|
572
|
+
frontmatter = YAML.load(File.read(File.join(dir, (".meta." + filename))))
|
573
|
+
pos = 0
|
574
|
+
else
|
575
|
+
|
576
|
+
case File.extname filename
|
577
|
+
when ".md"
|
578
|
+
|
579
|
+
# Load Markdown's YAML frontmatter.
|
580
|
+
File.open(File.join(dir, filename)) do |f|
|
581
|
+
l = f.gets
|
582
|
+
next unless l && l.chomp == "---"
|
583
|
+
|
584
|
+
lines = []
|
585
|
+
|
586
|
+
while l = f.gets
|
587
|
+
break if l.nil?
|
588
|
+
|
589
|
+
break if l.chomp == "---"
|
590
|
+
lines.push l
|
591
|
+
end
|
592
|
+
|
593
|
+
next if f.eof?
|
594
|
+
|
595
|
+
begin
|
596
|
+
frontmatter = YAML.load(lines.join)
|
597
|
+
rescue => e
|
598
|
+
STDERR.puts "!CRITICAL: Cannot parse frontmatter."
|
599
|
+
raise e
|
600
|
+
end
|
601
|
+
|
602
|
+
pos = f.pos
|
603
|
+
end
|
604
|
+
|
605
|
+
when ".rst"
|
606
|
+
# ReSTRUCTURED Text
|
607
|
+
|
608
|
+
File.open(File.join(dir, filename)) do |f|
|
609
|
+
l = f.gets
|
610
|
+
if l =~ /:([A-Za-z_-]+): (.*)/ #docinfo
|
611
|
+
frontmatter = { $1 => [$2.chomp] }
|
612
|
+
last_key = $1
|
613
|
+
|
614
|
+
# Read docinfo
|
615
|
+
while(l = f.gets)
|
616
|
+
break if l =~ /^\s*$/ # End of docinfo
|
617
|
+
if l =~ /^\s+/ # Continuous line
|
618
|
+
docinfo_lines.last.push($'.chomp)
|
619
|
+
elsif l =~ /:([A-Za-z_-]+): (.*)/
|
620
|
+
frontmatter[$1] = [$2.chomp]
|
621
|
+
last_key = $1
|
622
|
+
end
|
623
|
+
end
|
624
|
+
|
625
|
+
# Treat docinfo lines
|
626
|
+
frontmatter.each do |k,v|
|
627
|
+
v = v.join(" ")
|
628
|
+
#if((k == "author" || k == "authors") && v.include?(";")) # Multiple authors.
|
629
|
+
if(v.include?(";")) # Multiple element.
|
630
|
+
v = v.split(/\s*;\s*/)
|
631
|
+
|
632
|
+
elsif k == "date" # Date?
|
633
|
+
# Datetime?
|
634
|
+
if v =~ /[0-2][0-9]:[0-6][0-9]/
|
635
|
+
v = DateTime.parse(v)
|
636
|
+
else
|
637
|
+
v = Date.parse(v)
|
638
|
+
end
|
639
|
+
elsif v == "yes" || v == "true"
|
640
|
+
v = true
|
641
|
+
else # Simple String.
|
642
|
+
nil # keep v
|
643
|
+
end
|
644
|
+
|
645
|
+
frontmatter[k] = v
|
646
|
+
end
|
647
|
+
|
648
|
+
elsif l && l.chomp == ".." #YAML
|
649
|
+
# Load ReST YAML that document begins comment and block is yaml.
|
650
|
+
lines = []
|
651
|
+
|
652
|
+
while(l = f.gets)
|
653
|
+
if(l !~ /^\s*$/ .. l =~ /^\s*$/)
|
654
|
+
if l=~ /^\s*$/
|
655
|
+
break
|
656
|
+
else
|
657
|
+
lines.push l
|
658
|
+
end
|
659
|
+
end
|
660
|
+
end
|
661
|
+
next if f.eof?
|
662
|
+
|
663
|
+
|
664
|
+
# Rescue for failed to read YAML.
|
665
|
+
begin
|
666
|
+
frontmatter = YAML.load(lines.map {|i| i.sub(/^\s*/, "") }.join)
|
667
|
+
rescue
|
668
|
+
STDERR.puts "Error in parsing ReST YAML frontmatter (#{$!})"
|
669
|
+
next
|
670
|
+
end
|
671
|
+
else
|
672
|
+
next
|
673
|
+
end
|
674
|
+
|
675
|
+
pos = f.pos
|
676
|
+
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
abort "This document has no frontmatter" unless frontmatter
|
682
|
+
abort "This document has no title." unless frontmatter["title"]
|
683
|
+
|
684
|
+
|
685
|
+
### Additional meta values. ###
|
686
|
+
frontmatter["source_directory"] = dir # Source Directory
|
687
|
+
frontmatter["source_filename"] = filename # Source Filename
|
688
|
+
frontmatter["source_path"] = File.join(dir, filename) # Source Path
|
689
|
+
# URL in site.
|
690
|
+
this_url = (File.join(dir, filename)).sub(/^[\.\/]*/) { @config["self_url_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html")
|
691
|
+
frontmatter["page_url"] = this_url
|
692
|
+
# URL in site with URI encode.
|
693
|
+
frontmatter["page_url_encoded"] = ERB::Util.url_encode(this_url)
|
694
|
+
frontmatter["page_url_encoded_external"] = ERB::Util.url_encode((File.join(dir, filename)).sub(/^[\.\/]*/) { @config["self_url_external_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html"))
|
695
|
+
frontmatter["page_html_escaped"] = ERB::Util.html_escape(this_url)
|
696
|
+
frontmatter["page_html_escaped_external"] = ERB::Util.html_escape((File.join(dir, filename)).sub(/^[\.\/]*/) { @config["self_url_external_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html"))
|
697
|
+
# Title with URL Encoded.
|
698
|
+
frontmatter["title_encoded"] = ERB::Util.url_encode(frontmatter["title"])
|
699
|
+
frontmatter["title_html_escaped"] = ERB::Util.html_escape(frontmatter["title"])
|
700
|
+
fts = frontmatter["timestamp"]
|
701
|
+
fts = fts.to_datetime if Time === fts
|
702
|
+
if DateTime === fts
|
703
|
+
frontmatter["timestamp_xmlschema"] = fts.xmlschema
|
704
|
+
frontmatter["timestamp_jplocal"] = fts.strftime('%Y年%m月%d日 %H時%M分%S秒')
|
705
|
+
frontmatter["timestamp_rubytimestr"] = fts.strftime('%a %b %d %H:%M:%S %Z %Y')
|
706
|
+
frontmatter["timestamp_str"] = fts.strftime("%Y-%m-%d %H:%M:%S %Z")
|
707
|
+
elsif Date === fts
|
708
|
+
frontmatter["timestamp_xmlschema"] = fts.xmlschema
|
709
|
+
frontmatter["timestamp_jplocal"] = fts.strftime('%Y年%m月%d日')
|
710
|
+
frontmatter["timestamp_rubytimestr"] = fts.strftime('%a %b %d')
|
711
|
+
frontmatter["timestamp_str"] = fts.strftime("%Y-%m-%d")
|
712
|
+
elsif Date === frontmatter["Date"]
|
713
|
+
fts = frontmatter["Date"]
|
714
|
+
frontmatter["timestamp_xmlschema"] = fts.xmlschema
|
715
|
+
frontmatter["timestamp_jplocal"] = fts.strftime('%Y年%m月%d日')
|
716
|
+
frontmatter["timestamp_rubytimestr"] = fts.strftime('%a %b %d')
|
717
|
+
frontmatter["timestamp_str"] = fts.strftime("%Y-%m-%d")
|
718
|
+
end
|
719
|
+
|
720
|
+
fsize = FileTest.size(File.join(dir, filename))
|
721
|
+
mtime = File.mtime(File.join(dir, filename)).to_i
|
722
|
+
|
723
|
+
frontmatter["_filename"] ||= filename
|
724
|
+
frontmatter["pagetype"] ||= "post"
|
725
|
+
|
726
|
+
frontmatter["_size"] = fsize
|
727
|
+
frontmatter["_mtime"] = mtime
|
728
|
+
frontmatter["_last_proced"] = @now.to_i
|
729
|
+
|
730
|
+
if File.extname(filename) == ".md"
|
731
|
+
frontmatter["_docformat"] = "Markdown"
|
732
|
+
elsif File.extname(filename) == ".rst" || File.extname(filename) == ".rest"
|
733
|
+
frontmatter["_docformat"] = "ReST"
|
734
|
+
end
|
735
|
+
|
736
|
+
frontmatter["date"] ||= @now.strftime("%Y-%m-%d %H:%M:%S")
|
737
|
+
|
738
|
+
return frontmatter, pos
|
739
|
+
end
|
740
|
+
|
741
|
+
# Check is the article modified? (or force update?)
|
742
|
+
def check_modify(path, frontmatter)
|
743
|
+
modify = true
|
744
|
+
index = @indexes_orig[path[1]].dup || {}
|
745
|
+
frontmatter = @db.cmp_obj(frontmatter)
|
746
|
+
index.delete("_last_proced")
|
747
|
+
frontmatter.delete("_last_proced")
|
748
|
+
|
749
|
+
if index == frontmatter
|
750
|
+
STDERR.puts "#{path[1]} is not modified."
|
751
|
+
modify = false
|
752
|
+
else
|
753
|
+
STDERR.puts "#{path[1]} last modified at #{frontmatter["_mtime"]}, last processed at #{@indexes_orig[path[1]]&.[]("_last_proced") || 0}"
|
754
|
+
frontmatter["last_update"] = @now.strftime("%Y-%m-%d %H:%M:%S")
|
755
|
+
end
|
756
|
+
|
757
|
+
if @refresh
|
758
|
+
# Refresh (force update) mode.
|
759
|
+
true
|
760
|
+
else
|
761
|
+
modify
|
762
|
+
end
|
763
|
+
end
|
764
|
+
|
765
|
+
def bless_ruby(frontmatter)
|
766
|
+
# BLESSING (Always)
|
767
|
+
if PureBuilder.const_defined?(:BLESS) && Proc === PureBuilder::BLESS
|
768
|
+
begin
|
769
|
+
PureBuilder::BLESS.(frontmatter, self)
|
770
|
+
rescue
|
771
|
+
STDERR.puts "*** BLESSING PROC ERROR ***"
|
772
|
+
raise
|
773
|
+
end
|
774
|
+
end
|
775
|
+
|
776
|
+
# BLESSING (ACCS)
|
777
|
+
if @accs && PureBuilder::ACCS.const_defined?(:BLESS) && Proc === PureBuilder::ACCS::BLESS
|
778
|
+
begin
|
779
|
+
PureBuilder::ACCS::BLESS.(frontmatter, self)
|
780
|
+
rescue
|
781
|
+
STDERR.puts "*** ACCS BLESSING PROC ERROR ***"
|
782
|
+
raise
|
783
|
+
end
|
784
|
+
end
|
785
|
+
|
786
|
+
# ACCS DEFINITIONS
|
787
|
+
if @accs
|
788
|
+
if Proc === PureBuilder::ACCS::DEFINITIONS[:next]
|
789
|
+
i = PureBuilder::ACCS::DEFINITIONS[:next].call(frontmatter, self)
|
790
|
+
frontmatter["next_article"] = i if i
|
791
|
+
end
|
792
|
+
if Proc === PureBuilder::ACCS::DEFINITIONS[:prev]
|
793
|
+
i = PureBuilder::ACCS::DEFINITIONS[:prev].call(frontmatter, self)
|
794
|
+
frontmatter["prev_article"] = i if i
|
795
|
+
end
|
796
|
+
end
|
797
|
+
|
798
|
+
autobless(frontmatter)
|
799
|
+
end
|
800
|
+
|
801
|
+
def bless_cmd(frontmatter)
|
802
|
+
File.open(".pbsimply-frontmatter.json", "w") {|f| f.write JSON_LIB.dump(frontmatter) }
|
803
|
+
# BLESSING (Always)
|
804
|
+
if @config["bless_cmd"]
|
805
|
+
(Array === @config["bless_cmd"] ? system(*@config["bless_cmd"]) : system(@config["bless_cmd"]) ) or abort "*** BLESS COMMAND RETURNS NON-ZERO STATUS"
|
806
|
+
end
|
807
|
+
# BLESSING (ACCS)
|
808
|
+
if @config["bless_accscmd"]
|
809
|
+
(Array === @config["bless_accscmd"] ? system({"pbsimply_frontmatter" => ".pbsimply-frontmatter.json", "pbsimply_indexes" => @db.path}, *@config["bless_accscmd"]) : system({"pbsimply_frontmatter" => ".pbsimply-frontmatter.json", "pbsimply_indexes" => @db.path}, @config["bless_accscmd"]) ) or abort "*** BLESS COMMAND RETURNS NON-ZERO STATUS"
|
810
|
+
end
|
811
|
+
mod_frontmatter = JSON.load(File.read(".pbsimply-frontmatter.json"))
|
812
|
+
frontmatter.replace(mod_frontmatter)
|
813
|
+
|
814
|
+
autobless(frontmatter)
|
815
|
+
end
|
816
|
+
|
817
|
+
# Blessing automatic method with configuration.
|
818
|
+
def autobless(frontmatter)
|
819
|
+
catch(:accs_rel) do
|
820
|
+
# find Next/Prev page on accs
|
821
|
+
if @accs && @config["blessmethod_accs_rel"]
|
822
|
+
# Preparing. Run at once.
|
823
|
+
if !@article_order
|
824
|
+
@rev_article_order_index = {}
|
825
|
+
|
826
|
+
case @config["blessmethod_accs_rel"]
|
827
|
+
when "numbering"
|
828
|
+
@article_order = @indexes.to_a.sort_by {|i| i[1]["_filename"].to_i }
|
829
|
+
when "date"
|
830
|
+
begin
|
831
|
+
@article_order = @indexes.to_a.sort_by {|i| i[1]["date"]}
|
832
|
+
rescue
|
833
|
+
abort "*** Automatic Blessing Method Error: Maybe some article have no date."
|
834
|
+
end
|
835
|
+
when "timestamp"
|
836
|
+
begin
|
837
|
+
@article_order = @indexes.to_a.sort_by {|i| i[1]["timestamp"]}
|
838
|
+
rescue
|
839
|
+
abort "*** Automatic Blessing Method Error: Maybe some article have no timetsamp."
|
840
|
+
end
|
841
|
+
when "lexical"
|
842
|
+
@article_order = @indexes.to_a.sort_by {|i| i[1]["_filename"]}
|
843
|
+
end
|
844
|
+
@article_order.each_with_index {|x,i| @rev_article_order_index[x[0]] = i }
|
845
|
+
end
|
846
|
+
|
847
|
+
throw(:accs_rel) unless index = @rev_article_order_index[frontmatter["_filename"]]
|
848
|
+
if @article_order[index + 1]
|
849
|
+
frontmatter["next_article"] = {"url" => @article_order[index + 1][1]["page_url"],
|
850
|
+
"title" => @article_order[index + 1][1]["title"]}
|
851
|
+
end
|
852
|
+
if index > 0
|
853
|
+
frontmatter["prev_article"] = {"url" => @article_order[index - 1][1]["page_url"],
|
854
|
+
"title" => @article_order[index - 1][1]["title"]}
|
855
|
+
end
|
856
|
+
end
|
857
|
+
end
|
858
|
+
end
|
859
|
+
|
860
|
+
###############################################
|
861
|
+
# DOCUMENT PROCESSORS #
|
862
|
+
###############################################
|
863
|
+
|
864
|
+
|
865
|
+
module Processor
|
866
|
+
|
867
|
+
# Pandoc processor
|
868
|
+
class Pandoc < PBSimply
|
869
|
+
def initialize(config)
|
870
|
+
@pandoc_default_file = {}
|
871
|
+
|
872
|
+
# -d
|
873
|
+
@pandoc_default_file = {
|
874
|
+
"to" => "html5",
|
875
|
+
"standalone" => true
|
876
|
+
}
|
877
|
+
super
|
878
|
+
end
|
879
|
+
|
880
|
+
def setup_config(dir)
|
881
|
+
super
|
882
|
+
@pandoc_default_file["template"] = @config["template"]
|
883
|
+
|
884
|
+
if @config["css"]
|
885
|
+
if @config["css"].kind_of?(String)
|
886
|
+
@pandoc_default_file["css"] = [@config["css"]]
|
887
|
+
elsif @config["css"].kind_of?(Array)
|
888
|
+
@pandoc_default_file["css"] = @config["css"]
|
889
|
+
else
|
890
|
+
abort "css in Config should be a String or an Array."
|
891
|
+
end
|
892
|
+
end
|
893
|
+
|
894
|
+
if @config["toc"]
|
895
|
+
@pandoc_default_file["toc"] = true
|
896
|
+
end
|
897
|
+
|
898
|
+
if Hash === @config["pandoc_additional_options"]
|
899
|
+
@pandoc_default_file.merge! @config["pandoc_additional_options"]
|
900
|
+
end
|
901
|
+
|
902
|
+
end
|
903
|
+
|
904
|
+
# Invoke pandoc, parse and format and write out.
|
905
|
+
def print_fileproc_msg(filename)
|
906
|
+
STDERR.puts "#{filename} is going Pandoc."
|
907
|
+
end
|
908
|
+
|
909
|
+
def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
|
910
|
+
doc = nil
|
911
|
+
|
912
|
+
File.open(".pbsimply-defaultfiles.yaml", "w") {|f| YAML.dump(@pandoc_default_file, f)}
|
913
|
+
File.open(".pbsimply-frontmatter.yaml", "w") {|f| YAML.dump(frontmatter, f)}
|
914
|
+
|
915
|
+
# Go Pandoc
|
916
|
+
pandoc_cmdline = ["pandoc"]
|
917
|
+
pandoc_cmdline += ["-d", ".pbsimply-defaultfiles.yaml", "--metadata-file", ".pbsimply-frontmatter.yaml", "-M", "title:#{frontmatter["title"]}"]
|
918
|
+
pandoc_cmdline += ["-f", frontmatter["input_format"]] if frontmatter["input_format"]
|
919
|
+
pandoc_cmdline += [ procdoc ]
|
920
|
+
IO.popen((pandoc_cmdline)) do |io|
|
921
|
+
doc = io.read
|
922
|
+
end
|
923
|
+
|
924
|
+
# Abort if pandoc returns non-zero status
|
925
|
+
if $?.exitstatus != 0
|
926
|
+
abort "Pandoc returns exit code #{$?.exitstatus}"
|
927
|
+
end
|
928
|
+
|
929
|
+
doc
|
930
|
+
end
|
931
|
+
|
932
|
+
def target_file_extensions
|
933
|
+
[".md", ".rst"]
|
934
|
+
end
|
935
|
+
end
|
936
|
+
|
937
|
+
# RDoc family Base
|
938
|
+
class PbsRBase < PBSimply
|
939
|
+
def initialize(config)
|
940
|
+
require 'rdoc'
|
941
|
+
require 'rdoc/markup/to_html'
|
942
|
+
|
943
|
+
@rdoc_options = RDoc::Options.new
|
944
|
+
@rdoc_markup = RDoc::Markup.new
|
945
|
+
|
946
|
+
super
|
947
|
+
end
|
948
|
+
|
949
|
+
def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
|
950
|
+
# Getting HTML string.
|
951
|
+
rdoc = RDoc::Markup::ToHtml.new(@rdoc_options, @rdoc_markup)
|
952
|
+
article_body = rdoc.convert(get_markup_document(procdoc))
|
953
|
+
|
954
|
+
# Process with eRuby temaplte.
|
955
|
+
erb_template = ERB.new(File.read(@config["template"]), trim_mode: '%<>')
|
956
|
+
doc = erb_template.result(binding)
|
957
|
+
|
958
|
+
doc
|
959
|
+
end
|
960
|
+
end
|
961
|
+
|
962
|
+
# RDoc/Markdown processor
|
963
|
+
class PbsRMakrdown < PbsRBase
|
964
|
+
def initialize(config)
|
965
|
+
require 'rdoc'
|
966
|
+
require 'rdoc/markdown'
|
967
|
+
super
|
968
|
+
end
|
969
|
+
|
970
|
+
def print_fileproc_msg(filename)
|
971
|
+
STDERR.puts "#{filename} generate with RDoc/Markdown"
|
972
|
+
end
|
973
|
+
|
974
|
+
def get_markup_document procdoc
|
975
|
+
RDoc::Markdown.parse(File.read procdoc)
|
976
|
+
end
|
977
|
+
end
|
978
|
+
|
979
|
+
# RDoc processor
|
980
|
+
class PbsRDoc < PbsRBase
|
981
|
+
def print_fileproc_msg(filename)
|
982
|
+
STDERR.puts "#{filename} generate with RDoc"
|
983
|
+
end
|
984
|
+
|
985
|
+
def get_markup_document procdoc
|
986
|
+
File.read procdoc
|
987
|
+
end
|
988
|
+
|
989
|
+
def target_file_extensions
|
990
|
+
[".rdoc"]
|
991
|
+
end
|
992
|
+
end
|
993
|
+
|
994
|
+
class PbsRedCarpet < PBSimply
|
995
|
+
def initialize(config)
|
996
|
+
require 'redcarpet'
|
997
|
+
super
|
998
|
+
end
|
999
|
+
|
1000
|
+
def setup_config(dir)
|
1001
|
+
super
|
1002
|
+
@rc_extension = @config["redcarpet_extensions"] || {}
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def print_fileproc_msg(filename)
|
1006
|
+
STDERR.puts "#{filename} generate with Redcarpet Markdown"
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
|
1010
|
+
# Getting HTML string.
|
1011
|
+
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, **@rc_extension)
|
1012
|
+
article_body = markdown.render(File.read procdoc)
|
1013
|
+
|
1014
|
+
# Process with eRuby temaplte.
|
1015
|
+
erb_template = ERB.new(File.read(@config["template"]), trim_mode: '%<>')
|
1016
|
+
doc = erb_template.result(binding)
|
1017
|
+
|
1018
|
+
doc
|
1019
|
+
end
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
class PbsKramdown < PBSimply
|
1023
|
+
def initialize(config)
|
1024
|
+
require 'kramdown'
|
1025
|
+
super
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
def print_fileproc_msg(filename)
|
1029
|
+
STDERR.puts "#{filename} generate with Kramdown"
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
|
1033
|
+
# Set feature options
|
1034
|
+
features = @config["kramdown_features"] || {}
|
1035
|
+
|
1036
|
+
# Getting HTML string.
|
1037
|
+
markdown = Kramdown::Document.new(File.read(procdoc), **features)
|
1038
|
+
article_body = markdown.to_html
|
1039
|
+
|
1040
|
+
# Process with eRuby temaplte.
|
1041
|
+
erb_template = ERB.new(File.read(@config["template"]), trim_mode: '%<>')
|
1042
|
+
doc = erb_template.result(binding)
|
1043
|
+
|
1044
|
+
doc
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
class PbsCommonMark < PBSimply
|
1049
|
+
def initialize(config)
|
1050
|
+
require 'commonmarker'
|
1051
|
+
super
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
def print_fileproc_msg(filename)
|
1055
|
+
STDERR.puts "#{filename} generate with CommonMarker (cmark-gfm)"
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
|
1059
|
+
# Getting HTML string.
|
1060
|
+
article_body = CommonMarker.render_doc(File.read(procdoc), :DEFAULT, [:table, :strikethrough]).to_html
|
1061
|
+
|
1062
|
+
# Process with eRuby temaplte.
|
1063
|
+
erb_template = ERB.new(File.read(@config["template"]), trim_mode: '%<>')
|
1064
|
+
doc = erb_template.result(binding)
|
1065
|
+
|
1066
|
+
doc
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
end
|
1071
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pbsimply
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Masaki Haruka
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-01-02 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Pre compile, static serving headless CMS
|
14
|
+
email:
|
15
|
+
- yek@reasonset.net
|
16
|
+
executables:
|
17
|
+
- pbsimply
|
18
|
+
- pbsimply-testserver
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- bin/pbsimply
|
23
|
+
- bin/pbsimply-testserver
|
24
|
+
- lib/pbsimply.rb
|
25
|
+
homepage: https://github.com/reasonset/purebuilder-simply
|
26
|
+
licenses:
|
27
|
+
- Apache-2.0
|
28
|
+
metadata: {}
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options: []
|
31
|
+
require_paths:
|
32
|
+
- lib
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubygems_version: 3.2.29
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: PureBuiler Simply
|
48
|
+
test_files: []
|