pbsimply 3.4.2 → 3.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb5f5d9b6fc087e4096b312c9fd859f85d5e4435c8e6671af35570cc126b93d3
4
- data.tar.gz: d58e752fc487f64383c731075363535c14ed329a2c3cb43107059cfdb8707837
3
+ metadata.gz: 2f75e4f4e81729dbe5a291d473f1f2dc83bd51d52076179bd1a5517cf6bde380
4
+ data.tar.gz: df909fb121e61744b056e0d934e07acd43d88d1630873c78910cc92a6462c390
5
5
  SHA512:
6
- metadata.gz: 2dc1d4ea9145abefc6834e43fb8360bc6e01026ad1ea2f3a51dd461ea7656fb6d6284dcd564e62063cafc6f2cd6cd15d3b7630aa905cf2d1b57fd03c7f46e640
7
- data.tar.gz: 31c080d6f466a753f2ba834306f1a4fcb14420c37a9b54257672ae9717fa044d081f785ebe5152c4dbb29dad90c9aca42abbd7193d61c6009ee2d1c5fcafb88e
6
+ metadata.gz: 06417d28977298a737faee844340700128d9d047d938ea16737ede93d1d8609e6844d0f3b49c138b4129b9c658f9a1444f38eb89e80848aa3362e1d04b47b720
7
+ data.tar.gz: da761d0166bc05e276296b449393f2914ea6b462ebe28d6d96ea1f392323bfa919864c3d655e1279029f57773cbdd7d89464cb33f0f74be28032455ddd275ac2
data/bin/pbsimply CHANGED
@@ -25,6 +25,12 @@ end
25
25
  # Alias for compatibility.
26
26
  PureBuilder = pbs_class
27
27
 
28
- pbs = pbs_class.new(config)
29
- pbs.treat_cmdline
30
- pbs.main
28
+ begin
29
+ pbs = pbs_class.new(config)
30
+ pbs.treat_cmdline
31
+
32
+ pbs.main
33
+ rescue PBSimply::CommandLineError => e
34
+ $stderr.puts e.to_s
35
+ exit 1
36
+ end
@@ -85,7 +85,6 @@ class PBSimply
85
85
  end
86
86
 
87
87
  def target_file_extensions
88
- p [".md", ".rst"] + @pandoc_input_extmap.keys
89
88
  [".md", ".rst"] + @pandoc_input_extmap.keys
90
89
  end
91
90
  end
@@ -0,0 +1,110 @@
1
+ require 'pbsimply/frontmatter'
2
+
3
+ class PBSimply
4
+ class Document
5
+ include Frontmatter
6
+
7
+ def initialize(config, dir, filename, base_frontmatter, now)
8
+ @config = config
9
+ @dir = dir
10
+ @filename = filename
11
+ @ext = File.extname filename
12
+ @orig_filepath = File.join(dir, filename)
13
+ @now = now
14
+ frontmatter, @pos = read_frontmatter(dir, filename)
15
+ @frontmatter = base_frontmatter.merge frontmatter
16
+ @modified = true
17
+ @proc_doc_path = nil
18
+ end
19
+
20
+ attr_reader :frontmatter, :filename, :pos, :ext, :proc_doc_path, :orig_filepath
21
+ attr_accessor :orig_frontmatter, :now
22
+
23
+ def add_meta(additional_meta)
24
+ frontmatter.merge!(additional_meta)
25
+ end
26
+
27
+ def read_document(workdir: "")
28
+ File.open(File.join(@dir, @filename)) do |f|
29
+ f.seek(@pos)
30
+ doc_content = f.read
31
+ if @config["unicode_normalize"] && !@frontmatter["skip_normalize"]
32
+ doc_content.unicode_normalize!(@config["unicode_normalize"].to_sym)
33
+ end
34
+ File.open(File.join(workdir, "current_document#{@ext}"), "w") do |fo|
35
+ fo.write doc_content
36
+ end
37
+ end
38
+
39
+ @proc_doc_path = File.join(workdir, "current_document#{@ext}")
40
+ end
41
+
42
+ def draft?
43
+ frontmatter["draft"]
44
+ end
45
+
46
+ def to_a
47
+ [@dir, @filename, @frontmatter]
48
+ end
49
+
50
+ # Check is the article modified? (or force update?)
51
+ def modified?
52
+ index = @orig_frontmatter ||= {}
53
+
54
+ case @config["detect_modification"]
55
+ when "changes"
56
+ # Use "changes"
57
+ @modified = false if @frontmatter["changes"] == index["changes"]
58
+ when "mtimesize"
59
+ # Use mtime and file size.
60
+ @modified = false if @frontmatter["_mtime"] <= (index["_last_proced"] || 0) && @frontmatter["_size"] == index["_size"]
61
+ else
62
+ # Default method, use mtime.
63
+ @modified = false if @frontmatter["_mtime"] <= (index["_last_proced"] || 0)
64
+ end
65
+
66
+ if @modified
67
+ $stderr.puts "#{@filename} last modified at #{@frontmatter["_mtime"]}, last processed at #{index["_last_proced"] || 0}"
68
+ else
69
+ $stderr.puts "#{@filename} is not modified."
70
+ end
71
+
72
+ set_timestamp
73
+
74
+ if @frontmatter["skip_update"]
75
+ # Document specific skip update
76
+ @modified = false
77
+ elsif index["_modified"]
78
+ @modified = true
79
+ else
80
+ @modified
81
+ end
82
+ end
83
+
84
+ def mark_meta_modified
85
+ # Frontmatter used as a reference for metadata update detection.
86
+ # Keys that are always updated during processing should be removed.
87
+ ex_keys = ["_last_proced", "last_update"] + (@config["compr_ex_keys"] || [])
88
+ @orig_frontmatter ||= {}
89
+ compr_frontmatter = @orig_frontmatter.except(*ex_keys) # Hash#except from Ruby 2.0
90
+
91
+ if compr_frontmatter == frontmatter
92
+ @modified = false
93
+ else
94
+ @frontmatter["_modified"] = true
95
+ @frontmatter.merge!(@orig_frontmatter.slice(*ex_keys))
96
+ end
97
+ end
98
+
99
+ def effective_forntmatter
100
+ @modified ? @frontmatter : @orig_frontmatter
101
+ end
102
+
103
+ private
104
+
105
+ def set_timestamp
106
+ @frontmatter["_last_proced"] = @now.to_i
107
+ @frontmatter["last_update"] = @now.strftime("%Y-%m-%d %H:%M:%S")
108
+ end
109
+ end
110
+ end
@@ -211,6 +211,8 @@ module PBSimply::Frontmatter
211
211
  return frontmatter, pos
212
212
  end
213
213
 
214
+ private
215
+
214
216
  def outext frontmatter
215
217
  return frontmatter["force_ext"] if frontmatter["force_ext"]
216
218
 
@@ -107,11 +107,5 @@ class PBSimply::Hooks
107
107
  end
108
108
  end
109
109
 
110
- attr :pre
111
- attr :process
112
- attr :delete
113
- attr :post
114
- attr :accs
115
-
116
- attr :config
110
+ attr_reader :pre, :process, :delete, :post, :accs, :config
117
111
  end
data/lib/pbsimply.rb CHANGED
@@ -16,16 +16,19 @@ require 'pbsimply/docengine/base'
16
16
  require 'pbsimply/prayer'
17
17
  require 'pbsimply/plugger'
18
18
  require 'pbsimply/hooks'
19
- require 'pbsimply/frontmatter'
20
19
  require 'pbsimply/accs'
21
20
  require 'pbsimply/config-checker.rb'
21
+ require 'pbsimply/document'
22
22
 
23
23
  class PBSimply
24
24
  include Prayer
25
25
  include Plugger
26
- include Frontmatter
27
26
  include ACCS
28
27
 
28
+ # Custom exception
29
+ class CommandLineError < StandardError
30
+ end
31
+
29
32
  # Use Oj as JSON library for frontmatter passing if possible.
30
33
  begin
31
34
  require 'oj'
@@ -119,6 +122,7 @@ class PBSimply
119
122
 
120
123
  @refresh = false # Force generate all documents.
121
124
  @skip_index = false # Don't register to index.
125
+ @preflight = false # Don't generate output document.
122
126
  @outfile = nil # Fixed output filename
123
127
  @add_meta = nil
124
128
  @accs = nil
@@ -137,8 +141,10 @@ class PBSimply
137
141
  opts.on("-X", "--ignore-ext") { @ignore_ext = true }
138
142
  opts.on("-I", "--skip-index") { @skip_index = true }
139
143
  opts.on("-A", "--skip-accs") { @skip_accs = true }
144
+ opts.on("-p", "--preflight") { @preflight = true }
140
145
  opts.on("-o FILE", "--output") {|v| @outfile = v }
141
146
  opts.on("-m FILE", "--additional-metafile") {|v| @add_meta = Psych.unsafe_load(File.read(v))}
147
+ opts.on("-a", "--only-accs") { @accs_only = true }
142
148
  opts.parse!(ARGV)
143
149
 
144
150
  if File.exist?(".pbsimply-bless.rb")
@@ -171,7 +177,7 @@ class PBSimply
171
177
  @docobject
172
178
  end
173
179
 
174
- attr :indexes
180
+ attr_reader :indexes
175
181
 
176
182
  ###############################################
177
183
  # PROCESSING FUNCTIONS #
@@ -182,7 +188,6 @@ class PBSimply
182
188
  def proc_dir
183
189
  draft_articles = []
184
190
  target_docs = []
185
- @indexes_orig = {}
186
191
  $stderr.puts "in #{@dir}..."
187
192
 
188
193
  $stderr.puts "Checking Frontmatter..."
@@ -202,11 +207,9 @@ class PBSimply
202
207
  end
203
208
 
204
209
  $stderr.puts "Checking frontmatter in #{filename}"
205
- frontmatter, pos = read_frontmatter(@dir, filename)
206
- frontmatter = @frontmatter.merge frontmatter
207
- frontmatter.merge!(@add_meta) if @add_meta
210
+ doc = Document.new(@config, @dir, filename, @frontmatter, @now)
208
211
 
209
- if frontmatter["draft"]
212
+ if doc.draft?
210
213
  draft_articles.push({
211
214
  article_filename: filename,
212
215
  filename: filename,
@@ -215,30 +218,31 @@ class PBSimply
215
218
  next
216
219
  end
217
220
 
218
- @indexes_orig[filename] = @indexes[filename]
219
- @indexes[filename] = frontmatter
221
+ doc.orig_frontmatter = @indexes[filename]
220
222
 
221
223
  # Push to target documents without checking modification.
222
- target_docs.push([filename, frontmatter, pos])
224
+ target_docs.push(doc)
223
225
  end
224
226
  ENV.delete("pbsimply_currentdoc")
225
227
  ENV.delete("pbsimply_filename")
226
228
 
227
229
  delete_turn_draft draft_articles
228
230
 
229
- # #proc_docs destructs target_docs
230
- processed_docs = proc_docs target_docs.dup
231
+ proc_docs target_docs
231
232
 
232
233
  delete_missing
233
-
234
- # Restore skipped doc's frontmatter
235
- orig_filelist = Set.new(target_docs.map {|i| i[0]})
236
- proc_filelist = Set.new(processed_docs.map {|i| i[0]})
237
- recov_filelist = orig_filelist - proc_filelist
238
- recov_filelist.each do |filename|
239
- @indexes[filename] = @indexes_orig[filename]
240
- end
241
234
 
235
+ # Update modified doc's frontmatter
236
+ if @preflight
237
+ target_docs.each do |doc|
238
+ @indexes[doc.filename] = doc.effective_forntmatter
239
+ end
240
+ else
241
+ target_docs.each do |doc|
242
+ @indexes[doc.filename] = doc.frontmatter
243
+ end
244
+ end
245
+
242
246
  # Save index.
243
247
  @db.dump(@indexes) unless @skip_index
244
248
 
@@ -250,37 +254,41 @@ class PBSimply
250
254
 
251
255
  def proc_docs target_docs
252
256
  # Exclude unchanged documents.
253
- if @indexes && @indexes_orig
257
+ unless @singlemode
254
258
  $stderr.puts "Checking modification..."
255
- target_docs.delete_if {|filename, frontmatter, pos| !check_modify(filename, frontmatter)}
259
+ if !@preflight
260
+ target_docs.delete_if do |doc|
261
+ next false if @refresh # Force refresh mode
262
+ !doc.modified?
263
+ end
264
+ # target_docs.delete_if {|filename, frontmatter, pos| !check_modify(filename, frontmatter)}
265
+ end
256
266
  end
257
267
 
258
268
  # Modify frontmatter `BLESSING'
259
- target_docs.each do |filename, frontmatter, pos|
260
- $stderr.puts "Blessing #{filename}..."
261
- bless frontmatter
269
+ target_docs.each do |doc|
270
+ $stderr.puts "Blessing #{doc.filename}..."
271
+ bless doc.frontmatter
272
+ end
273
+
274
+ if !@singlemode && @preflight
275
+ $stderr.puts "Checking metadata modification..."
276
+ target_docs.each {|doc| doc.mark_meta_modified }
277
+ return # Resign processing document in preflight mode.
262
278
  end
263
279
 
264
280
  # Ready.
265
281
  $stderr.puts "Okay, Now ready. Process documents..."
266
282
 
267
283
  # Proccess documents
268
- target_docs.each do |filename, frontmatter, pos|
269
- ext = File.extname filename
270
- ENV["pbsimply_currentdoc"] = File.join(@workdir, "current_document#{ext}")
271
- ENV["pbsimply_filename"] = filename
272
- @index = frontmatter
273
- File.open(File.join(@dir, filename)) do |f|
274
- f.seek(pos)
275
- doc_content = f.read
276
- if @config["unicode_normalize"] && !frontmatter["skip_normalize"]
277
- doc_content.unicode_normalize!(@config["unicode_normalize"].to_sym)
278
- end
279
- File.open(File.join(@workdir, "current_document#{ext}"), "w") {|fo| fo.write doc_content }
280
- end
281
-
282
- $stderr.puts "Processing #{filename}"
283
- generate(@dir, filename, frontmatter)
284
+ target_docs.each do |doc|
285
+ ENV["pbsimply_currentdoc"] = File.join(@workdir, "current_document#{doc.ext}")
286
+ ENV["pbsimply_filename"] = doc.filename
287
+ @index = doc.frontmatter
288
+ doc.read_document(workdir: @workdir)
289
+
290
+ $stderr.puts "Processing #{doc.filename}"
291
+ generate(doc)
284
292
  end
285
293
 
286
294
  # Call post plugins
@@ -337,11 +345,20 @@ class PBSimply
337
345
  ENV["pbsimply_frontmatter"] = @workfile_frontmatter
338
346
  @workfile_pandoc_defaultfiles ||= File.join(@workdir, "pbsimply-defaultfiles.yaml")
339
347
  # If target file is regular file, run as single mode.
340
- @singlemode = true if File.file?(@dir)
348
+ @singlemode = File.file?(@dir)
349
+
350
+ if @accs_only && !@accs_processing
351
+ accs_only_mode_check
341
352
 
342
- # Check single file mode.
343
- if @singlemode
353
+ # Process ACCS without regular generating document
354
+ setup_config(@dir)
355
+ load_index
356
+
357
+ process_accs
358
+ elsif @singlemode # Check single file mode.
344
359
  # Single file mode
360
+ return if @preflight
361
+
345
362
  if @dir =~ %r:(.*)/([^/]+):
346
363
  dir = $1
347
364
  filename = $2
@@ -354,14 +371,13 @@ class PBSimply
354
371
 
355
372
  load_index
356
373
 
357
- frontmatter, pos = read_frontmatter(dir, filename)
358
- frontmatter = @frontmatter.merge frontmatter
359
- @index = frontmatter
374
+ doc = Document.new(@config, dir, filename, @frontmatter, @now)
375
+ @index = doc.frontmatter
360
376
 
361
- proc_docs([[filename, frontmatter, pos]])
377
+ proc_docs([doc])
362
378
 
363
379
  if File.exist?(File.join(@dir, ".accs.yaml")) && !@accs_processing && !@skip_accs
364
- single_accs filename, frontmatter
380
+ single_accs doc.filename, doc.frontmatter
365
381
  end
366
382
  else
367
383
  # Normal (directory) mode.
@@ -379,13 +395,14 @@ class PBSimply
379
395
  @workfile_pandoc_defaultfiles = nil
380
396
  end
381
397
 
382
- def generate(dir, filename, frontmatter)
398
+ def generate(doc)
399
+ dir, filename, frontmatter = *doc.to_a
383
400
  print_fileproc_msg(filename) # at sub-class
384
401
 
385
402
  # Preparing and pre script.
386
- orig_filepath = [dir, filename].join("/")
387
- ext = File.extname(filename)
388
- procdoc = File.join(@workdir, "current_document#{ext}")
403
+ orig_filepath = doc.orig_filepath
404
+ ext = doc.ext
405
+ procdoc = doc.proc_doc_path
389
406
 
390
407
  pre_plugins(procdoc, frontmatter)
391
408
  @hooks.pre.run({procdoc: procdoc, frontmatter: frontmatter})
@@ -454,41 +471,12 @@ class PBSimply
454
471
  end
455
472
  end
456
473
 
457
- # Check is the article modified? (or force update?)
458
- def check_modify(filename, frontmatter)
459
- modify = true
460
- index = @indexes_orig[filename]&.dup || {}
461
-
462
- case @config["detect_modification"]
463
- when "changes"
464
- # Use "changes"
465
- modify = false if frontmatter["changes"] == index["changes"]
466
- when "mtimesize"
467
- # Use mtime and file size.
468
- modify = false if frontmatter["_mtime"] <= (index["_last_proced"] || 0) && frontmatter["_size"] == index["_size"]
469
- else
470
- # Default method, use mtime.
471
- modify = false if frontmatter["_mtime"] <= (index["_last_proced"] || 0)
472
- end
473
-
474
-
475
- if modify
476
- $stderr.puts "#{filename} last modified at #{frontmatter["_mtime"]}, last processed at #{@indexes_orig[filename]&.[]("_last_proced") || 0}"
477
- else
478
- $stderr.puts "#{filename} is not modified."
474
+ def accs_only_mode_check
475
+ unless File.exist?(File.join(@dir, ".accs.yaml"))
476
+ raise CommandLineError.new "ACCS-only processing mode can only be performed on the ACCS directory."
479
477
  end
480
-
481
- frontmatter["_last_proced"] = @now.to_i
482
- frontmatter["last_update"] = @now.strftime("%Y-%m-%d %H:%M:%S")
483
-
484
- if frontmatter["skip_update"]
485
- # Document specific skip update
486
- false
487
- elsif @refresh
488
- # Refresh (force update) mode.
489
- true
490
- else
491
- modify
478
+ unless File.directory?(@dir)
479
+ raise CommandLineError.new "ACCS-only processing needs ACCS directory as an argument."
492
480
  end
493
481
  end
494
482
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pbsimply
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.2
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Haruka
@@ -36,6 +36,7 @@ files:
36
36
  - lib/pbsimply/docengine/misc.rb
37
37
  - lib/pbsimply/docengine/pandoc.rb
38
38
  - lib/pbsimply/docengine/rdoc.rb
39
+ - lib/pbsimply/document.rb
39
40
  - lib/pbsimply/frontmatter.rb
40
41
  - lib/pbsimply/hooks.rb
41
42
  - lib/pbsimply/plugger.rb