giblish 0.8.2 → 2.0.0.pre.alpha1
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/.github/workflows/unit_tests.yml +30 -0
- data/.gitignore +7 -3
- data/.ruby-version +1 -1
- data/Changelog.adoc +59 -0
- data/README.adoc +261 -0
- data/docs/concepts/text_search.adoc +213 -0
- data/docs/concepts/text_search_im/cgi-search_request.puml +35 -0
- data/docs/concepts/text_search_im/cgi-search_request.svg +397 -0
- data/docs/concepts/text_search_im/search_request.puml +40 -0
- data/docs/concepts/text_search_im/search_request.svg +408 -0
- data/docs/howtos/trigger_generation.adoc +180 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/Render Documents.png +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/View Documents.png +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.graphml +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_hooks.svg +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.graphml +0 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/deploy_with_jenkins.svg +0 -0
- data/docs/howtos/trigger_generation_im/docgen_github.puml +51 -0
- data/docs/{setup_server_assets → howtos/trigger_generation_im}/giblish_deployment.graphml +0 -0
- data/docs/howtos/trigger_generation_im/post-receive-example.sh +50 -0
- data/docs/reference/box_flow_spec.adoc +22 -0
- data/docs/reference/search_spec.adoc +185 -0
- data/giblish.gemspec +54 -32
- data/lib/giblish/adocsrc_providers.rb +23 -0
- data/lib/giblish/application.rb +214 -41
- data/lib/giblish/cmdline.rb +273 -259
- data/lib/giblish/config_utils.rb +41 -0
- data/lib/giblish/configurator.rb +163 -0
- data/lib/giblish/conversion_info.rb +120 -0
- data/lib/giblish/docattr_providers.rb +125 -0
- data/lib/giblish/docid/docid.rb +181 -0
- data/lib/giblish/github_trigger/webhook_manager.rb +64 -0
- data/lib/giblish/gitrepos/checkoutmanager.rb +124 -0
- data/lib/giblish/{gititf.rb → gitrepos/gititf.rb} +30 -4
- data/lib/giblish/gitrepos/gitsummary.erb +61 -0
- data/lib/giblish/gitrepos/gitsummaryprovider.rb +78 -0
- data/lib/giblish/gitrepos/history_pb.rb +41 -0
- data/lib/giblish/indexbuilders/d3treegraph.rb +88 -0
- data/lib/giblish/indexbuilders/depgraphbuilder.rb +109 -0
- data/lib/giblish/indexbuilders/dotdigraphadoc.rb +174 -0
- data/lib/giblish/indexbuilders/standard_index.erb +10 -0
- data/lib/giblish/indexbuilders/subtree_indices.rb +132 -0
- data/lib/giblish/indexbuilders/templates/circles.html.erb +111 -0
- data/lib/giblish/indexbuilders/templates/flame.html.erb +61 -0
- data/lib/giblish/indexbuilders/templates/tree.html.erb +366 -0
- data/lib/giblish/indexbuilders/templates/treemap.html.erb +127 -0
- data/lib/giblish/indexbuilders/verbatimtree.rb +94 -0
- data/lib/giblish/pathtree.rb +473 -74
- data/lib/giblish/resourcepaths.rb +150 -0
- data/lib/giblish/search/expand_adoc.rb +55 -0
- data/lib/giblish/search/headingindexer.rb +312 -0
- data/lib/giblish/search/request_manager.rb +110 -0
- data/lib/giblish/search/searchquery.rb +68 -0
- data/lib/giblish/search/textsearcher.rb +349 -0
- data/lib/giblish/subtreeinfobuilder.rb +77 -0
- data/lib/giblish/treeconverter.rb +272 -0
- data/lib/giblish/utils.rb +142 -294
- data/lib/giblish/version.rb +1 -1
- data/lib/giblish.rb +10 -7
- data/scripts/hooks/post-receive.example +66 -0
- data/{docgen/scripts/githook_examples → scripts/hooks}/post-update.example +0 -0
- data/{docgen → scripts}/resources/css/adoc-colony.css +0 -0
- data/scripts/resources/css/giblish-serif.css +419 -0
- data/scripts/resources/css/giblish.css +1979 -419
- data/{docgen → scripts}/resources/fonts/Ubuntu-B.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/Ubuntu-BI.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/Ubuntu-R.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/Ubuntu-RI.ttf +0 -0
- data/{docgen → scripts}/resources/fonts/mplus1p-regular-fallback.ttf +0 -0
- data/{docgen → scripts}/resources/images/giblish_logo.png +0 -0
- data/{docgen → scripts}/resources/images/giblish_logo.svg +0 -0
- data/{docgen → scripts}/resources/themes/giblish.yml +0 -0
- data/scripts/wserv_development.rb +32 -0
- data/web_apps/cgi_search/gibsearch.rb +43 -0
- data/web_apps/gh_webhook_trigger/config.ru +2 -0
- data/web_apps/gh_webhook_trigger/gh_webhook_trigger.rb +73 -0
- data/web_apps/gh_webhook_trigger/public/dummy.txt +3 -0
- data/web_apps/sinatra_search/config.ru +2 -0
- data/web_apps/sinatra_search/public/dummy.txt +3 -0
- data/web_apps/sinatra_search/sinatra_search.rb +34 -0
- data/web_apps/sinatra_search/tmp/restart.txt +0 -0
- metadata +188 -85
- data/.rubocop.yml +0 -7
- data/.travis.yml +0 -3
- data/Changelog +0 -16
- data/Gemfile +0 -4
- data/README.adoc +0 -1
- data/Rakefile +0 -41
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/data/testdocs/malformed/no_header.adoc +0 -5
- data/data/testdocs/toplevel.adoc +0 -19
- data/data/testdocs/wellformed/adorned_purpose.adoc +0 -17
- data/data/testdocs/wellformed/docidtest/docid_1.adoc +0 -24
- data/data/testdocs/wellformed/docidtest/docid_2.adoc +0 -8
- data/data/testdocs/wellformed/simple.adoc +0 -14
- data/data/testdocs/wellformed/source_highlighting/highlight_source.adoc +0 -38
- data/docgen/resources/css/giblish.css +0 -1979
- data/docgen/scripts/Jenkinsfile +0 -18
- data/docgen/scripts/gen_adoc_org.sh +0 -58
- data/docs/README.adoc +0 -387
- data/docs/setup_server.adoc +0 -202
- data/lib/giblish/buildgraph.rb +0 -216
- data/lib/giblish/buildindex.rb +0 -459
- data/lib/giblish/core.rb +0 -451
- data/lib/giblish/docconverter.rb +0 -308
- data/lib/giblish/docid.rb +0 -180
- data/lib/giblish/docinfo.rb +0 -75
- data/lib/giblish/indexheadings.rb +0 -251
- data/lib/giblish-search.cgi +0 -459
- data/scripts/hooks/post-receive +0 -57
- data/scripts/publish_html.sh +0 -99
data/lib/giblish/docconverter.rb
DELETED
@@ -1,308 +0,0 @@
|
|
1
|
-
require "pathname"
|
2
|
-
require "asciidoctor"
|
3
|
-
require "asciidoctor-pdf"
|
4
|
-
|
5
|
-
require_relative "utils"
|
6
|
-
|
7
|
-
module Giblish
|
8
|
-
# Base class for document converters. It contains a hash of
|
9
|
-
# conversion options used by derived classes
|
10
|
-
class DocConverter
|
11
|
-
# a common set of converter options used for all output formats
|
12
|
-
COMMON_CONVERTER_OPTS = {
|
13
|
-
safe: Asciidoctor::SafeMode::UNSAFE,
|
14
|
-
header_footer: true,
|
15
|
-
mkdirs: true
|
16
|
-
}.freeze
|
17
|
-
|
18
|
-
# the giblish attribute defaults used if nothing else
|
19
|
-
# is required by the user
|
20
|
-
DEFAULT_ATTRIBUTES = {
|
21
|
-
"source-highlighter" => "rouge",
|
22
|
-
"xrefstyle" => "short"
|
23
|
-
}.freeze
|
24
|
-
|
25
|
-
# setup common options that are used regardless of the
|
26
|
-
# specific output format used
|
27
|
-
attr_reader :converter_options
|
28
|
-
|
29
|
-
# the path manager used by this converter
|
30
|
-
attr_accessor :paths
|
31
|
-
|
32
|
-
def initialize(paths, deployment_info, options)
|
33
|
-
@paths = paths
|
34
|
-
@deployment_info = deployment_info
|
35
|
-
@user_style = options[:userStyle]
|
36
|
-
@converter_options = COMMON_CONVERTER_OPTS.dup
|
37
|
-
|
38
|
-
# use the default options and override them with options set by
|
39
|
-
# the user if applicable
|
40
|
-
@converter_options[:attributes] = DEFAULT_ATTRIBUTES.dup
|
41
|
-
@converter_options[:attributes].merge!(options[:attributes]) unless options[:attributes].nil?
|
42
|
-
@converter_options[:backend] = options[:backend]
|
43
|
-
|
44
|
-
# give derived classes the opportunity to add options and attributes
|
45
|
-
add_backend_options(@converter_options)
|
46
|
-
add_backend_attributes(@converter_options[:attributes])
|
47
|
-
end
|
48
|
-
|
49
|
-
# Public: Convert one single adoc file using the specific conversion
|
50
|
-
# options.
|
51
|
-
#
|
52
|
-
# filepath - a pathname with the absolute path to the input file to convert
|
53
|
-
#
|
54
|
-
# Returns: The resulting Asciidoctor::Document object
|
55
|
-
def convert(filepath, logger: nil)
|
56
|
-
raise ArgumentError, "Trying to invoke convert with non-pathname!" unless filepath.is_a?(Pathname)
|
57
|
-
|
58
|
-
Giblog.logger.info { "Processing: #{filepath}" }
|
59
|
-
|
60
|
-
# update the relevant options for each specific document
|
61
|
-
set_common_doc_specific_options(filepath, logger)
|
62
|
-
|
63
|
-
# give derived classes the opportunity to set doc specific attributes
|
64
|
-
add_doc_specific_attributes(filepath, true, @converter_options[:attributes])
|
65
|
-
|
66
|
-
Giblog.logger.debug { "converter_options: #{@converter_options}" }
|
67
|
-
|
68
|
-
# do the actual conversion
|
69
|
-
doc = Asciidoctor.convert_file filepath, @converter_options
|
70
|
-
|
71
|
-
# bail out if asciidoctor failed to convert the doc
|
72
|
-
if logger&.max_severity && logger.max_severity > Logger::Severity::WARN
|
73
|
-
raise "Failed to convert the file #{filepath}"
|
74
|
-
end
|
75
|
-
|
76
|
-
doc
|
77
|
-
end
|
78
|
-
|
79
|
-
# converts the supplied string to the file
|
80
|
-
# dst_dir/basename.<backend-ext>
|
81
|
-
#
|
82
|
-
# the supplied string must pass asciidoctor without
|
83
|
-
# any error to stderr, otherwise, nothing will be written
|
84
|
-
# to disk.
|
85
|
-
# Returns: whether any errors occured during conversion (true) or
|
86
|
-
# not (false).
|
87
|
-
def convert_str(src_str, dst_dir, basename, logger: nil)
|
88
|
-
index_opts = @converter_options.dup
|
89
|
-
|
90
|
-
# use the same options as when converting all docs
|
91
|
-
# in the tree but make sure we don't write to file
|
92
|
-
# by trial and error, the following dirs seem to be
|
93
|
-
# necessary to change
|
94
|
-
index_opts[:to_dir] = dst_dir.to_s
|
95
|
-
index_opts[:base_dir] = dst_dir.to_s
|
96
|
-
index_opts.delete_if { |k, _v| %i[to_file].include? k }
|
97
|
-
|
98
|
-
# give derived classes the opportunity to set doc specific attributes
|
99
|
-
index_filepath = dst_dir + "#{basename}.#{index_opts[:fileext]}"
|
100
|
-
add_doc_specific_attributes(index_filepath, false, index_opts[:attributes])
|
101
|
-
|
102
|
-
# load and convert the document using the converter options
|
103
|
-
begin
|
104
|
-
conv_error = false
|
105
|
-
# set a specific logger instance to-be-used by asciidoctor
|
106
|
-
index_opts[:logger] = logger unless logger.nil?
|
107
|
-
doc = Asciidoctor.load src_str, index_opts
|
108
|
-
output = doc.convert index_opts
|
109
|
-
|
110
|
-
if logger&.max_severity && logger.max_severity > Logger::Severity::WARN
|
111
|
-
raise "Failed to convert string to asciidoc!! "\
|
112
|
-
"Will _not_ generate #{index_filepath}"
|
113
|
-
end
|
114
|
-
|
115
|
-
# write the converted document to an index file located at the
|
116
|
-
# destination root
|
117
|
-
doc.write output, index_filepath.to_s
|
118
|
-
rescue StandardError => e
|
119
|
-
puts e.backtrace
|
120
|
-
Giblog.logger.error(e)
|
121
|
-
conv_error = true
|
122
|
-
end
|
123
|
-
|
124
|
-
conv_error
|
125
|
-
end
|
126
|
-
|
127
|
-
protected
|
128
|
-
|
129
|
-
# Hook for specific converters to inject their own options.
|
130
|
-
# The following options must be provided by the derived class:
|
131
|
-
# :fileext - a string with the filename extention to use for the
|
132
|
-
# generated file
|
133
|
-
#
|
134
|
-
# backend_options - the option dict from the backend implementation
|
135
|
-
def add_backend_options(backend_options)
|
136
|
-
@converter_options.merge!(backend_options)
|
137
|
-
end
|
138
|
-
|
139
|
-
# Hook for specific converters to inject their own attributes
|
140
|
-
# valid for all conversions.
|
141
|
-
# backend_attributes - the attribute dict from the backend implementation
|
142
|
-
def add_backend_attributes(backend_attributes)
|
143
|
-
@converter_options[:attributes].merge!(backend_attributes)
|
144
|
-
end
|
145
|
-
|
146
|
-
# Hook for specific converters to inject attributes on a per-doc
|
147
|
-
# basis
|
148
|
-
def add_doc_specific_attributes(filepath, is_src, attributes); end
|
149
|
-
|
150
|
-
private
|
151
|
-
|
152
|
-
def set_common_doc_specific_options(src_filepath, logger)
|
153
|
-
# create an asciidoc doc object and convert to requested
|
154
|
-
# output using current conversion options
|
155
|
-
@converter_options[:to_dir] = @paths.adoc_output_dir(src_filepath).to_s
|
156
|
-
@converter_options[:base_dir] =
|
157
|
-
Giblish::PathManager.closest_dir(src_filepath).to_s
|
158
|
-
@converter_options[:to_file] =
|
159
|
-
Giblish::PathManager.get_new_basename(src_filepath,
|
160
|
-
@converter_options[:fileext])
|
161
|
-
@converter_options[:logger] = logger unless logger.nil?
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
# Converts asciidoc files to html5 output.
|
166
|
-
class HtmlConverter < DocConverter
|
167
|
-
def initialize(paths, deployment_info, options)
|
168
|
-
super paths, deployment_info, options
|
169
|
-
|
170
|
-
# validate that things are ok on the resource front
|
171
|
-
# and copy if needed
|
172
|
-
@dst_asset_dir = @paths.dst_root_abs.join("web_assets")
|
173
|
-
validate_and_copy_resources @dst_asset_dir
|
174
|
-
|
175
|
-
# identify ourselves as an html converter
|
176
|
-
add_backend_options({ backend: "html5", fileext: "html" })
|
177
|
-
# setup the attributes specific for this converter
|
178
|
-
add_backend_attributes(common_attributes)
|
179
|
-
end
|
180
|
-
|
181
|
-
protected
|
182
|
-
|
183
|
-
def add_doc_specific_attributes(filepath, is_src_file, attributes)
|
184
|
-
doc_attrib = {}
|
185
|
-
if @paths.resource_dir_abs
|
186
|
-
# user has given a resource dir, use the css from that dir
|
187
|
-
doc_attrib.merge!(
|
188
|
-
{
|
189
|
-
"linkcss" => 1,
|
190
|
-
"stylesheet" => @user_style ||= "giblish.css",
|
191
|
-
"copycss!" => 1
|
192
|
-
}
|
193
|
-
)
|
194
|
-
if @deployment_info.web_path.nil?
|
195
|
-
# user wants to deploy without web server, the css
|
196
|
-
# link shall thus be the relative path from the
|
197
|
-
# generated doc to the css directory
|
198
|
-
dst_css_dir = @dst_asset_dir.join("css")
|
199
|
-
css_rel_dir = if is_src_file
|
200
|
-
# the filepath is a src path
|
201
|
-
@paths.relpath_to_dir_after_generate(
|
202
|
-
filepath,
|
203
|
-
dst_css_dir
|
204
|
-
)
|
205
|
-
else
|
206
|
-
# the given file path is the destination path of
|
207
|
-
# the generated file, find the relative path to the
|
208
|
-
# css dir
|
209
|
-
dst_dir = PathManager.closest_dir(filepath)
|
210
|
-
dst_css_dir.relative_path_from(dst_dir)
|
211
|
-
end
|
212
|
-
doc_attrib["stylesdir"] = css_rel_dir.to_s
|
213
|
-
else
|
214
|
-
# user has given a web deployment path, the css shall then
|
215
|
-
# be linked using that path
|
216
|
-
doc_attrib["stylesdir"] = @deployment_info.web_path.join("css").cleanpath.to_s
|
217
|
-
end
|
218
|
-
end
|
219
|
-
Giblog.logger.debug { "Rendered docs expect a css at: #{doc_attrib['stylesdir']}" }
|
220
|
-
Giblog.logger.debug { "The expected css is named: #{doc_attrib['stylesheet']}" }
|
221
|
-
|
222
|
-
attributes.merge!(doc_attrib)
|
223
|
-
end
|
224
|
-
|
225
|
-
private
|
226
|
-
|
227
|
-
def common_attributes
|
228
|
-
# Setting 'data-uri' makes asciidoctor embed images in the resulting
|
229
|
-
# html file
|
230
|
-
{
|
231
|
-
"data-uri" => 1
|
232
|
-
}
|
233
|
-
end
|
234
|
-
|
235
|
-
def copy_resource_dir(dst_dir)
|
236
|
-
# create assets_dir and copy everything in the resource dir
|
237
|
-
# to the destination
|
238
|
-
Dir.exist?(dst_dir) || FileUtils.mkdir_p(dst_dir)
|
239
|
-
|
240
|
-
# copy all subdirs that exist in the source tree to the
|
241
|
-
# dst tree
|
242
|
-
%i[css fonts images].each do |dir|
|
243
|
-
src = "#{@paths.resource_dir_abs}/#{dir}"
|
244
|
-
Dir.exist?(src) && FileUtils.copy_entry(src, "#{dst_dir}/#{dir}")
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
# make as sure as we can that the user has given a
|
249
|
-
# directory with valid resources
|
250
|
-
def validate_and_copy_resources(dst_dir)
|
251
|
-
# we don't have a resource path, which is fine, use
|
252
|
-
# defaults
|
253
|
-
return nil unless @paths.resource_dir_abs
|
254
|
-
|
255
|
-
# If user has requested the use of a specific css, use that,
|
256
|
-
# otherwise use asciidoctor default css
|
257
|
-
if @user_style
|
258
|
-
# Make sure that a user supplied stylesheet ends with .css or .CSS
|
259
|
-
@user_style && @user_style =
|
260
|
-
/\.(css|CSS)$/ =~ @user_style ? @user_style : "#{@user_style}.css"
|
261
|
-
|
262
|
-
# bail out if we can not find the given css file
|
263
|
-
src_css_path = @paths.resource_dir_abs
|
264
|
-
.join("css").join(Pathname.new(@user_style))
|
265
|
-
unless src_css_path.exist?
|
266
|
-
raise "Could not find the specified "\
|
267
|
-
"css file at: #{src_css_path}"
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
copy_resource_dir dst_dir
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
# Converts adoc into pdf
|
276
|
-
class PdfConverter < DocConverter
|
277
|
-
def initialize(paths, deployment_info, options)
|
278
|
-
super paths, deployment_info, options
|
279
|
-
require "asciidoctor-mathematical"
|
280
|
-
|
281
|
-
# identify ourselves as a pdf converter
|
282
|
-
add_backend_options({ backend: "pdf", fileext: "pdf" })
|
283
|
-
# setup the attributes specific for this converter
|
284
|
-
add_backend_attributes(setup_pdf_attribs)
|
285
|
-
end
|
286
|
-
|
287
|
-
private
|
288
|
-
|
289
|
-
def setup_pdf_attribs
|
290
|
-
# only set this up if user has specified a resource dir
|
291
|
-
return {} unless @paths.resource_dir_abs
|
292
|
-
|
293
|
-
pdf_attrib = {
|
294
|
-
"pdf-stylesdir" => "#{@paths.resource_dir_abs}/themes",
|
295
|
-
"pdf-style" => "giblish.yml",
|
296
|
-
"pdf-fontsdir" => "#{@paths.resource_dir_abs}/fonts",
|
297
|
-
"icons" => "font"
|
298
|
-
}
|
299
|
-
|
300
|
-
# Make sure that the stylesheet ends with .yml or YML
|
301
|
-
@user_style &&
|
302
|
-
pdf_attrib["pdf-style"] =
|
303
|
-
/\.(yml|YML)$/ =~ @user_style ? @user_style : "#{@user_style}.yml"
|
304
|
-
|
305
|
-
pdf_attrib
|
306
|
-
end
|
307
|
-
end
|
308
|
-
end
|
data/lib/giblish/docid.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
require_relative "./utils"
|
2
|
-
require "asciidoctor"
|
3
|
-
require "asciidoctor/extensions"
|
4
|
-
|
5
|
-
# put docid stuff in the giblish namespace
|
6
|
-
module Giblish
|
7
|
-
# Parse all adoc files for :docid: attributes
|
8
|
-
class DocidCollector < Asciidoctor::Extensions::Preprocessor
|
9
|
-
# Use a class-global docid_cache since asciidoctor creates a new instance
|
10
|
-
# for each preprocessor hook
|
11
|
-
# a hash of {doc_id => Pathname(src_path)}
|
12
|
-
@docid_cache = {}
|
13
|
-
|
14
|
-
# A class-global hash of {src_path => [target doc_ids] }
|
15
|
-
@docid_deps = {}
|
16
|
-
|
17
|
-
class << self
|
18
|
-
attr_reader :docid_cache, :docid_deps
|
19
|
-
|
20
|
-
def clear_cache
|
21
|
-
@docid_cache = {}
|
22
|
-
end
|
23
|
-
|
24
|
-
def clear_deps
|
25
|
-
@docid_deps = {}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# The minimum number of characters required for a valid doc id
|
30
|
-
ID_MIN_LENGTH = 2
|
31
|
-
|
32
|
-
# The maximum number of characters required for a valid doc id
|
33
|
-
ID_MAX_LENGTH = 10
|
34
|
-
|
35
|
-
# Note: I don't know how to hook into the 'initialize' or if I should
|
36
|
-
# let this be, currently it is disabled...
|
37
|
-
# def initialize(*everything)
|
38
|
-
# super(everything)
|
39
|
-
# end
|
40
|
-
|
41
|
-
# Check if a :docid: <id> entry exists in the header.
|
42
|
-
# According to http://www.methods.co.nz/asciidoc/userguide.html#X95
|
43
|
-
# the header is optional, but if it exists it:
|
44
|
-
# - must start with a titel (=+ <My Title>)
|
45
|
-
# - ends with one or more blank lines
|
46
|
-
# - does not contain any blank line
|
47
|
-
def parse_file(path)
|
48
|
-
Giblog.logger.debug { "parsing file #{path} for docid..." }
|
49
|
-
Giblish.process_header_lines_from_file(path) do |line|
|
50
|
-
m = /^:docid: +(.*)$/.match(line)
|
51
|
-
if m
|
52
|
-
# There is a docid defined, cache the path and doc id
|
53
|
-
validate_and_add m[1], path
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# add a new source document to the docid_deps
|
59
|
-
def add_source_dep(src_path)
|
60
|
-
return if docid_deps.key? src_path
|
61
|
-
|
62
|
-
docid_deps[src_path] = []
|
63
|
-
end
|
64
|
-
|
65
|
-
# This hook is called by Asciidoctor once for each document _before_
|
66
|
-
# Asciidoctor processes the adoc content.
|
67
|
-
#
|
68
|
-
# It replaces references of the format <<:docid: ID-1234,Hello >> with
|
69
|
-
# references to a resolved relative path.
|
70
|
-
def process(document, reader)
|
71
|
-
# Add doc as a source dependency for doc ids
|
72
|
-
src_path = document.attributes["docfile"]
|
73
|
-
|
74
|
-
# Note: the nil check is there to prevent us adding generated
|
75
|
-
# asciidoc docs that does not exist in the file system (e.g. the
|
76
|
-
# generated index pages). This is a bit hackish and should maybe be
|
77
|
-
# done differently
|
78
|
-
return if src_path.nil?
|
79
|
-
|
80
|
-
add_source_dep src_path
|
81
|
-
|
82
|
-
# Convert all docid refs to valid relative refs
|
83
|
-
reader.lines.each do |line|
|
84
|
-
line.gsub!(/<<\s*:docid:\s*(.*?)>>/) do |_m|
|
85
|
-
# parse the ref
|
86
|
-
target_id, section, display_str =
|
87
|
-
parse_doc_id_ref Regexp.last_match(1)
|
88
|
-
|
89
|
-
# The result is a valid ref in the form
|
90
|
-
# <<target_doc.adoc#[section][,display_str]>>
|
91
|
-
Giblog.logger.debug { "Replace docid ref in doc #{src_path}..." }
|
92
|
-
if docid_cache.key? target_id
|
93
|
-
# add the referenced doc id as a target dependency of this document
|
94
|
-
docid_deps[src_path] << target_id
|
95
|
-
docid_deps[src_path] = docid_deps[src_path].uniq
|
96
|
-
|
97
|
-
# resolve the doc id ref to a valid relative path
|
98
|
-
"<<#{get_rel_path(src_path, target_id)}##{section}#{display_str}>>"
|
99
|
-
else
|
100
|
-
"<<UNKNOWN_DOC, Could not resolve doc id reference !!!>>"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
reader
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
# Helper method to shorten calls to docid_cache from instance methods
|
110
|
-
def docid_cache
|
111
|
-
self.class.docid_cache
|
112
|
-
end
|
113
|
-
|
114
|
-
def docid_deps
|
115
|
-
self.class.docid_deps
|
116
|
-
end
|
117
|
-
|
118
|
-
# Get the relative path from the src doc to the
|
119
|
-
# doc with the given doc id
|
120
|
-
def get_rel_path(src_path, doc_id)
|
121
|
-
raise ArgumentError("unknown doc id: #{doc_id}") unless docid_cache.key? doc_id
|
122
|
-
|
123
|
-
rel_path = docid_cache[doc_id]
|
124
|
-
.dirname
|
125
|
-
.relative_path_from(Pathname.new(src_path).dirname) +
|
126
|
-
docid_cache[doc_id].basename
|
127
|
-
rel_path.to_s
|
128
|
-
end
|
129
|
-
|
130
|
-
# input_str shall be the expression between
|
131
|
-
# <<:docid:<input_str>>> where the <input_str> is in the form
|
132
|
-
# <id>[#section][,display_str]
|
133
|
-
#
|
134
|
-
# returns an array with [id, section, display_str]
|
135
|
-
def parse_doc_id_ref(input_str)
|
136
|
-
ref, display_str = input_str.split(",").each(&:strip)
|
137
|
-
id, section = ref.split "#"
|
138
|
-
|
139
|
-
display_str = id.dup if display_str.nil?
|
140
|
-
display_str.prepend ","
|
141
|
-
|
142
|
-
section = "" if section.nil?
|
143
|
-
|
144
|
-
[id, section, display_str]
|
145
|
-
end
|
146
|
-
|
147
|
-
# make sure the id is within the designated length and
|
148
|
-
# does not contain a '#' symbol
|
149
|
-
def doc_id_ok?(doc_id)
|
150
|
-
(doc_id.length.between?(ID_MIN_LENGTH, ID_MAX_LENGTH) &&
|
151
|
-
!doc_id.include?("#"))
|
152
|
-
end
|
153
|
-
|
154
|
-
def validate_and_add(doc_id, path)
|
155
|
-
id = doc_id.strip
|
156
|
-
Giblog.logger.debug { "found possible docid: #{id}" }
|
157
|
-
|
158
|
-
unless doc_id_ok? doc_id
|
159
|
-
Giblog.logger.error { "Invalid docid: #{id} in file #{path}, this will be ignored!" }
|
160
|
-
return
|
161
|
-
end
|
162
|
-
|
163
|
-
if docid_cache.key? id
|
164
|
-
Giblog.logger.warn { "Found same doc id twice (#{id})." }
|
165
|
-
Giblog.logger.warn { "Assigning this id to the file #{path}." }
|
166
|
-
Giblog.logger.warn { "Discarding this id from the file #{docid_cache[id]}." }
|
167
|
-
end
|
168
|
-
docid_cache[id] = Pathname(path)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
# Helper method to register the docid preprocessor extension with
|
173
|
-
# the asciidoctor engine.
|
174
|
-
def register_docid_extension
|
175
|
-
Asciidoctor::Extensions.register do
|
176
|
-
preprocessor DocidCollector
|
177
|
-
end
|
178
|
-
end
|
179
|
-
module_function :register_docid_extension
|
180
|
-
end
|
data/lib/giblish/docinfo.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require "pathname"
|
2
|
-
|
3
|
-
module Giblish
|
4
|
-
# Container class for bundling together the data we cache for
|
5
|
-
# each asciidoc file we come across
|
6
|
-
class DocInfo
|
7
|
-
# History info from git
|
8
|
-
class DocHistory
|
9
|
-
attr_accessor :date, :author, :message
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_accessor :converted, :doc_id, :purpose_str, :status, :history, :error_msg, :stderr
|
13
|
-
attr_reader :title, :rel_path, :src_file
|
14
|
-
|
15
|
-
# these members can have encoding issues when
|
16
|
-
# running in a mixed Windows/Linux setting.
|
17
|
-
# that is why we explicitly encodes them when
|
18
|
-
# writing to them
|
19
|
-
|
20
|
-
def title=(rhs)
|
21
|
-
@title = rhs.nil? ? nil : rhs.encode("utf-8")
|
22
|
-
end
|
23
|
-
|
24
|
-
def src_file=(rhs)
|
25
|
-
@src_file = rhs.nil? ? nil : rhs.encode("utf-8")
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize(adoc: nil, dst_root_abs: nil, adoc_stderr: "")
|
29
|
-
@src_file = nil
|
30
|
-
@history = []
|
31
|
-
@converted = true
|
32
|
-
@stderr = adoc_stderr
|
33
|
-
return unless adoc
|
34
|
-
|
35
|
-
# Get the purpose info if it exists
|
36
|
-
@purpose_str = get_purpose_info adoc
|
37
|
-
|
38
|
-
# fill in doc meta data
|
39
|
-
d_attr = adoc.attributes
|
40
|
-
self.src_file = (d_attr["docfile"])
|
41
|
-
self.title = (adoc.doctitle)
|
42
|
-
@doc_id = d_attr["docid"]
|
43
|
-
return if dst_root_abs.nil?
|
44
|
-
|
45
|
-
# Get the relative path beneath the root dir to the doc
|
46
|
-
@rel_path = Pathname.new(
|
47
|
-
"#{d_attr['outdir']}/#{d_attr['docname']}#{d_attr['docfilesuffix']}".encode("utf-8")
|
48
|
-
).relative_path_from(dst_root_abs)
|
49
|
-
end
|
50
|
-
|
51
|
-
def to_s
|
52
|
-
"DocInfo: title: #{@title} src_file: #{@src_file}"
|
53
|
-
end
|
54
|
-
|
55
|
-
private
|
56
|
-
|
57
|
-
def get_purpose_info(adoc)
|
58
|
-
# Get the 'Purpose' section if it exists
|
59
|
-
purpose_str = String.new("")
|
60
|
-
adoc.blocks.each do |section|
|
61
|
-
next unless section.is_a?(Asciidoctor::Section) &&
|
62
|
-
(section.level == 1) &&
|
63
|
-
(section.name =~ /^Purpose$/)
|
64
|
-
|
65
|
-
# filter out 'odd' text, such as lists etc...
|
66
|
-
section.blocks.each do |bb|
|
67
|
-
next unless bb.is_a?(Asciidoctor::Block)
|
68
|
-
|
69
|
-
purpose_str << "#{bb.source}\n+\n"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
purpose_str
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|