pbsimply 3.3.1 → 3.4.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: 38b7c82bfe81f73eb7ce562485bb9e624f9feb0ac6632b0161bef86039b4bf0d
4
- data.tar.gz: 97d5d322aa777ae16cfd0064907e088fcfeec60923da4cd1c1fe9e370a863e51
3
+ metadata.gz: 87e2e59a800bc257a946462c2396a7abe5dcb4d56c005890c633ac8060f21853
4
+ data.tar.gz: 59d8f531580cb215fba217fb1494539c6cb9a158642789059bb17ceaeb8a871c
5
5
  SHA512:
6
- metadata.gz: c9667151ac7f946cd50dcde20cc534c1aae15dbd288160b5927394cc9cfc64b60009cc9cf2eee6093e7734ebdea6adcbb20cdd20f3f0805e5e97d50ecd8b9094
7
- data.tar.gz: ad3504af0ab19b7780e5890ac6329fbbfb6fd00ff9fc58b529cb9aa469d32571bd3987f3b6b38ff4106645058b2d12a42e1aef8350e6ea8a378a86b574bd3a11
6
+ metadata.gz: b0ce2e7378becd3db0770612ef499d1924a473cb9e22b14d998e613d952cb2431f992d3605442802c3cd10d4a7f45debc23b2c57cb27db921c032f08ac2823ba
7
+ data.tar.gz: 2826fa6dca8231a850c31cd336338f00442076d733a594256416c40df2b87e450c95d495208207b444d30e751f40517de24bab50b86a9db44e41ef0b7f449337
data/LICENSE ADDED
@@ -0,0 +1,191 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ Copyright 2017 Masaki Haruka
180
+
181
+ Licensed under the Apache License, Version 2.0 (the "License");
182
+ you may not use this file except in compliance with the License.
183
+ You may obtain a copy of the License at
184
+
185
+ http://www.apache.org/licenses/LICENSE-2.0
186
+
187
+ Unless required by applicable law or agreed to in writing, software
188
+ distributed under the License is distributed on an "AS IS" BASIS,
189
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
190
+ See the License for the specific language governing permissions and
191
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # Purebuilder Simply
2
+
3
+ Programmable static site generator supporting Markdown, reStructuredText, and RDoc via pluggable engines and CLI-based workflows.
4
+
5
+ ## What is PureBuilder
6
+
7
+ PureBuilder Simply is a pre-built website building tool. It is also called a headless CMS or SSG.
8
+
9
+ It is easy to build and update, excels in writing functions, and is suitable for building text-centric websites.
10
+
11
+ ## What is ACCS
12
+
13
+ ACCS is site building script for serialized articles.
14
+
15
+ PB Simply ACCS make `index.md` with indexes build by PureBuilder.
16
+
17
+ ## Install
18
+
19
+ ### Install from rubygems.org
20
+
21
+ `gem install pbsimply`
22
+
23
+ ### Manually make Gem
24
+
25
+ * `gem build pbsimply.gemspec`
26
+ * `gem install pbsimply-$version.gem`
27
+
28
+ ### Manually from GitHub
29
+
30
+ * `git clone https://github.com/reasonset/purebuilder-simply`
31
+ * Copy under `bin/` files on your PATH directory.
32
+ * Copy under `lib/` files on your Ruby library directory.
33
+
34
+ ## Dependency
35
+
36
+ * Ruby >= 3.0
37
+ * Pandoc >= 2.8
38
+
39
+ ## Usage
40
+
41
+ ### Create a Project
42
+
43
+ Use `pbsimply-init` to generate a project directory with both the document source root (`Source`) and the document build root (`Build`):
44
+
45
+ ```bash
46
+ pbsimply-init
47
+ ```
48
+
49
+ - You can pass a directory name as an argument.
50
+ - If omitted, the current directory will be used.
51
+ - The directory must be empty.
52
+
53
+ You can also specify a theme for initialization with the `-t` option.
54
+
55
+ ### Build Documents
56
+
57
+ Move into the document source root and run:
58
+
59
+ ```bash
60
+ pbsimply directory
61
+ ```
62
+
63
+ PureBuilder Simply will process the documents in the given directory and output HTML files.
64
+
65
+ ## Documentation
66
+
67
+ For more details, see the [project homepage](https://purebuilder.app/).
data/lib/pbsimply/accs.rb CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  # ACCS namespace.
4
4
  module PBSimply::ACCS
@@ -62,7 +62,7 @@ EOF
62
62
  #
63
63
  # This method called on the assumption that processed all documents and run as directory mode.
64
64
  def process_accs
65
- STDERR.puts "Processing ACCS index..."
65
+ $stderr.puts "Processing ACCS index..."
66
66
  if File.exist?(File.join(@dir, ".accsindex.erb"))
67
67
  erbtemplate = File.read(File.join(@dir, ".accsindex.erb"))
68
68
  elsif File.exist?(".accsindex.erb")
@@ -107,4 +107,4 @@ EOF
107
107
  end
108
108
  process_accs
109
109
  end
110
- end
110
+ end
@@ -0,0 +1,20 @@
1
+ #!/bin/env ruby
2
+
3
+ class PBSimply
4
+ class ConfigChecker
5
+ class InvalidConfigError < StandardError
6
+ end
7
+
8
+ def self.verify_config config
9
+ # blessmethod_accs_rel
10
+ if config["blessmethod_accs_rel"] && ! %w:numbering date timestamp lexical:.include?(config["blessmethod_accs_rel"])
11
+ raise InvalidConfigError.new("blessmethod_accs_rel must be either numbering, date, timestamp or lexical.")
12
+ end
13
+
14
+ # unicode_normalize
15
+ if config["unicode_normalize"] && ! %w:nfc nfd nfkc nfkd:.include?(config["unicode_normalize"])
16
+ raise InvalidConfigError.new("unicode_normalize must be either nfc, nfd, nfkc or nfkd.")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
  require 'yaml'
3
3
 
4
4
  class PBSimply
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
  require 'pbsimply/docengine/pandoc.rb'
3
3
  require 'pbsimply/docengine/rdoc.rb'
4
4
  require 'pbsimply/docengine/misc.rb'
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  class PBSimply
4
4
  module Processor
@@ -30,7 +30,7 @@ class PBSimply
30
30
 
31
31
  # Invoke pandoc, parse and format and write out.
32
32
  def print_fileproc_msg(filename)
33
- STDERR.puts "#{filename} is going Docutils."
33
+ $stderr.puts "#{filename} is going Docutils."
34
34
  end
35
35
 
36
36
  def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
@@ -57,4 +57,4 @@ class PBSimply
57
57
  end
58
58
  end
59
59
  end
60
- end
60
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  class PBSimply
4
4
  module Processor
@@ -15,7 +15,7 @@ class PBSimply
15
15
  end
16
16
 
17
17
  def print_fileproc_msg(filename)
18
- STDERR.puts "#{filename} generate with Redcarpet Markdown"
18
+ $stderr.puts "#{filename} generate with Redcarpet Markdown"
19
19
  end
20
20
 
21
21
  def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
@@ -39,7 +39,7 @@ class PBSimply
39
39
  end
40
40
 
41
41
  def print_fileproc_msg(filename)
42
- STDERR.puts "#{filename} generate with Kramdown"
42
+ $stderr.puts "#{filename} generate with Kramdown"
43
43
  end
44
44
 
45
45
  def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
@@ -66,12 +66,14 @@ class PBSimply
66
66
  end
67
67
 
68
68
  def print_fileproc_msg(filename)
69
- STDERR.puts "#{filename} generate with CommonMarker (cmark-gfm)"
69
+ $stderr.puts "#{filename} generate with CommonMarker (cmark-gfm)"
70
70
  end
71
71
 
72
72
  def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
73
+ options = @config["commonmarker_options"]&.map(&:to_sym) || [:table, :strikethrough]
74
+
73
75
  # Getting HTML string.
74
- article_body = CommonMarker.render_doc(File.read(procdoc), :DEFAULT, [:table, :strikethrough]).to_html
76
+ article_body = CommonMarker.render_doc(File.read(procdoc), :DEFAULT, options).to_html
75
77
 
76
78
  # Process with eRuby temaplte.
77
79
  erb_template = ERB.new(File.read(@config["template"]), trim_mode: '%<>')
@@ -81,4 +83,4 @@ class PBSimply
81
83
  end
82
84
  end
83
85
  end
84
- end
86
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  ###############################################
4
4
  # DOCUMENT PROCESSORS #
@@ -17,7 +17,14 @@ class PBSimply
17
17
  "to" => "html5",
18
18
  "standalone" => true
19
19
  }
20
+
20
21
  super
22
+
23
+ @pandoc_input_extmap = {}
24
+ @config["pandoc_input_ext"]&.each do |k,v|
25
+ key = k[0] == "." ? k : "." + k
26
+ @pandoc_input_extmap[key] = v
27
+ end
21
28
  end
22
29
 
23
30
  def setup_config(dir)
@@ -46,7 +53,7 @@ class PBSimply
46
53
 
47
54
  # Invoke pandoc, parse and format and write out.
48
55
  def print_fileproc_msg(filename)
49
- STDERR.puts "#{filename} is going Pandoc."
56
+ $stderr.puts "#{filename} is going Pandoc."
50
57
  end
51
58
 
52
59
  def process_document(dir, filename, frontmatter, orig_filepath, ext, procdoc)
@@ -58,9 +65,13 @@ class PBSimply
58
65
  # Go Pandoc
59
66
  pandoc_cmdline = [(@config["pandoc_command"] || "pandoc")]
60
67
  pandoc_cmdline += ["-d", @workfile_pandoc_defaultfiles, "--metadata-file", @workfile_frontmatter, "-M", "title:#{frontmatter["title"]}", "-w", "html5"]
61
- pandoc_cmdline += ["-f", frontmatter["input_format"]] if frontmatter["input_format"]
68
+ if frontmatter["input_format"]
69
+ pandoc_cmdline += ["-f", frontmatter["input_format"]]
70
+ elsif @pandoc_input_extmap[File.extname filename]
71
+ pandoc_cmdline += ["-f", @pandoc_input_extmap[File.extname filename]]
72
+ end
62
73
  pandoc_cmdline += [ procdoc ]
63
- pp pandoc_cmdline if ENV["DEBUG"] == "yes"
74
+ pp pandoc_cmdline if @debug
64
75
  IO.popen((pandoc_cmdline)) do |io|
65
76
  doc = io.read
66
77
  end
@@ -74,8 +85,9 @@ class PBSimply
74
85
  end
75
86
 
76
87
  def target_file_extensions
77
- [".md", ".rst"]
88
+ p [".md", ".rst"] + @pandoc_input_extmap.keys
89
+ [".md", ".rst"] + @pandoc_input_extmap.keys
78
90
  end
79
91
  end
80
92
  end
81
- end
93
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  class PBSimply
4
4
  module Processor
@@ -36,7 +36,7 @@ class PBSimply
36
36
  end
37
37
 
38
38
  def print_fileproc_msg(filename)
39
- STDERR.puts "#{filename} generate with RDoc/Markdown"
39
+ $stderr.puts "#{filename} generate with RDoc/Markdown"
40
40
  end
41
41
 
42
42
  def get_markup_document procdoc
@@ -47,7 +47,7 @@ class PBSimply
47
47
  # RDoc processor
48
48
  class PbsRDoc < PbsRBase
49
49
  def print_fileproc_msg(filename)
50
- STDERR.puts "#{filename} generate with RDoc"
50
+ $stderr.puts "#{filename} generate with RDoc"
51
51
  end
52
52
 
53
53
  def get_markup_document procdoc
@@ -59,4 +59,4 @@ class PBSimply
59
59
  end
60
60
  end
61
61
  end
62
- end
62
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
  require 'erb'
3
3
  require 'yaml'
4
4
 
@@ -16,6 +16,14 @@ module PBSimply::Frontmatter
16
16
  # Load standalone metadata YAML.
17
17
  frontmatter = Psych.unsafe_load(File.read(File.join(dir, (".meta." + filename))))
18
18
  pos = 0
19
+ elsif File.exist? File.join(dir, ".meta." + filename + ".yaml")
20
+ # Load standalone metadata YAML with .yaml extension.
21
+ frontmatter = Psych.unsafe_load(File.read(File.join(dir, (".meta." + filename + ".yaml"))))
22
+ pos = 0
23
+ elsif File.exist? File.join(dir, ".meta." + filename + ".yml")
24
+ # Load standalone metadata YAML with .yml extension.
25
+ frontmatter = Psych.unsafe_load(File.read(File.join(dir, (".meta." + filename + ".yaml"))))
26
+ pos = 0
19
27
  else
20
28
 
21
29
  case File.extname filename
@@ -40,7 +48,7 @@ module PBSimply::Frontmatter
40
48
  begin
41
49
  frontmatter = Psych.unsafe_load(lines.join)
42
50
  rescue => e
43
- STDERR.puts "!CRITICAL: Cannot parse frontmatter."
51
+ $stderr.puts "!CRITICAL: Cannot parse frontmatter."
44
52
  raise e
45
53
  end
46
54
 
@@ -110,7 +118,7 @@ module PBSimply::Frontmatter
110
118
  begin
111
119
  frontmatter = Psych.unsafe_load(lines.map {|i| i.sub(/^\s*/, "") }.join)
112
120
  rescue
113
- STDERR.puts "Error in parsing ReST YAML frontmatter (#{$!})"
121
+ $stderr.puts "Error in parsing ReST YAML frontmatter (#{$!})"
114
122
  next
115
123
  end
116
124
  else
@@ -149,12 +157,15 @@ module PBSimply::Frontmatter
149
157
  frontmatter["normalized_docpath"] = absolute_docpath[pwd_length..]
150
158
  # URL in site.
151
159
  this_url = (source_path).sub(/^[\.\/]*/) { @config["self_url_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html")
160
+ this_url_external = (source_path).sub(/^[\.\/]*/) { @config["self_url_external_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html")
161
+ this_url.sub!(%r!/\.([^/]+.html)$!, '/\1')
162
+ this_url_external.sub!(%r!/\.([^/]+.html)$!, '/\1')
152
163
  frontmatter["page_url"] = this_url
153
164
  # URL in site with URI encode.
154
165
  frontmatter["page_url_encoded"] = ERB::Util.url_encode(this_url)
155
- frontmatter["page_url_encoded_external"] = ERB::Util.url_encode((source_path).sub(/^[\.\/]*/) { @config["self_url_external_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html"))
166
+ frontmatter["page_url_encoded_external"] = ERB::Util.url_encode(this_url_external)
156
167
  frontmatter["page_html_escaped"] = ERB::Util.html_escape(this_url)
157
- frontmatter["page_html_escaped_external"] = ERB::Util.html_escape((source_path).sub(/^[\.\/]*/) { @config["self_url_external_prefix"] || "/" }.sub(/\.[a-zA-Z0-9]+$/, ".html"))
168
+ frontmatter["page_html_escaped_external"] = ERB::Util.html_escape(this_url_external)
158
169
  # Title with URL Encoded.
159
170
  frontmatter["title_encoded"] = ERB::Util.url_encode(frontmatter["title"])
160
171
  frontmatter["title_html_escaped"] = ERB::Util.html_escape(frontmatter["title"])
@@ -209,4 +220,4 @@ module PBSimply::Frontmatter
209
220
  ".html"
210
221
  end
211
222
  end
212
- end
223
+ end
@@ -1,8 +1,8 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  # Hooks is new in PureBuilder Simply 2.2.
4
4
  # Hooks object has instance variables for each timing.
5
- #
5
+ #
6
6
  class PBSimply::Hooks
7
7
 
8
8
  # Timing object class.
@@ -29,13 +29,13 @@ class PBSimply::Hooks
29
29
  end
30
30
 
31
31
  def run(arg)
32
- STDERR.puts "Hooks processing (#{@name})"
32
+ $stderr.puts "Hooks processing (#{@name})"
33
33
  @hooks.each_with_index do |proc, index|
34
- STDERR.puts "Hooks[#{index}]"
34
+ $stderr.puts "Hooks[#{index}]"
35
35
  begin
36
36
  proc.(arg)
37
37
  rescue
38
- STDERR.puts "*** HOOKS PROC ERROR ***"
38
+ $stderr.puts "*** HOOKS PROC ERROR ***"
39
39
  raise
40
40
  end
41
41
  end
@@ -71,7 +71,7 @@ class PBSimply::Hooks
71
71
  @pre = HooksHolderPre.new "pre"
72
72
 
73
73
  # Called after document was generated.
74
- #
74
+ #
75
75
  # Argument: outpath, frontmatter, procdoc.
76
76
  # outpath is generated final document path. You can read output result.
77
77
  # procdoc is source document path before generate.
@@ -114,4 +114,4 @@ class PBSimply::Hooks
114
114
  attr :accs
115
115
 
116
116
  attr :config
117
- end
117
+ end
@@ -18,11 +18,11 @@ module PBSimply::Plugger
18
18
  # Porcessing document (same content as source document) path given as first argument.
19
19
  def pre_plugins(procdoc, frontmatter)
20
20
  if File.directory?(".pre_generate")
21
- STDERR.puts("Processing with pre plugins")
21
+ $stderr.puts("Processing with pre plugins")
22
22
  script_file = File.join(".pre_generate", script_file)
23
23
  Dir.entries(".pre_generate").sort.each do |script_file|
24
24
  next if script_file =~ /^\./
25
- STDERR.puts "Running script: #{File.basename script_file}"
25
+ $stderr.puts "Running script: #{File.basename script_file}"
26
26
  pre_script_result = nil
27
27
  script_cmdline = case
28
28
  when File.executable?(script_file)
@@ -45,16 +45,16 @@ module PBSimply::Plugger
45
45
  def post_plugins(frontmatter=nil)
46
46
  if File.directory?(".post_generate")
47
47
 
48
- STDERR.puts("Processing with post plugins")
48
+ $stderr.puts("Processing with post plugins")
49
49
 
50
50
  @this_time_processed.each do |v|
51
- STDERR.puts "Processing #{v[:dest]} (from #{v[:source]})"
51
+ $stderr.puts "Processing #{v[:dest]} (from #{v[:source]})"
52
52
  procdoc = v[:dest]
53
53
  frontmatter ||= @indexes[File.basename v[:source]]
54
- File.open(@workfile_frontmatter, "w") {|f| f.write JSON_LIB.dump(frontmatter)}
54
+ File.open(@workfile_frontmatter, "w") {|f| f.write PBSimply::JSON_LIB.dump(frontmatter)}
55
55
  Dir.entries(".post_generate").sort.each do |script_file|
56
56
  next if script_file =~ /^\./
57
- STDERR.puts "Running script: #{script_file}"
57
+ $stderr.puts "Running script: #{script_file}"
58
58
  script_file = File.join(".post_generate", script_file)
59
59
  post_script_result = nil
60
60
  script_cmdline = case
@@ -74,4 +74,4 @@ module PBSimply::Plugger
74
74
  end
75
75
  end
76
76
  end
77
- end
77
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/ruby
1
+ #!/bin/env ruby
2
2
 
3
3
  # Module for BLESSING feature.
4
4
  module PBSimply::Prayer
@@ -9,14 +9,14 @@ module PBSimply::Prayer
9
9
  bless_ruby frontmatter
10
10
  end
11
11
  end
12
-
12
+
13
13
  def bless_ruby(frontmatter)
14
14
  # BLESSING (Always)
15
15
  if PureBuilder.const_defined?(:BLESS) && Proc === PureBuilder::BLESS
16
16
  begin
17
17
  PureBuilder::BLESS.(frontmatter, self)
18
18
  rescue
19
- STDERR.puts "*** BLESSING PROC ERROR ***"
19
+ $stderr.puts "*** BLESSING PROC ERROR ***"
20
20
  raise
21
21
  end
22
22
  end
@@ -26,7 +26,7 @@ module PBSimply::Prayer
26
26
  begin
27
27
  PureBuilder::ACCS::BLESS.(frontmatter, self)
28
28
  rescue
29
- STDERR.puts "*** ACCS BLESSING PROC ERROR ***"
29
+ $stderr.puts "*** ACCS BLESSING PROC ERROR ***"
30
30
  raise
31
31
  end
32
32
  end
@@ -47,7 +47,7 @@ module PBSimply::Prayer
47
47
  end
48
48
 
49
49
  def bless_cmd(frontmatter)
50
- File.open(@workfile_frontmatter, "w") {|f| f.write JSON_LIB.dump(frontmatter) }
50
+ File.open(@workfile_frontmatter, "w") {|f| f.write PBSimply::JSON_LIB.dump(frontmatter) }
51
51
  # BLESSING (Always)
52
52
  if @config["bless_cmd"]
53
53
  (Array === @config["bless_cmd"] ? system(*@config["bless_cmd"]) : system(@config["bless_cmd"]) ) or abort "*** BLESS COMMAND RETURNS NON-ZERO STATUS"
@@ -104,4 +104,4 @@ module PBSimply::Prayer
104
104
  end
105
105
  end
106
106
  end
107
- end
107
+ end
data/lib/pbsimply.rb CHANGED
@@ -17,6 +17,7 @@ require 'pbsimply/plugger'
17
17
  require 'pbsimply/hooks'
18
18
  require 'pbsimply/frontmatter'
19
19
  require 'pbsimply/accs'
20
+ require 'pbsimply/config-checker.rb'
20
21
 
21
22
  class PBSimply
22
23
  include Prayer
@@ -55,6 +56,9 @@ class PBSimply
55
56
  File.open(".pbsimply.yaml") do |f|
56
57
  config = Psych.unsafe_load(f)
57
58
  end
59
+ ConfigChecker.verify_config config
60
+ rescue PBSimply::ConfigChecker::InvalidConfigError
61
+ abort $!.to_s
58
62
  rescue
59
63
  abort "Failed to load config file (./.pbsimply.yaml)"
60
64
  end
@@ -99,7 +103,7 @@ class PBSimply
99
103
  end
100
104
 
101
105
  unless File.exist? outdir
102
- STDERR.puts "destination directory is not exist. creating (only one step.)"
106
+ $stderr.puts "destination directory is not exist. creating (only one step.)"
103
107
  FileUtils.mkdir_p outdir
104
108
  end
105
109
  end
@@ -120,6 +124,8 @@ class PBSimply
120
124
  @accs_index = {}
121
125
  @now = Time.now
122
126
  @hooks = PBSimply::Hooks.new(self, @config)
127
+
128
+ @debug = (ENV["DEBUG"] == "yes")
123
129
  end
124
130
 
125
131
  # Process command-line
@@ -176,9 +182,9 @@ class PBSimply
176
182
  draft_articles = []
177
183
  target_docs = []
178
184
  @indexes_orig = {}
179
- STDERR.puts "in #{@dir}..."
185
+ $stderr.puts "in #{@dir}..."
180
186
 
181
- STDERR.puts "Checking Frontmatter..."
187
+ $stderr.puts "Checking Frontmatter..."
182
188
  Dir.foreach(@dir) do |filename|
183
189
  next if filename == "." || filename == ".." || filename == ".index.md"
184
190
  if filename =~ /^\./ || filename =~ /^draft-/
@@ -194,7 +200,7 @@ class PBSimply
194
200
  next
195
201
  end
196
202
 
197
- STDERR.puts "Checking frontmatter in #{filename}"
203
+ $stderr.puts "Checking frontmatter in #{filename}"
198
204
  frontmatter, pos = read_frontmatter(@dir, filename)
199
205
  frontmatter = @frontmatter.merge frontmatter
200
206
  frontmatter.merge!(@add_meta) if @add_meta
@@ -235,18 +241,18 @@ class PBSimply
235
241
  def proc_docs target_docs
236
242
  # Exclude unchanged documents.
237
243
  if @indexes && @indexes_orig
238
- STDERR.puts "Checking modification..."
244
+ $stderr.puts "Checking modification..."
239
245
  target_docs.delete_if {|filename, frontmatter, pos| !check_modify(filename, frontmatter)}
240
246
  end
241
247
 
242
248
  # Modify frontmatter `BLESSING'
243
249
  target_docs.each do |filename, frontmatter, pos|
244
- STDERR.puts "Blessing #{filename}..."
250
+ $stderr.puts "Blessing #{filename}..."
245
251
  bless frontmatter
246
252
  end
247
253
 
248
254
  # Ready.
249
- STDERR.puts "Okay, Now ready. Process documents..."
255
+ $stderr.puts "Okay, Now ready. Process documents..."
250
256
 
251
257
  # Proccess documents
252
258
  target_docs.each do |filename, frontmatter, pos|
@@ -256,13 +262,17 @@ class PBSimply
256
262
  @index = frontmatter
257
263
  File.open(File.join(@dir, filename)) do |f|
258
264
  f.seek(pos)
259
- File.open(File.join(@workdir, "current_document#{ext}"), "w") {|fo| fo.write f.read}
265
+ doc_content = f.read
266
+ if @config["unicode_normalize"] && !frontmatter["skip_normalize"]
267
+ doc_content.unicode_normalize!(@config["unicode_normalize"].to_sym)
268
+ end
269
+ File.open(File.join(@workdir, "current_document#{ext}"), "w") {|fo| fo.write doc_content }
260
270
  end
261
271
 
262
- STDERR.puts "Processing #{filename}"
272
+ $stderr.puts "Processing #{filename}"
263
273
  generate(@dir, filename, frontmatter)
264
274
  end
265
-
275
+
266
276
  # Call post plugins
267
277
  post_plugins
268
278
 
@@ -272,13 +282,13 @@ class PBSimply
272
282
 
273
283
  # Delete turn to draft article.
274
284
  def delete_turn_draft draft_articles
275
- STDERR.puts "Checking turn to draft..."
285
+ $stderr.puts "Checking turn to draft..."
276
286
  draft_articles.each do |dah|
277
287
  df = dah[:article_filename]
278
288
  [df, (df + ".html"), File.basename(df, ".*"), (File.basename(df, ".*") + ".html")].each do |tfn|
279
289
  tfp = File.join(@config["outdir"], @dir, tfn)
280
290
  if File.file?(tfp)
281
- STDERR.puts "#{df} was turn to draft."
291
+ $stderr.puts "#{df} was turn to draft."
282
292
  @hooks.delete.run({target_file_path: tfp, source_file_path: dah[:source_file_path]})
283
293
  File.delete tfp if @config["auto_delete"]
284
294
  end
@@ -290,12 +300,12 @@ class PBSimply
290
300
  # Delete missing source
291
301
  def delete_missing
292
302
  return unless @indexes
293
- STDERR.puts "Checking missing article..."
303
+ $stderr.puts "Checking missing article..."
294
304
  missing_keys = []
295
305
  @indexes.each do |k, v|
296
306
  next if !v["source_path"] || !v["dest_path"]
297
307
  unless File.exist? v["source_path"]
298
- STDERR.puts "#{k} is missing."
308
+ $stderr.puts "#{k} is missing."
299
309
  missing_keys.push k
300
310
  @hooks.delete.run({target_file_path: v["dest_path"] ,source_file_path: v["source_path"]})
301
311
  File.delete v["dest_path"] if @config["auto_delete"]
@@ -372,7 +382,7 @@ class PBSimply
372
382
 
373
383
  ##### Post eRuby
374
384
  if @config["post_eruby"]
375
- STDERR.puts "Porcessing with eRuby."
385
+ $stderr.puts "Porcessing with eRuby."
376
386
  doc = ERB.new(doc, nil, "%<>").result(binding)
377
387
  end
378
388
 
@@ -450,14 +460,17 @@ class PBSimply
450
460
 
451
461
 
452
462
  if modify
453
- STDERR.puts "#{filename} last modified at #{frontmatter["_mtime"]}, last processed at #{@indexes_orig[filename]&.[]("_last_proced") || 0}"
463
+ $stderr.puts "#{filename} last modified at #{frontmatter["_mtime"]}, last processed at #{@indexes_orig[filename]&.[]("_last_proced") || 0}"
454
464
  else
455
- STDERR.puts "#{filename} is not modified."
465
+ $stderr.puts "#{filename} is not modified."
456
466
  end
457
467
 
458
468
  frontmatter["_last_proced"] = @now.to_i
459
469
  frontmatter["last_update"] = @now.strftime("%Y-%m-%d %H:%M:%S")
460
470
 
471
+ if frontmatter["skip_update"]
472
+ # Document specific skip update
473
+ false
461
474
  if @refresh
462
475
  # Refresh (force update) mode.
463
476
  true
@@ -57,6 +57,10 @@ self_url_external_prefix: https://example.com/
57
57
  # Delete output file automatically when lose source document.
58
58
  #auto_delete: yes
59
59
  #
60
+ # Unicode normalize in processing document.
61
+ # nfc, nfd, nfkc, nfkd.
62
+ #unicode_normalize: nfkc
63
+ #
60
64
  #################################################
61
65
  # Pandoc engine option
62
66
  #################################################
@@ -74,6 +78,13 @@ self_url_external_prefix: https://example.com/
74
78
  # include-after-body:
75
79
  # - after.html
76
80
  #
81
+ # Add extensions and input formats in Pandoc.
82
+ # The extensions specified here are interpreted as source documents,
83
+ # and the values are used as the values of the -f option in pandoc.
84
+ # pandoc_input_ext:
85
+ # t2t: t2t
86
+ # mw: mediawiki
87
+ # muse: muse
77
88
  #################################################
78
89
  # Kramdown engine option
79
90
  #################################################
@@ -89,6 +100,14 @@ pbsimply_processor: kramdown
89
100
  #redcarpet_extensions: {}
90
101
  #
91
102
  #################################################
103
+ # CommonMarker engine option
104
+ #################################################
105
+ #pbsimply_processor: cmark
106
+ #
107
+ # An array showing `CommonMarker.render_doc`'s 3rd agrument.
108
+ #commonmarker_options: []
109
+ #
110
+ #################################################
92
111
  # Docutils engine option
93
112
  #################################################
94
113
  #pbsimply_processor: docutils
@@ -12,7 +12,10 @@ template: template.html
12
12
  # This values must be *server's URL*.
13
13
  # This settings is not avilable on rdoc, rdoc_markdown, kramdown, redcarpet or cmark engine.
14
14
  css:
15
- - /css/theme.css
15
+ - /css/base.css
16
+ - /css/layout.css
17
+ - /css/lightbox.css
18
+ - /css/skylighting.css
16
19
  # Enable TOC. true or false. false by default.
17
20
  # This settings is not avilable on rdoc, rdoc_markdown, kramdown, redcarpet, cmark or docutils engine.
18
21
  toc: true
@@ -57,6 +60,10 @@ self_url_external_prefix: https://example.com/
57
60
  # Delete output file automatically when lose source document.
58
61
  #auto_delete: yes
59
62
  #
63
+ # Unicode normalize in processing document.
64
+ # nfc, nfd, nfkc, nfkd.
65
+ #unicode_normalize: nfkc
66
+ #
60
67
  #################################################
61
68
  # Pandoc engine option
62
69
  #################################################
@@ -75,6 +82,13 @@ pandoc_additional_options:
75
82
  # include-after-body:
76
83
  # - after.html
77
84
  #
85
+ # Add extensions and input formats in Pandoc.
86
+ # The extensions specified here are interpreted as source documents,
87
+ # and the values are used as the values of the -f option in pandoc.
88
+ # pandoc_input_ext:
89
+ # t2t: t2t
90
+ # mw: mediawiki
91
+ # muse: muse
78
92
  #################################################
79
93
  # Kramdown engine option
80
94
  #################################################
@@ -92,6 +106,14 @@ pandoc_additional_options:
92
106
  #redcarpet_extensions: {}
93
107
  #
94
108
  #################################################
109
+ # CommonMarker engine option
110
+ #################################################
111
+ #pbsimply_processor: cmark
112
+ #
113
+ # An array showing `CommonMarker.render_doc`'s 3rd agrument.
114
+ #commonmarker_options: []
115
+ #
116
+ #################################################
95
117
  # Docutils engine option
96
118
  #################################################
97
119
  #pbsimply_processor: docutils
@@ -104,4 +126,4 @@ pandoc_additional_options:
104
126
  #################################################
105
127
  #pbsimply_processor: rdoc
106
128
  #pbsimply_processor: rdoc_markdown
107
- #pbsimply_processor: cmark
129
+ #pbsimply_processor: cmark
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Old Pandoc themes
3
+ ---
4
+
5
+ These themes are come from PureBuiler Simply 1.x.
@@ -57,6 +57,10 @@ self_url_external_prefix: https://example.com/
57
57
  # Delete output file automatically when lose source document.
58
58
  #auto_delete: yes
59
59
  #
60
+ # Unicode normalize in processing document.
61
+ # nfc, nfd, nfkc, nfkd.
62
+ #unicode_normalize: nfkc
63
+ #
60
64
  #################################################
61
65
  # Pandoc engine option
62
66
  #################################################
@@ -75,6 +79,13 @@ pandoc_additional_options:
75
79
  # include-after-body:
76
80
  # - after.html
77
81
  #
82
+ # Add extensions and input formats in Pandoc.
83
+ # The extensions specified here are interpreted as source documents,
84
+ # and the values are used as the values of the -f option in pandoc.
85
+ # pandoc_input_ext:
86
+ # t2t: t2t
87
+ # mw: mediawiki
88
+ # muse: muse
78
89
  #################################################
79
90
  # Kramdown engine option
80
91
  #################################################
@@ -92,6 +103,14 @@ pandoc_additional_options:
92
103
  #redcarpet_extensions: {}
93
104
  #
94
105
  #################################################
106
+ # CommonMarker engine option
107
+ #################################################
108
+ #pbsimply_processor: cmark
109
+ #
110
+ # An array showing `CommonMarker.render_doc`'s 3rd agrument.
111
+ #commonmarker_options: []
112
+ #
113
+ #################################################
95
114
  # Docutils engine option
96
115
  #################################################
97
116
  #pbsimply_processor: docutils
@@ -104,4 +123,4 @@ pandoc_additional_options:
104
123
  #################################################
105
124
  #pbsimply_processor: rdoc
106
125
  #pbsimply_processor: rdoc_markdown
107
- #pbsimply_processor: cmark
126
+ #pbsimply_processor: cmark
metadata CHANGED
@@ -1,30 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pbsimply
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.1
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaki Haruka
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
- description: Pre compile, static serving website builder.
12
+ description: A flexible, programmable static site generator for Markdown, reStructuredText,
13
+ and RDoc formats. PureBuilder Simply supports both embedded and external content
14
+ processors—including Kramdown, Redcarpet, CommonMarker, RDoc, Pandoc, Docutils—and
15
+ enables customizable conversion workflows and CLI-based project generation.
14
16
  email:
15
17
  - yek@reasonset.net
16
18
  executables:
17
19
  - pbsimply
18
- - pbsimply-testserver
19
20
  - pbsimply-init
21
+ - pbsimply-testserver
20
22
  extensions: []
21
23
  extra_rdoc_files: []
22
24
  files:
25
+ - LICENSE
26
+ - README.md
23
27
  - bin/pbsimply
24
28
  - bin/pbsimply-init
25
29
  - bin/pbsimply-testserver
26
30
  - lib/pbsimply.rb
27
31
  - lib/pbsimply/accs.rb
32
+ - lib/pbsimply/config-checker.rb
28
33
  - lib/pbsimply/docdb.rb
29
34
  - lib/pbsimply/docengine/base.rb
30
35
  - lib/pbsimply/docengine/docutils.rb
@@ -52,6 +57,7 @@ files:
52
57
  - themes/pandoc/_pandoc_base/css/layout.css
53
58
  - themes/pandoc/_pandoc_base/css/lightbox.css
54
59
  - themes/pandoc/_pandoc_base/css/skylightning.css
60
+ - themes/pandoc/_pandoc_base/index.md
55
61
  - themes/pandoc/_pandoc_base/javascript/lightbox.js
56
62
  - themes/pandoc/_pandoc_base/post/.accs.yaml
57
63
  - themes/pandoc/_pandoc_base/post/20231028-untitled.md
@@ -79,11 +85,14 @@ files:
79
85
  - themes/pandoc/practical/css/layout.css
80
86
  - themes/pandoc/warm/.theme.yaml
81
87
  - themes/pandoc/warm/css/base.css
82
- homepage: https://github.com/reasonset/purebuilder-simply
88
+ homepage: https://purebuilder.app/
83
89
  licenses:
84
90
  - Apache-2.0
85
- metadata: {}
86
- post_install_message:
91
+ metadata:
92
+ homepage_uri: https://purebuilder.app/
93
+ source_code_uri: https://github.com/reasonset/purebuilder-simply
94
+ changelog_uri: https://github.com/reasonset/purebuilder-simply/blob/master/CHANGELOG.md
95
+ bug_tracker_uri: https://github.com/reasonset/purebuilder-simply/issues
87
96
  rdoc_options: []
88
97
  require_paths:
89
98
  - lib
@@ -98,8 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
107
  - !ruby/object:Gem::Version
99
108
  version: '0'
100
109
  requirements: []
101
- rubygems_version: 3.5.16
102
- signing_key:
110
+ rubygems_version: 3.6.9
103
111
  specification_version: 4
104
- summary: PureBuiler Simply
112
+ summary: Flexible and programmable static site generator with pluggable Markdown engines
105
113
  test_files: []