giblish 0.6.1 → 0.7.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.
@@ -0,0 +1,58 @@
1
+ #!/bin/bash
2
+ # generates the asciidoctor.org docs to a web server
3
+ # see usage function for usage
4
+
5
+ ### configuration variables
6
+
7
+ # the deployment paths needed by giblish when generating the docs
8
+ uri_path="/adocorg/with_search"
9
+ deployment_dir="/var/www/rillbert_se/adoc/examples/adocorg"
10
+
11
+ # the cgi bin paths on the deployment server
12
+ cgi_dir="/var/www/cgi-bin"
13
+
14
+ ### end of config section
15
+
16
+ function usage() {
17
+ echo ""
18
+ echo "Generates the asciidoctor.org docs to html using giblish and"
19
+ echo "deploys it to the server given by <ssh_host>."
20
+ echo ""
21
+ echo "NOTE: that you most likely need to tweak the deployment paths within this script"
22
+ echo "to your specific situation. See the doc within the script."
23
+ echo ""
24
+ echo "Usage: "
25
+ echo " gen_adoc_org <ssh_host>"
26
+ echo ""
27
+ echo " ssh_host the ssh host including user name (eg user1@my.webserver.com)"
28
+ echo ""
29
+ }
30
+
31
+ # check input variables
32
+ if [ $# -ne 1 ]; then
33
+ echo ""
34
+ echo "ERROR: Wrong number of input arguments !!!"
35
+ usage
36
+ exit 1
37
+ fi
38
+
39
+ # ssh_host="${ssh_user}@${web_server}:"
40
+ ssh_host="$1:"
41
+ html_doc_target="${ssh_host}${deployment_dir}"
42
+ cgi_bin_target="${ssh_host}${cgi_dir}"
43
+
44
+
45
+ # clone the asciidoctor repo
46
+ git clone https://github.com/asciidoctor/asciidoctor.org.git
47
+
48
+ # generate the html docs
49
+ giblish -j '^.*_include.*' -m -mp "${deployment_dir}" -w ${uri_path} -g master --index-basename "myindex" asciidoctor.org/docs ./generated_docs
50
+
51
+ # copy the docs to the web server
52
+ scp -r ./generated_docs/* "${html_doc_target}"
53
+
54
+ # get the path to the search script
55
+ search_script="$(dirname $(gem which giblish))/giblish-search.rb"
56
+
57
+ # copy the script to the cgi-bin on the web server
58
+ scp "${search_script}" "${cgi_bin_target}/giblish-search.cgi"
@@ -12,7 +12,10 @@ Gem::Specification.new do |spec|
12
12
  spec.email = ["anders.rillbert@kutso.se"]
13
13
 
14
14
  spec.summary = "A tool for publishing asciidoc docs stored in git repos"
15
- spec.description = "A tool for publishing asciidoc docs stored in git repos"
15
+ spec.description = <<~EOF
16
+ giblish generates indexed and searchable documents from a tree of
17
+ asciidoc files.
18
+ EOF
16
19
  spec.homepage = "https://github.com/rillbert/giblish"
17
20
  spec.license = "MIT"
18
21
  spec.required_ruby_version = ">= 2.3"
@@ -38,8 +41,8 @@ Gem::Specification.new do |spec|
38
41
  # Usage: spec.add_runtime_dependency "[gem name]", [[version]]
39
42
  spec.add_runtime_dependency "asciidoctor", "~>2.0", ">= 2.0.10"
40
43
  spec.add_runtime_dependency "asciidoctor-diagram", ["~> 1.5"]
41
- spec.add_runtime_dependency "asciidoctor-pdf", [">= 1.5.0.beta.6"]
44
+ spec.add_runtime_dependency "asciidoctor-pdf", [">= 1.5.0.rc.1"]
42
45
  spec.add_runtime_dependency "git", "~> 1.3"
43
46
  spec.add_runtime_dependency "rouge", "~> 3.3"
44
- spec.add_runtime_dependency "prawn-svg", "~> 0.29.1"
47
+ spec.add_runtime_dependency "prawn-svg", "~> 0.30.0"
45
48
  end
@@ -9,7 +9,7 @@ require "uri/generic"
9
9
 
10
10
  class GrepDocTree
11
11
  Line_info = Struct.new(:line, :line_no) {
12
- def initialize(line,line_no)
12
+ def initialize(line, line_no)
13
13
  self.line = line
14
14
  self.line_no = Integer(line_no)
15
15
  end
@@ -22,10 +22,10 @@ class GrepDocTree
22
22
  # :useregexp
23
23
  def initialize(grep_opts)
24
24
  @grep_opts = "-nHr --include '*.adoc' "
25
- @grep_opts += "-i " if grep_opts.has_key? :ignorecase
26
- @grep_opts += "-F " unless grep_opts.has_key? :useregexp
25
+ @grep_opts += "-i " if grep_opts[:ignorecase]
26
+ @grep_opts += "-F " unless grep_opts[:useregexp]
27
27
 
28
- @search_root = grep_opts[:search_top]
28
+ @search_root = grep_opts[:searchassetstop]
29
29
  @input = grep_opts[:search_phrase]
30
30
 
31
31
  @output = ""
@@ -36,7 +36,7 @@ class GrepDocTree
36
36
 
37
37
  def grep
38
38
  # This console code sequence will only show the matching word in bold ms=01:mc=:sl=:cx=:fn=:ln=:bn=:se=
39
- grep_env="GREP_COLORS=\"ms=01:mc=:sl=:cx=:fn=:ln=:bn=:se=\""
39
+ grep_env = "GREP_COLORS=\"ms=01:mc=:sl=:cx=:fn=:ln=:bn=:se=\""
40
40
  @grep_opts += " --color=always"
41
41
 
42
42
 
@@ -44,8 +44,8 @@ class GrepDocTree
44
44
 
45
45
  begin
46
46
  @output.force_encoding(Encoding::UTF_8)
47
- @output.gsub!(/\x1b\[01m\x1b\[K/,"##")
48
- @output.gsub!(/\x1b\[m\x1b\[K/,"##")
47
+ @output.gsub!(/\x1b\[01m\x1b\[K/, "##")
48
+ @output.gsub!(/\x1b\[m\x1b\[K/, "##")
49
49
  rescue StandardError => e
50
50
  print e.message
51
51
  print e.backtrace.inspect
@@ -87,7 +87,7 @@ class GrepDocTree
87
87
  matches = []
88
88
 
89
89
  # for each file with at least one match
90
- @match_index.each do |file_path,match_infos|
90
+ @match_index.each do |file_path, match_infos|
91
91
  # assume that max one file with the specified path
92
92
  # exists
93
93
  files = heading_db["file_infos"].select do |fi|
@@ -97,7 +97,7 @@ class GrepDocTree
97
97
 
98
98
  file_anchors = construct_user_info files.first, match_infos
99
99
  matches << file_anchors
100
- end
100
+ end
101
101
  matches
102
102
  end
103
103
 
@@ -155,7 +155,7 @@ class GrepDocTree
155
155
  def formatted_output
156
156
  # assume we have an updated index
157
157
  adoc_str = ""
158
- @match_index.each do |k,v|
158
+ @match_index.each do |k, v|
159
159
  adoc_str += "#{k}::\n"
160
160
  v.each { |line_info|
161
161
  adoc_str += "#{line_info.line_no} : #{line_info.line}\n"
@@ -177,10 +177,10 @@ class GrepDocTree
177
177
  def grep2hash(base_dir)
178
178
  @match_index = {}
179
179
  @output.split("\n").each do |line|
180
- tokens = line.split(":",3)
180
+ tokens = line.split(":", 3)
181
181
 
182
182
  # remove all lines starting with :<attrib>:
183
- tokens[2].gsub!(/^:[[:graph:]]+:.*$/,"")
183
+ tokens[2].gsub!(/^:[[:graph:]]+:.*$/, "")
184
184
  next if tokens[2].empty?
185
185
 
186
186
  # remove everything above the repo root from the filepath
@@ -198,8 +198,7 @@ class SearchDocTree
198
198
 
199
199
  def search
200
200
  # read the heading_db from file
201
- jsonpath = @input_data[:search_top].join("heading_index.json")
202
- src_index = {}
201
+ jsonpath = @input_data[:searchassetstop].join("heading_index.json")
203
202
  json = File.read(jsonpath.to_s)
204
203
  src_index = JSON.parse(json)
205
204
 
@@ -215,14 +214,14 @@ class SearchDocTree
215
214
  private
216
215
 
217
216
  def get_uri_top
218
- return @input_data[:referer][0,@input_data[:referer].rindex('/')]
217
+ return @input_data[:referer][0, @input_data[:referer].rindex('/')]
219
218
  end
220
219
 
221
220
  def wash_line line
222
221
  # remove any '::'
223
- result = line.gsub(/::*/,"")
222
+ result = line.gsub(/::*/, "")
224
223
  # remove =,| at the start of a line
225
- result.gsub!(/^[=|]+/,"")
224
+ result.gsub!(/^[=|]+/, "")
226
225
  result
227
226
  end
228
227
 
@@ -234,19 +233,19 @@ class SearchDocTree
234
233
  # line_1
235
234
  # line_2
236
235
  # ...
237
- def format_search_adoc index,uri_top
236
+ def format_search_adoc index, uri_top
238
237
  str = ""
239
238
  # debug print referer...
240
239
  # str << "uri_top: #{uri_top}\n"
241
240
  index.each do |file_info|
242
241
  filename = Pathname.new(file_info["filepath"]).basename
243
242
  str << "== #{file_info["title"]}\n\n"
244
- file_info["matches"].each do |section_id, info |
243
+ file_info["matches"].each do |section_id, info|
245
244
  str << "#{uri_top}/#{info["location"]}[#{info["section_title"]}]::\n\n"
246
245
  # str << "<<#{info["location"]},#{info["section_title"]}>>::\n\n"
247
246
  str << "[subs=\"quotes\"]\n"
248
247
  str << "----\n"
249
- info["lines"].each do | line |
248
+ info["lines"].each do |line|
250
249
  str << "-- #{wash_line(line)}\n"
251
250
  end.join("\n\n")
252
251
  str << "----\n"
@@ -255,9 +254,9 @@ class SearchDocTree
255
254
  end
256
255
 
257
256
  <<~ADOC
258
- = Search Result
257
+ = Search Result
259
258
 
260
- #{str}
259
+ #{str}
261
260
  ADOC
262
261
  end
263
262
  end
@@ -271,12 +270,14 @@ def init_web_server web_root
271
270
  server = WEBrick::HTTPServer.new(
272
271
  :Port => 8000,
273
272
  :DocumentRoot => root,
274
- :Logger => WEBrick::Log.new("webrick.log",WEBrick::Log::DEBUG)
273
+ :Logger => WEBrick::Log.new("webrick.log", WEBrick::Log::DEBUG)
275
274
  )
276
275
 
277
276
  puts "WEBrick instance now listening to localhost:8000"
278
277
 
279
- trap 'INT' do server.shutdown end
278
+ trap 'INT' do
279
+ server.shutdown
280
+ end
280
281
 
281
282
  server.start
282
283
  end
@@ -305,110 +306,20 @@ def hello_world
305
306
  print "<br>"
306
307
  end
307
308
 
308
- def cgi_main cgi
309
- # retrieve the form data supplied by user
310
- input_data = {
311
- search_phrase: cgi["searchphrase"],
312
- ignorecase: cgi.has_key?("ignorecase"),
313
- useregexp: cgi.has_key?("useregexp"),
314
- doc_root_abs: Pathname.new(cgi["topdir"]),
315
- referer_rel_top: Pathname.new("#{cgi["reltop"]}"),
316
- referer: cgi.referer,
317
- uri_path: URI(cgi.referer).path,
318
- client_css: cgi["css"],
319
- search_top: nil,
320
- styles_top: nil
321
- }
322
-
323
- # fixup paths depending on git branch or not
324
- #
325
- # search_assets is an absolute path
326
- # styles_top is a relative path
327
- #
328
- # if the source was rendered from a git branch, the paths
329
- # search_assets = <index_dir>/../search_assets/<branch_name>/
330
- # styles_top = ../web_assets/css
331
- #
332
- # and if not, the path is
333
- # search_assets = <index_dir>/search_assets
334
- # styles_top = /web_assets/css
335
- # <link rel="stylesheet" href="/web_assets/css/virodoc.css">
336
- #
337
- if input_data[:doc_root_abs].join("./search_assets").exist?
338
- # this is not from a git branch
339
- input_data[:search_top] = input_data[:doc_root_abs].join("./search_assets")
340
- input_data[:styles_top] = Pathname.new(input_data[:referer_rel_top]).join("web_assets/css")
341
- input_data[:gitbranch] = false
342
- elsif input_data[:doc_root_abs].join("../search_assets").exist?
343
- # this is from a git branch
344
- input_data[:search_top] = input_data[:doc_root_abs].join("../search_assets").join(input_data[:doc_root_abs].basename)
345
- input_data[:styles_top] = Pathname.new(input_data[:referer_rel_top]).join("../web_assets/css")
346
- input_data[:gitbranch] = true
347
- else
348
- raise ScriptError, "Could not find search_assets dir!"
349
- end
350
-
351
- # Set some reasonable default attributes and options
352
- adoc_attributes = {
353
- "data-uri" => 1,
354
- }
355
-
356
- converter_options = {
357
- backend: "html5",
358
- # need this to let asciidoctor include the default css if user
359
- # has not specified any css
360
- safe: Asciidoctor::SafeMode::SAFE,
361
- header_footer: true,
362
- attributes: adoc_attributes
363
- }
364
-
365
- # use a relative stylesheet (same as the index page was rendered with)
366
- # if the script has received input in the client_css form field
367
- if !input_data[:client_css].nil? && !input_data[:client_css].empty?
368
- css_path = if input_data[:styles_top].to_s[0] != '/'
369
- "/" + input_data[:styles_top].to_s
370
- else
371
- input_data[:styles_top].to_s
372
- end
373
- adoc_attributes.merge!({
374
- "linkcss" => 1,
375
- "stylesdir" => css_path,
376
- "stylesheet" => input_data[:client_css],
377
- "copycss!" => 1
378
- })
379
- end
380
309
 
381
- # search the docs and render html
382
- sdt = SearchDocTree.new(input_data)
383
- docstr = sdt.search
384
-
385
- # used for debug purposes
386
- # docstr = <<~EOF
387
- #
388
- # #{input_data[:referer_rel_top]} is branch: #{input_data[:gitbranch]}
389
- #
390
- # #{adoc_attributes.to_s}
310
+ # assume that the file tree looks like this when rendering
311
+ # a git branch:
391
312
  #
392
- #
393
- # #{sdt.search}
394
- # EOF
395
-
396
- # send the result back to the client
397
- print Asciidoctor.convert(docstr, converter_options)
398
- end
399
-
400
- # assume that the file tree looks like this when running
401
- # on a git branch:
402
- #
403
- # dst_root_dir
313
+ # root_dir
314
+ # |- index.html (the generated index of rendered git branches and tags)
404
315
  # |- branch_1_top_dir
405
- # | |- index.html
316
+ # | |- index.html (the generated index of this branch)
406
317
  # | |- file_1.html
407
318
  # | |- dir_1
408
319
  # | | |- file2.html
409
320
  # |- branch_2_top_dir
410
321
  # |- branch_x_...
411
- # |- web_assets
322
+ # |- web_assets (only if a custom stylesheet is used...)
412
323
  # |- search_assets
413
324
  # | |- branch_1_top_dir
414
325
  # | |- heading_index.json
@@ -422,8 +333,8 @@ end
422
333
  # assume that the file tree looks like this when not
423
334
  # rendering a git branch:
424
335
  #
425
- # dst_root_dir
426
- # |- index.html
336
+ # root_dir
337
+ # |- index.html (the generated index of all rendered files)
427
338
  # |- file_1.html
428
339
  # |- dir_1
429
340
  # | |- file2.html
@@ -436,14 +347,83 @@ end
436
347
  # | | |- file2.html
437
348
  # | |- ...
438
349
 
350
+ def cgi_main(cgi, debug_mode = false)
351
+ # retrieve the form data supplied by user
352
+ input_data = {
353
+ search_phrase: cgi["searchphrase"],
354
+ ignorecase: cgi.has_key?("ignorecase"),
355
+ useregexp: cgi.has_key?("useregexp"),
356
+ searchassetstop: Pathname.new(
357
+ cgi.has_key?("searchassetstop") ? cgi["searchassetstop"] : ""),
358
+ webassetstop: Pathname.new(
359
+ cgi.has_key?("webassetstop") ? cgi["webassetstop"] : nil),
360
+ client_css:
361
+ cgi.has_key?("css") ? cgi["css"] : nil,
362
+ referer: cgi.referer
363
+ }
364
+
365
+ if input_data[:searchassetstop].nil? || !Dir.exist?(input_data[:searchassetstop])
366
+ raise ScriptError, "Could not find search_assets dir (#{input_data[:searchassetstop]}) !"
367
+ end
368
+
369
+ adoc_attributes = {
370
+ "data-uri" => 1,
371
+ }
372
+
373
+ # Set attributes so that the generated result page uses the same
374
+ # css as the other docs
375
+ if !input_data[:client_css].nil? && !input_data[:webassetstop].nil?
376
+ adoc_attributes.merge!(
377
+ {
378
+ "linkcss" => 1,
379
+ "stylesdir" => "#{input_data[:webassetstop]}/css",
380
+ "stylesheet" => input_data[:client_css],
381
+ "copycss!" => 1
382
+ }
383
+ )
384
+ end
385
+
386
+ converter_options = {
387
+ backend: "html5",
388
+ # need this to let asciidoctor include the default css if user
389
+ # has not specified any css
390
+ safe: Asciidoctor::SafeMode::SAFE,
391
+ header_footer: true,
392
+ attributes: adoc_attributes
393
+ }
394
+
395
+
396
+ # search the docs and render html
397
+ sdt = SearchDocTree.new(input_data)
398
+ docstr = sdt.search
399
+
400
+ if debug_mode
401
+ # print some useful data for debugging
402
+ docstr = <<~EOF
403
+
404
+ == Input data
405
+
406
+ #{input_data.to_s}
407
+
408
+ == Adoc attributes
409
+
410
+ #{adoc_attributes.to_s}
411
+
412
+ #{docstr}
413
+ EOF
414
+ end
415
+
416
+ # send the result back to the client
417
+ print Asciidoctor.convert(docstr, converter_options)
418
+ end
439
419
 
440
420
 
441
421
  # Usage:
442
422
  # to start a local web server for development work
443
- # giblish-search.rb <web_root>
423
+ # ruby giblish-search.cgi <web_root>
444
424
  #
445
425
  # to run as a cgi script via a previously setup web server
446
- # giblish-search.rb
426
+ # giblish-search.cgi
447
427
  #
448
428
  # (note that you might need to rename the script to eg
449
429
  # giblish-search.cgi or similar depending on your web server
@@ -459,9 +439,11 @@ if __FILE__ == $PROGRAM_NAME
459
439
  cgi = CGI.new
460
440
  print cgi.header
461
441
  begin
462
- cgi_main cgi
442
+ cgi_main(cgi, false)
463
443
  rescue Exception => e
464
444
  print e.message
445
+ print ""
446
+ print e.backtrace
465
447
  exit 1
466
448
  end
467
449
  exit 0