giblish 0.2.3 → 0.2.5
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 +4 -4
- data/.rubocop.yml +8 -0
- data/Rakefile +8 -0
- data/data/testdocs/malformed/no_header.adoc +5 -0
- data/data/testdocs/toplevel.adoc +19 -0
- data/data/testdocs/wellformed/docidtest/docid_1.adoc +24 -0
- data/data/testdocs/wellformed/docidtest/docid_2.adoc +8 -0
- data/data/testdocs/wellformed/simple.adoc +14 -0
- data/exe/giblish +1 -1
- data/giblish.gemspec +6 -2
- data/lib/giblish/application.rb +30 -8
- data/lib/giblish/buildindex.rb +3 -3
- data/lib/giblish/cmdline.rb +16 -7
- data/lib/giblish/core.rb +82 -24
- data/lib/giblish/docid.rb +163 -0
- data/lib/giblish/utils.rb +24 -5
- data/lib/giblish/version.rb +1 -1
- data/lib/giblish.rb +1 -1
- data/resources/themes/giblish.yml +2 -2
- metadata +39 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 40b38c28081c397793557e264413ee5929ff6cfc
|
4
|
+
data.tar.gz: 07f92ab1e58fcd19b9584f29dbc9198aa0076108
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 238635d62f4c703c9f0bb86600b7effd1aadadad53d9c8a84d082ec96473ca032e2cf57cc643832b05f8e8b930466a08ecce751c21503cbfe715d63599fcce8f
|
7
|
+
data.tar.gz: 57715ef6f6db7a14215b235aead2d567d025a46c9e810b67b0e249c39e64a89dd6288fc58b83496ecaa3a152e6c453d373652358cff34071b8129505b855001a
|
data/.rubocop.yml
ADDED
data/Rakefile
CHANGED
@@ -7,5 +7,13 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
+
Rake::TestTask.new(:current_test) do |t|
|
11
|
+
t.libs << "test"
|
12
|
+
t.libs << "lib"
|
13
|
+
t.test_files = FileList["test/**/run_test.rb"]
|
14
|
+
# t.test_files = FileList["test/**/docid_test.rb"]
|
15
|
+
end
|
16
|
+
|
17
|
+
|
10
18
|
# task :default => :spec
|
11
19
|
task :default => :test
|
@@ -0,0 +1,19 @@
|
|
1
|
+
= Toplevel document for Giblish test suite
|
2
|
+
:toc: left
|
3
|
+
:docid: GT-001
|
4
|
+
:imagesdir: images
|
5
|
+
:numbered:
|
6
|
+
|
7
|
+
This is the preamble
|
8
|
+
|
9
|
+
== Purpose
|
10
|
+
|
11
|
+
This doc tests some aspects of giblish.
|
12
|
+
|
13
|
+
== Another section
|
14
|
+
|
15
|
+
With some text...
|
16
|
+
|
17
|
+
=== A sub-section
|
18
|
+
|
19
|
+
With some more text...
|
@@ -0,0 +1,24 @@
|
|
1
|
+
= Testing document ids
|
2
|
+
:toc:
|
3
|
+
:docid: WF-013
|
4
|
+
|
5
|
+
== Purpose
|
6
|
+
|
7
|
+
To test the basic functionality of document id references.
|
8
|
+
This paragraph can be referenced as <<:docid:WF-013#Purpose,This paragraph>>.
|
9
|
+
|
10
|
+
Other valid docid references::
|
11
|
+
|
12
|
+
* << :docid:WF-013,Using space before>>
|
13
|
+
* << :docid: WF-013,Using space and tabs>>
|
14
|
+
* <<:docid:WF-013#Testing Document ids>> No title but hash and section.
|
15
|
+
* <<:docid:WF-013>> No title and no hash
|
16
|
+
* <<:docid:WF-022,docid_2 adoc>> Another document within the tree.
|
17
|
+
* <<:docid:WF-001#Purpose>> Reference a section in another document
|
18
|
+
|
19
|
+
Invalid docid references::
|
20
|
+
|
21
|
+
* <<:DOCID:WF-022>> Wrong case
|
22
|
+
* <<:docid:WF-013 No ending signs
|
23
|
+
* <<:docid:WF-0134567890123>> Doc id longer than max chars
|
24
|
+
* <<:docid:W>> Doc id too short
|
@@ -0,0 +1,14 @@
|
|
1
|
+
= A simple Ascidoc document
|
2
|
+
Using the author line as sub-title
|
3
|
+
:toc:
|
4
|
+
:docid: WF-001
|
5
|
+
:imagesdir: images
|
6
|
+
:numbered:
|
7
|
+
|
8
|
+
== Purpose
|
9
|
+
|
10
|
+
To provide a barebone, wellformed asciidoc document.
|
11
|
+
|
12
|
+
== The gist
|
13
|
+
|
14
|
+
This paragraph is the only content.
|
data/exe/giblish
CHANGED
data/giblish.gemspec
CHANGED
@@ -33,6 +33,10 @@ Gem::Specification.new do |spec|
|
|
33
33
|
|
34
34
|
# Usage: spec.add_runtime_dependency "[gem name]", [[version]]
|
35
35
|
spec.add_runtime_dependency "git", "~> 1.3"
|
36
|
-
spec.add_runtime_dependency "asciidoctor", "
|
37
|
-
spec.add_runtime_dependency "asciidoctor-pdf", [">= 1.5.0.alpha.
|
36
|
+
spec.add_runtime_dependency "asciidoctor", "1.5", ">= 1.5.6.1"
|
37
|
+
spec.add_runtime_dependency "asciidoctor-pdf", [">= 1.5.0.alpha.16"]
|
38
|
+
# needed by asciidoctor-pdf, see instructions at
|
39
|
+
# https://github.com/asciidoctor/asciidoctor-pdf/releases
|
40
|
+
spec.add_runtime_dependency "prawn-svg", "0.27", ">= 0.27.1"
|
41
|
+
|
38
42
|
end
|
data/lib/giblish/application.rb
CHANGED
@@ -5,29 +5,51 @@ require_relative "utils"
|
|
5
5
|
|
6
6
|
module Giblish
|
7
7
|
class Application
|
8
|
-
|
8
|
+
|
9
|
+
def run_with_args(args)
|
10
|
+
run args
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_from_cmd_line
|
14
|
+
run ARGV
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(args)
|
9
18
|
# setup logging
|
10
19
|
Giblog.setup
|
11
20
|
|
12
21
|
# Parse cmd line
|
13
|
-
cmdline = CmdLineParser.new
|
22
|
+
cmdline = CmdLineParser.new args
|
14
23
|
|
15
|
-
Giblog.logger.debug { "cmd line args: #{cmdline.args
|
24
|
+
Giblog.logger.debug { "cmd line args: #{cmdline.args}" }
|
16
25
|
|
17
26
|
# Convert using given args
|
18
27
|
begin
|
19
28
|
if cmdline.args[:gitRepoRoot]
|
20
|
-
Giblog.logger.info {"User asked to parse a git repo"}
|
29
|
+
Giblog.logger.info { "User asked to parse a git repo" }
|
21
30
|
GitRepoParser.new cmdline.args
|
22
31
|
else
|
23
32
|
tc = TreeConverter.new cmdline.args
|
24
33
|
tc.walk_dirs
|
25
34
|
end
|
35
|
+
Giblog.logger.info { "Giblish is done!" }
|
26
36
|
rescue Exception => e
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
log_error e
|
38
|
+
exit(1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def log_error(ex)
|
45
|
+
Giblog.logger.error do
|
46
|
+
<<~ERR_MSG
|
47
|
+
Error: #{ex.message}
|
48
|
+
Backtrace:
|
49
|
+
\t#{ex.backtrace.join("\n\t")}
|
50
|
+
|
51
|
+
cmdline.usage
|
52
|
+
ERR_MSG
|
31
53
|
end
|
32
54
|
end
|
33
55
|
end
|
data/lib/giblish/buildindex.rb
CHANGED
@@ -41,6 +41,7 @@ class BasicIndexBuilder
|
|
41
41
|
# set up the basic index building info
|
42
42
|
def initialize(path_manager)
|
43
43
|
@paths = path_manager
|
44
|
+
@nof_missing_titles = 0
|
44
45
|
@added_docs = []
|
45
46
|
@src_str = ""
|
46
47
|
end
|
@@ -305,6 +306,8 @@ end
|
|
305
306
|
class GitRepoIndexBuilder < BasicIndexBuilder
|
306
307
|
def initialize(path_manager, git_repo_root)
|
307
308
|
super path_manager
|
309
|
+
|
310
|
+
# initialize state variables
|
308
311
|
@git_repo_root = git_repo_root
|
309
312
|
|
310
313
|
# no repo root given...
|
@@ -314,9 +317,6 @@ class GitRepoIndexBuilder < BasicIndexBuilder
|
|
314
317
|
# Make sure that we can "talk" to git if user feeds us
|
315
318
|
# a git repo root
|
316
319
|
@git_repo = Git.open(@git_repo_root)
|
317
|
-
|
318
|
-
# initialize state variables
|
319
|
-
@nof_missing_titles = 0
|
320
320
|
rescue Exception => e
|
321
321
|
Giblog.logger.error { "No git repo! exception: #{e.message}" }
|
322
322
|
end
|
data/lib/giblish/cmdline.rb
CHANGED
@@ -51,6 +51,11 @@ class CmdLineParser
|
|
51
51
|
a separate subdir under the destination root dir.
|
52
52
|
-c --local-only do not try to fetch git info from any remotes of the
|
53
53
|
repo before generating documents.
|
54
|
+
-d --resolve-docid use two passes, the first to collect :docid:
|
55
|
+
attributes in the doc headers, the second to
|
56
|
+
generate the documents and use the collected
|
57
|
+
doc ids to resolve relative paths between the
|
58
|
+
generated documents
|
54
59
|
--log-level set the log level explicitly. Must be one of
|
55
60
|
debug, info, warn (default), error or fatal.
|
56
61
|
ENDHELP
|
@@ -60,12 +65,14 @@ ENDHELP
|
|
60
65
|
|
61
66
|
# handle help and version requests
|
62
67
|
if @args[:help]
|
68
|
+
puts USAGE
|
69
|
+
puts ""
|
63
70
|
puts HELP
|
64
|
-
exit
|
71
|
+
exit 0
|
65
72
|
end
|
66
73
|
if @args[:version]
|
67
74
|
puts "Giblish v#{Giblish::VERSION}"
|
68
|
-
exit
|
75
|
+
exit 0
|
69
76
|
end
|
70
77
|
|
71
78
|
# set log level
|
@@ -96,7 +103,7 @@ ENDHELP
|
|
96
103
|
else
|
97
104
|
puts "Invalid log level specified. Run with -h to see supported levels"
|
98
105
|
puts USAGE
|
99
|
-
exit
|
106
|
+
exit 1
|
100
107
|
end
|
101
108
|
end
|
102
109
|
|
@@ -115,6 +122,7 @@ ENDHELP
|
|
115
122
|
flatten: false,
|
116
123
|
suppressBuildRef: false,
|
117
124
|
localRepoOnly: false,
|
125
|
+
resolveDocid: false,
|
118
126
|
webRoot: false
|
119
127
|
}
|
120
128
|
|
@@ -136,9 +144,10 @@ ENDHELP
|
|
136
144
|
when "-g", "--git-branches" then next_arg = :gitBranchRegexp
|
137
145
|
when "-t", "--git-tags" then next_arg = :gitTagRegexp
|
138
146
|
when "-c", "--local-only" then @args[:localRepoOnly] = true
|
147
|
+
when "-d", "--resolve-docid" then @args[:resolveDocid] = true
|
139
148
|
when "-s", "--style" then next_arg = :userStyle
|
140
149
|
when "-w", "--web-root" then next_arg = :webRoot
|
141
|
-
when "--log-level"
|
150
|
+
when "--log-level" then next_arg = :logLevel
|
142
151
|
else
|
143
152
|
if next_arg
|
144
153
|
@args[next_arg] = arg
|
@@ -159,7 +168,7 @@ ENDHELP
|
|
159
168
|
end
|
160
169
|
|
161
170
|
puts USAGE
|
162
|
-
exit
|
171
|
+
exit 1
|
163
172
|
end
|
164
173
|
|
165
174
|
def ensure_required_args
|
@@ -168,7 +177,7 @@ ENDHELP
|
|
168
177
|
|
169
178
|
puts "Error: Too few arguments."
|
170
179
|
puts USAGE
|
171
|
-
exit
|
180
|
+
exit 1
|
172
181
|
end
|
173
182
|
|
174
183
|
def set_gitrepo_root
|
@@ -185,6 +194,6 @@ ENDHELP
|
|
185
194
|
# We should not get here if everything is koscher...
|
186
195
|
puts "Error: Source dir not in a git working dir despite -g or -t option given!"
|
187
196
|
puts USAGE
|
188
|
-
exit
|
197
|
+
exit 1
|
189
198
|
end
|
190
199
|
end
|
data/lib/giblish/core.rb
CHANGED
@@ -13,6 +13,7 @@ require "asciidoctor-pdf"
|
|
13
13
|
|
14
14
|
require_relative "cmdline"
|
15
15
|
require_relative "buildindex"
|
16
|
+
require_relative "docid"
|
16
17
|
|
17
18
|
# Base class for document converters. It contains a hash of
|
18
19
|
# conversion options used by derived classes
|
@@ -42,26 +43,53 @@ class DocConverter
|
|
42
43
|
@converter_options[:backend] = options[:backend]
|
43
44
|
end
|
44
45
|
|
46
|
+
def convert_str(input_str, src_path, output_file = nil)
|
47
|
+
unless input_str.is_a?(String)
|
48
|
+
raise ArgumentError("Trying to invoke convert_str with non-string!")
|
49
|
+
end
|
50
|
+
|
51
|
+
# use the same options as when converting all docs
|
52
|
+
# in the tree but make sure Asciidoctor doesn't write to file
|
53
|
+
index_opts = @converter_options.dup
|
54
|
+
index_opts.delete(:to_file)
|
55
|
+
index_opts.delete(:to_dir)
|
56
|
+
|
57
|
+
# load and convert the string using the converter options
|
58
|
+
doc = Asciidoctor.load input_str, index_opts
|
59
|
+
output = doc.convert index_opts
|
60
|
+
|
61
|
+
# determine the correct output path
|
62
|
+
if output_file.nil?
|
63
|
+
output_file = @paths.adoc_output_file(src_path,
|
64
|
+
@converter_options[:fileext])
|
65
|
+
end
|
66
|
+
|
67
|
+
# write the converted document to file and return the doc
|
68
|
+
doc.write output, output_file.to_s
|
69
|
+
doc
|
70
|
+
end
|
71
|
+
|
45
72
|
# Public: Convert one single adoc file using the specific conversion
|
46
73
|
# options.
|
47
74
|
#
|
48
|
-
# filepath - a
|
75
|
+
# filepath - a pathname with the absolute path to the input file to convert
|
49
76
|
#
|
50
77
|
# Returns: The resulting Asciidoctor::Document object
|
51
78
|
def convert(filepath)
|
79
|
+
unless filepath.is_a?(Pathname)
|
80
|
+
raise ArgumentError, "Trying to invoke convert with non-pathname!"
|
81
|
+
end
|
82
|
+
|
52
83
|
Giblog.logger.info { "Processing: #{filepath}" }
|
53
84
|
|
54
85
|
# create an asciidoc doc object and convert to requested
|
55
86
|
# output using current conversion options
|
56
87
|
@converter_options[:to_dir] = @paths.adoc_output_dir(filepath).to_s
|
57
|
-
@converter_options[:base_dir] =
|
58
|
-
filepath
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@converter_options[:fileext]
|
63
|
-
)
|
64
|
-
|
88
|
+
@converter_options[:base_dir] =
|
89
|
+
Giblish::PathManager.closest_dir(filepath).to_s
|
90
|
+
@converter_options[:to_file] =
|
91
|
+
Giblish::PathManager.get_new_basename(filepath,
|
92
|
+
@converter_options[:fileext])
|
65
93
|
|
66
94
|
Giblog.logger.debug { "converter_options: #{@converter_options}" }
|
67
95
|
# do the actual conversion
|
@@ -160,6 +188,18 @@ class PdfConverter < DocConverter
|
|
160
188
|
def initialize(options)
|
161
189
|
super options
|
162
190
|
|
191
|
+
pdf_attrib = setup_pdf_attribs
|
192
|
+
|
193
|
+
backend_options = { backend: "pdf", fileext: "pdf" }
|
194
|
+
add_backend_options backend_options, pdf_attrib
|
195
|
+
end
|
196
|
+
|
197
|
+
private
|
198
|
+
|
199
|
+
def setup_pdf_attribs()
|
200
|
+
# only set this up if user has specified a resource dir
|
201
|
+
return {} unless @paths.resource_dir_abs
|
202
|
+
|
163
203
|
pdf_attrib = {
|
164
204
|
"pdf-stylesdir" => "#{@paths.resource_dir_abs}/themes",
|
165
205
|
"pdf-style" => "giblish.yml",
|
@@ -172,21 +212,12 @@ class PdfConverter < DocConverter
|
|
172
212
|
pdf_attrib["pdf-style"] =
|
173
213
|
/\.(yml|YML)$/ =~ @user_style ? @user_style : "#{@user_style}.yml"
|
174
214
|
|
175
|
-
|
176
|
-
add_backend_options backend_options, pdf_attrib
|
215
|
+
pdf_attrib
|
177
216
|
end
|
178
217
|
end
|
179
218
|
|
180
219
|
class TreeConverter
|
181
220
|
|
182
|
-
# def init_dst_root
|
183
|
-
# # make sure destination dir exists
|
184
|
-
# Giblog.logger.info do
|
185
|
-
# "Will generate docs to destination root: #{@paths.dst_root_abs}"
|
186
|
-
# end
|
187
|
-
# Dir.exist?(@paths.dst_root_abs) || FileUtils.mkdir_p(@paths.dst_root_abs)
|
188
|
-
# end
|
189
|
-
|
190
221
|
# Required options:
|
191
222
|
# srcDirRoot
|
192
223
|
# dstDirRoot
|
@@ -243,7 +274,7 @@ class TreeConverter
|
|
243
274
|
# do the conversion and capture eventual errors that
|
244
275
|
# the asciidoctor lib writes to stderr
|
245
276
|
adoc_stderr = Giblish.with_captured_stderr do
|
246
|
-
adoc = @conversion.convert
|
277
|
+
adoc = @conversion.convert filepath
|
247
278
|
end
|
248
279
|
|
249
280
|
# build the reference index if the user wants it
|
@@ -251,17 +282,20 @@ class TreeConverter
|
|
251
282
|
rescue Exception => e
|
252
283
|
str = "Error when converting doc: #{e.message}\n"
|
253
284
|
e.backtrace.each { |l| str << "#{l}\n" }
|
254
|
-
Giblog.logger.
|
285
|
+
Giblog.logger.error { str }
|
255
286
|
@options[:suppressBuildRef] || @index_builder.add_doc_fail(filepath, e)
|
256
287
|
end
|
257
288
|
end
|
258
289
|
|
259
290
|
def walk_dirs
|
291
|
+
# pass 1: collect all found doc ids if user wishes
|
292
|
+
collect_doc_ids if @options[:resolveDocid]
|
293
|
+
|
260
294
|
# traverse the src file tree and convert all files that ends with
|
261
295
|
# .adoc or .ADOC
|
262
296
|
Find.find(@paths.src_root_abs) do |path|
|
263
|
-
|
264
|
-
to_asciidoc(
|
297
|
+
p = Pathname.new(path)
|
298
|
+
to_asciidoc(p) if adocfile? p
|
265
299
|
end
|
266
300
|
|
267
301
|
# check if we shall build index or not
|
@@ -274,6 +308,30 @@ class TreeConverter
|
|
274
308
|
@index_builder = nil
|
275
309
|
GC.start
|
276
310
|
end
|
311
|
+
|
312
|
+
private
|
313
|
+
|
314
|
+
def adocfile?(path)
|
315
|
+
path.extname.casecmp(".ADOC").zero?
|
316
|
+
end
|
317
|
+
|
318
|
+
def collect_doc_ids
|
319
|
+
# Register the docid preprocessor hook
|
320
|
+
Giblish.register_extensions
|
321
|
+
|
322
|
+
# Make sure that no prior docid's are hangning around
|
323
|
+
Giblish::DocidCollector.clear_cache
|
324
|
+
idc = Giblish::DocidCollector.new
|
325
|
+
|
326
|
+
# traverse the src file tree and collect ids from all
|
327
|
+
# .adoc or .ADOC files
|
328
|
+
Find.find(@paths.src_root_abs) do |path|
|
329
|
+
p = Pathname.new(path)
|
330
|
+
idc.parse_file(p) if adocfile? p
|
331
|
+
end
|
332
|
+
idc
|
333
|
+
end
|
334
|
+
|
277
335
|
end
|
278
336
|
|
279
337
|
class GitRepoParser
|
@@ -325,7 +383,7 @@ class GitRepoParser
|
|
325
383
|
end
|
326
384
|
end
|
327
385
|
|
328
|
-
# Get the
|
386
|
+
# Get the tags the user wants to parse
|
329
387
|
if options[:gitTagRegexp]
|
330
388
|
regexp = Regexp.new options[:gitTagRegexp]
|
331
389
|
@user_tags = @git_repo.tags.select do |t|
|
@@ -0,0 +1,163 @@
|
|
1
|
+
|
2
|
+
require_relative "./utils.rb"
|
3
|
+
|
4
|
+
require 'asciidoctor'
|
5
|
+
require 'asciidoctor/extensions'
|
6
|
+
|
7
|
+
module Giblish
|
8
|
+
# Parse all adoc files for :docid: attributes
|
9
|
+
class DocidCollector < Asciidoctor::Extensions::Preprocessor
|
10
|
+
# Use a class-global docid_cache since asciidoctor creates a new instance
|
11
|
+
# for each preprocessor hook
|
12
|
+
@docid_cache = {}
|
13
|
+
class << self
|
14
|
+
def docid_cache
|
15
|
+
@docid_cache
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear_cache
|
19
|
+
@docid_cache = {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# The minimum number of characters required for a valid doc id
|
24
|
+
ID_MIN_LENGTH = 2
|
25
|
+
|
26
|
+
# The maximum number of characters required for a valid doc id
|
27
|
+
ID_MAX_LENGTH = 10
|
28
|
+
|
29
|
+
# Note: I don't know how to hook into the 'initialize' or if I should
|
30
|
+
# let this be, currently it is disabled...
|
31
|
+
# def initialize(*everything)
|
32
|
+
# super(everything)
|
33
|
+
# end
|
34
|
+
|
35
|
+
# Helper method that provides the user with a way of processing only the
|
36
|
+
# lines within the asciidoc header block.
|
37
|
+
# The user must return nil to get the next line.
|
38
|
+
#
|
39
|
+
# ex:
|
40
|
+
# process_header_lines(file_path) do |line|
|
41
|
+
# if line == "Quack!"
|
42
|
+
# puts "Donald!"
|
43
|
+
# 1
|
44
|
+
# else
|
45
|
+
# nil
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
def process_header_lines(path)
|
49
|
+
state = "before_header"
|
50
|
+
File.foreach(path) do |line|
|
51
|
+
case state
|
52
|
+
when "before_header" then (state = "in_header" if line =~ /^=+.*$/)
|
53
|
+
when "in_header" then (state = "done" if line =~ /^\s*$/ || yield(line))
|
54
|
+
when "done" then break
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Check if a :docid: <id> entry exists in the header.
|
60
|
+
# According to http://www.methods.co.nz/asciidoc/userguide.html#X95
|
61
|
+
# the header is optional, but if it exists it:
|
62
|
+
# - must start with a titel (=+ <My Title>)
|
63
|
+
# - ends with one or more blank lines
|
64
|
+
# - does not contain any blank line
|
65
|
+
def parse_file(path)
|
66
|
+
Giblog.logger.debug { "parsing file #{path} for docid..." }
|
67
|
+
process_header_lines(path) do |line|
|
68
|
+
m = /^:docid: +(.*)$/.match(line)
|
69
|
+
if m
|
70
|
+
# There is a docid defined, cache the path and doc id
|
71
|
+
validate_and_add m[1], path
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# This hook is called by Asciidoctor once for each document _before_
|
77
|
+
# Asciidoctor processes the adoc content.
|
78
|
+
#
|
79
|
+
# It replaces references of the format <<:docid: ID-1234,Hello >> with
|
80
|
+
# references to a resolved relative path.
|
81
|
+
def process(document, reader)
|
82
|
+
reader.lines.each do |line|
|
83
|
+
line.gsub!(/<<\s*:docid:\s*(.*)>>/) do |_m|
|
84
|
+
replace_doc_id Regexp.last_match(1), document.attributes["docfile"]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
reader
|
88
|
+
end
|
89
|
+
|
90
|
+
def substitute_ids_file(path)
|
91
|
+
substitute_ids(File.read(path), path)
|
92
|
+
end
|
93
|
+
|
94
|
+
def substitute_ids(src_str, src_path)
|
95
|
+
src_str.gsub!(/<<\s*:docid:\s*(.*)>>/) do |_m|
|
96
|
+
replace_doc_id Regexp.last_match(1), src_path
|
97
|
+
end
|
98
|
+
src_str
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# Helper method to shorten calls to docid_cache from instance methods
|
104
|
+
def docid_cache
|
105
|
+
self.class.docid_cache
|
106
|
+
end
|
107
|
+
|
108
|
+
def get_rel_path(src_path, doc_id)
|
109
|
+
return "UNKNOWN_DOC" unless docid_cache.key? doc_id
|
110
|
+
|
111
|
+
rel_path = docid_cache[doc_id]
|
112
|
+
.dirname
|
113
|
+
.relative_path_from(Pathname.new(src_path).dirname) +
|
114
|
+
docid_cache[doc_id].basename
|
115
|
+
rel_path.to_s
|
116
|
+
end
|
117
|
+
|
118
|
+
# The input string shall contain the expression between
|
119
|
+
# <<:docid:<input_str>>> where the <input_str> is in the form
|
120
|
+
# <id>[#section][,display_str]
|
121
|
+
#
|
122
|
+
# The result shall be a valid ref in the form
|
123
|
+
# <<target_doc.adoc#[section][,display_str]>>
|
124
|
+
def replace_doc_id(input_str, src_path)
|
125
|
+
ref, display_str = input_str.split(",").each(&:strip)
|
126
|
+
display_str = "" if display_str.nil?
|
127
|
+
display_str.prepend "," if display_str.length.positive?
|
128
|
+
|
129
|
+
id, section = ref.split "#"
|
130
|
+
section = "" if section.nil?
|
131
|
+
|
132
|
+
Giblog.logger.debug { "Replace docid ref in doc #{src_path}..." }
|
133
|
+
"<<#{get_rel_path(src_path, id)}##{section}#{display_str}>>"
|
134
|
+
end
|
135
|
+
|
136
|
+
def validate_and_add(doc_id, path)
|
137
|
+
id = doc_id.strip
|
138
|
+
Giblog.logger.debug { "found possible docid: #{id}" }
|
139
|
+
|
140
|
+
# make sure the id is within the designated length and
|
141
|
+
# does not contain a '#' symbol
|
142
|
+
if id.length.between?(ID_MIN_LENGTH, ID_MAX_LENGTH) &&
|
143
|
+
!id.include?("#")
|
144
|
+
# the id is ok
|
145
|
+
if docid_cache.key? id
|
146
|
+
Giblog.logger.warn { "Found same doc id twice (#{id}). Using last found id."}
|
147
|
+
end
|
148
|
+
docid_cache[id] = Pathname(path)
|
149
|
+
else
|
150
|
+
Giblog.logger.error { "Invalid docid: #{id}, this will be ignored!" }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Helper method to register the docid preprocessor extension with
|
156
|
+
# the asciidoctor engine.
|
157
|
+
def register_extensions
|
158
|
+
Asciidoctor::Extensions.register do
|
159
|
+
preprocessor DocidCollector
|
160
|
+
end
|
161
|
+
end
|
162
|
+
module_function :register_extensions
|
163
|
+
end
|
data/lib/giblish/utils.rb
CHANGED
@@ -4,15 +4,19 @@ require "fileutils"
|
|
4
4
|
|
5
5
|
class Giblog
|
6
6
|
def self.setup
|
7
|
-
if @logger
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
7
|
+
return if defined? @logger
|
8
|
+
@logger = Logger.new(STDOUT)
|
9
|
+
@logger.formatter = proc do |_severity, datetime, _progname, msg|
|
10
|
+
"#{datetime.strftime('%H:%M:%S')} - #{msg}\n"
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
15
14
|
def self.logger
|
15
|
+
unless defined? @logger
|
16
|
+
puts "!!!! Error: Trying to access logger before setup !!!!"
|
17
|
+
puts caller
|
18
|
+
exit
|
19
|
+
end
|
16
20
|
@logger
|
17
21
|
end
|
18
22
|
end
|
@@ -61,6 +65,21 @@ module Giblish
|
|
61
65
|
src_abs.relative_path_from(@src_root_abs)
|
62
66
|
end
|
63
67
|
|
68
|
+
def adoc_output_file(infile_path, extension)
|
69
|
+
# Get absolute source dir path
|
70
|
+
src_dir_abs = self.class.closest_dir infile_path
|
71
|
+
|
72
|
+
# Get relative path from source root dir
|
73
|
+
src_dir_rel = src_dir_abs.relative_path_from(@src_root_abs)
|
74
|
+
|
75
|
+
# Get the destination path relative the absolute source
|
76
|
+
# root
|
77
|
+
dst_dir_abs = @dst_root_abs.realpath.join(src_dir_rel)
|
78
|
+
|
79
|
+
# return full file path with correct extension
|
80
|
+
dst_dir_abs + get_new_basename(infile_path, extension)
|
81
|
+
end
|
82
|
+
|
64
83
|
# Public: Get the path to the directory where to generate the given
|
65
84
|
# file. The path is given as the relative path from the source adoc
|
66
85
|
# file to the desired output directory (required by the Asciidoctor
|
data/lib/giblish/version.rb
CHANGED
data/lib/giblish.rb
CHANGED
@@ -245,14 +245,14 @@ thematic_break:
|
|
245
245
|
margin_bottom: $vertical_rhythm * 2.5
|
246
246
|
description_list:
|
247
247
|
term_font_style: bold
|
248
|
-
term_font_color: $
|
248
|
+
term_font_color: $primecolor
|
249
249
|
term_spacing: $vertical_rhythm / 4
|
250
250
|
description_indent: $horizontal_rhythm * 1.25
|
251
251
|
outline_list:
|
252
252
|
indent: $horizontal_rhythm * 1.5
|
253
253
|
# NOTE item_spacing applies to list items that do not have complex content
|
254
254
|
item_spacing: $vertical_rhythm / 4
|
255
|
-
marker_font_color: $
|
255
|
+
marker_font_color: $primecolor
|
256
256
|
table:
|
257
257
|
border_color: $primecolor
|
258
258
|
border_width: $base_border_width * 0.25
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: giblish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anders Rillbert
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,30 +70,56 @@ dependencies:
|
|
70
70
|
name: asciidoctor
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '1.5'
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.5.6.1
|
76
79
|
type: :runtime
|
77
80
|
prerelease: false
|
78
81
|
version_requirements: !ruby/object:Gem::Requirement
|
79
82
|
requirements:
|
80
|
-
- -
|
83
|
+
- - '='
|
81
84
|
- !ruby/object:Gem::Version
|
82
85
|
version: '1.5'
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.5.6.1
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
90
|
name: asciidoctor-pdf
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
86
92
|
requirements:
|
87
93
|
- - ">="
|
88
94
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.5.0.alpha.
|
95
|
+
version: 1.5.0.alpha.16
|
90
96
|
type: :runtime
|
91
97
|
prerelease: false
|
92
98
|
version_requirements: !ruby/object:Gem::Requirement
|
93
99
|
requirements:
|
94
100
|
- - ">="
|
95
101
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.5.0.alpha.
|
102
|
+
version: 1.5.0.alpha.16
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: prawn-svg
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - '='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.27'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.27.1
|
113
|
+
type: :runtime
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - '='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0.27'
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 0.27.1
|
97
123
|
description: TBD...
|
98
124
|
email:
|
99
125
|
- anders.rillbert@kutso.se
|
@@ -103,12 +129,18 @@ extensions: []
|
|
103
129
|
extra_rdoc_files: []
|
104
130
|
files:
|
105
131
|
- ".gitignore"
|
132
|
+
- ".rubocop.yml"
|
106
133
|
- Gemfile
|
107
134
|
- LICENSE
|
108
135
|
- README.adoc
|
109
136
|
- Rakefile
|
110
137
|
- bin/console
|
111
138
|
- bin/setup
|
139
|
+
- data/testdocs/malformed/no_header.adoc
|
140
|
+
- data/testdocs/toplevel.adoc
|
141
|
+
- data/testdocs/wellformed/docidtest/docid_1.adoc
|
142
|
+
- data/testdocs/wellformed/docidtest/docid_2.adoc
|
143
|
+
- data/testdocs/wellformed/simple.adoc
|
112
144
|
- exe/giblish
|
113
145
|
- giblish.gemspec
|
114
146
|
- lib/giblish.rb
|
@@ -116,6 +148,7 @@ files:
|
|
116
148
|
- lib/giblish/buildindex.rb
|
117
149
|
- lib/giblish/cmdline.rb
|
118
150
|
- lib/giblish/core.rb
|
151
|
+
- lib/giblish/docid.rb
|
119
152
|
- lib/giblish/pathtree.rb
|
120
153
|
- lib/giblish/utils.rb
|
121
154
|
- lib/giblish/version.rb
|