jekyll_aspec 0.0.1.pre

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 01f45e1bf4e7cac463fa045dab24998acf30bf0d
4
+ data.tar.gz: 011c516de7e397f5d4f55b70edacbb2a0214cdf0
5
+ SHA512:
6
+ metadata.gz: 417e6fc6ba196a25f75a318ac2b4ea889481fdbf325472b5513bd4e28cfb6d94afc04e1c2bbc268856b1d1160a44bf8e1fe54f723be342bfa27be9b2717ba6f4
7
+ data.tar.gz: 6bb4fd91bfd8a420b5c83d00911c7ae51e97513cc46b3ab2bae45887049e4257ac66aa852d4a96f62d9d5667f90c66a36405980f48fb68a3ae56674ae0161d8c
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ **/*.html
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in jekyll-aspec.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,26 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jekyll_aspec (0.0.1.pre)
5
+ asciidoctor
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ asciidoctor (1.5.6.1)
11
+ power_assert (1.0.2)
12
+ rake (10.5.0)
13
+ test-unit (3.2.4)
14
+ power_assert
15
+
16
+ PLATFORMS
17
+ ruby
18
+
19
+ DEPENDENCIES
20
+ bundler
21
+ jekyll_aspec!
22
+ rake
23
+ test-unit
24
+
25
+ BUNDLED WITH
26
+ 1.16.0.pre.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 bsmith-n4
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Jekyll Aspec
2
+
3
+ [![Build Status](https://travis-ci.org/bsmith-n4/jekyll_aspec.svg?branch=master)](https://travis-ci.org/bsmith-n4/jekyll_aspec)
4
+
5
+ A selection of Asciidoctor extensions designed to used with Jekyll.
6
+
7
+ These extensions add custom blocks for Requirements, Definitions and inter-document auto-linking functionality for these blocks.
8
+
9
+ ## Installation
10
+
11
+ Add `jekyll_aspec` to your Jekyll Gemfile:
12
+
13
+ ```ruby
14
+ group :jekyll_plugins do
15
+ gem 'jekyll-asciidoc'
16
+ gem 'jekyll_aspec'
17
+ end
18
+ ```
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install jekyll_aspec
23
+
24
+ ## Contributing
25
+
26
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bsmith-n4/jekyll_aspec.
27
+
28
+ ## License
29
+
30
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'test/unit'
3
+
4
+ task :default => :test
5
+
6
+ task :test do
7
+ ruby "test/suite.rb"
8
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "jekyll-aspec"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,27 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "jekyll_aspec/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jekyll_aspec"
8
+ spec.version = JekyllAspec::VERSION
9
+ spec.authors = ["bsmith-n4"]
10
+ spec.email = ["brian.smith@numberfour.eu"]
11
+
12
+ spec.summary = %q{Asciidoctor extensions for use as a Jekyll plugin}
13
+ spec.homepage = "https://github.com/bsmith-n4/jekyll_aspec"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "test-unit"
26
+ spec.add_runtime_dependency "asciidoctor"
27
+ end
@@ -0,0 +1,156 @@
1
+ require 'asciidoctor/extensions'
2
+ require 'pathname'
3
+
4
+ include ::Asciidoctor
5
+
6
+ # Find all Adoc Files
7
+ adoc_files = Dir.glob('**/*.adoc')
8
+ invoc = Dir.pwd
9
+
10
+ # Make some arrays available
11
+ titles = []
12
+ anchors = []
13
+ xrefs = []
14
+ mismatches = []
15
+
16
+ replacement = ''
17
+
18
+ def trim(s)
19
+ s.gsub!(/_docs\//, '')
20
+ s.gsub!(/(\.adoc|\.md|\.html)/, '')
21
+ end
22
+
23
+ def targetify(t)
24
+ # make all chars lowercase and substitute spaces with hyphens
25
+ t.downcase.gsub(/\s/, '-')
26
+ end
27
+
28
+ adoc_files.each do |file_name|
29
+ lc = 0
30
+
31
+ File.read(file_name).each_line do |li|
32
+ lc += 1
33
+
34
+ # Match all <<xrefs>> exluding Requirements
35
+ if li[/\<\<(?!Req)(.+?)\>\>/]
36
+
37
+ text = ''
38
+ target = ''
39
+ path = trim(file_name)
40
+ xref = li.chop.match(/\<\<(?!Req)(\S.+?)\>\>/i).captures[0].to_s
41
+
42
+ if xref[/,/]
43
+ target = xref.downcase.gsub(/,.+/, '').gsub(/\s/, '-')
44
+ text = xref.gsub(/.+,/, '').lstrip!
45
+ xref = xref.sub(/,.+/, '')
46
+ path = file_name
47
+ else
48
+ target = xref.downcase.gsub(/\s/, '-')
49
+ text = xref
50
+ end
51
+
52
+ item = [xref, path, file_name, text, target]
53
+ xrefs.push item
54
+
55
+ # Match .Titles and = Section Titles
56
+ elsif li[/(^(\.\S\w+)|^(\=+\s+?\S+.+))/]
57
+
58
+ # Add check if none found (captures nil)
59
+ title = li.chop.match(/(?!=+\s)(\S+.+?)$/i).captures[0]
60
+ title.sub!(/\.(?=\w+?)/, '') if title[/\.(?=\w+?)/]
61
+ path = trim(file_name)
62
+ item = [title, path, file_name]
63
+ titles.push item
64
+
65
+ # Match [[anchors]]
66
+ elsif li[/\[\[.+?\]\]/]
67
+
68
+ # Add check if none found (captures nil)
69
+ anchor = li.chop.match(/(?<=\[\[).+?(?=\]\])/).to_s
70
+
71
+ if anchor[/,/]
72
+ anchor = anchor.match(/(?<=\[\[)(?:|[\w+?_:][\w+?:.-]*)(?=,.+?\]\])/).to_s
73
+ text = anchor.sub(/.+?,/, '')
74
+ text = text.sub(/\]\]$/, '')
75
+ end
76
+
77
+ path = trim(file_name)
78
+ item = [anchor, path, file_name, text]
79
+ titles.push item
80
+
81
+ end
82
+ end
83
+ end
84
+
85
+ # Run through each xref and check for matching titles
86
+ xrefs.each do |xref, xpath, xfile, xtext, xtarget|
87
+ # check xrefs against titles
88
+ titles.each do |ttext, tpath, tfile, _tdisp|
89
+ # puts "checking #{ttext} against #{xref}"
90
+ next unless ttext == xref
91
+ tpath = 'index' if tpath.to_s.empty?
92
+ # If the paths are not the same (xref and title not the same document) do the following
93
+ next unless tpath != xpath
94
+
95
+ # puts "Title \"#{ttext}\" in #{tfile} - mismatched xref \"#{xref}\" to different doc - #{xpath}"
96
+ xtform = targetify(xtarget)
97
+ detail = [xref, xtarget, xtext, xpath, xfile, ttext, tpath, tfile, xtform]
98
+ mismatches.push detail
99
+ end
100
+ end
101
+
102
+ Extensions.register do
103
+ preprocessor do
104
+ process do |document, reader|
105
+ fixes = []
106
+ i = 0
107
+
108
+ # Block is loaded once per document!!!
109
+ # for each malformed xref
110
+ mismatches.each do |_xref, _xtarget, xtext, _xpath, xfile, _ttext, _tpath, tfile, xtform|
111
+ # FIXME: This directory is empty in POSTS - breaks conversion
112
+ docfile = document.attributes['docfile'].sub(/^#{invoc}\//, '')
113
+ trim(docfile)
114
+
115
+ next unless docfile.to_s == xfile
116
+
117
+ # calculate the relative path between source and target
118
+ first = Pathname.new xfile.to_s
119
+ second = Pathname.new tfile.to_s
120
+ relpath = second.relative_path_from first
121
+
122
+ relpath = relpath.sub(/^\.\.\//, '') if docfile == 'index'
123
+ fix = "#{relpath}/index##{xtform},#{xtext}"
124
+ fixes.push fix
125
+ end
126
+
127
+ Reader.new reader.readlines.map { |li|
128
+ # If the line contains an xref (not to requirements)
129
+ if li[/\<\<(?!Req)(.+?)\>\>/]
130
+
131
+ mismatches.each do |xref, xtarget, xtext, _xpath, _xfile, _ttext, _tpath, _tfile, _relpath|
132
+ # check if the line contains the original xref
133
+
134
+ next unless li[/\<\<#{xref}(,.+)?\>\>/]
135
+ fixes.each do |x|
136
+ if x[/#{xtarget}/]
137
+ t = xref if xtext.to_s.empty?
138
+ replacement = li.sub(/\<\<#{xref}(,.+)?\>\>/, "icon:expand[] <<#{x}#{t}>> ")
139
+ end
140
+ end
141
+ i += 1
142
+ end
143
+
144
+ else
145
+ replacement = ''
146
+ end
147
+
148
+ if replacement.to_s.empty?
149
+ li
150
+ else
151
+ replacement
152
+ end
153
+ }
154
+ end # each document
155
+ end
156
+ end
@@ -0,0 +1,12 @@
1
+ require 'asciidoctor/extensions'
2
+
3
+ include ::Asciidoctor
4
+
5
+ Extensions.register do
6
+ postprocessor do
7
+ process do |document, output|
8
+ output = output.gsub(/<\/p>/, '')
9
+ output
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'asciidoctor/extensions'
2
+
3
+ include ::Asciidoctor
4
+
5
+ Asciidoctor::Extensions.register do
6
+ inline_macro do
7
+ named :call
8
+ process do |parent, target, attrs|
9
+ Asciidoctor::Inline.new(parent, :callout, target.to_i).convert
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,22 @@
1
+ require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
2
+ require_relative 'utils/labels'
3
+ require_relative 'utils/block'
4
+
5
+ include ::Asciidoctor
6
+
7
+ Extensions.register do
8
+ inline_macro do
9
+ named :cwiki
10
+
11
+ process do |parent, target, attrs|
12
+ pattern =
13
+ (parent.document.attr 'cwiki-pattern') ||
14
+ 'https://confluence.numberfour.eu/display/%s'
15
+ url = pattern % target
16
+
17
+ label = Labels.getstatus(attrs)
18
+ html = Context.form(attrs, target, url, label)
19
+ (create_pass_block parent, html, attrs).render
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,80 @@
1
+ require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
2
+
3
+ include ::Asciidoctor
4
+
5
+ # Link to a file on GitHub.
6
+ #
7
+ # repo:<repository>:<file>:<line>[]
8
+ #
9
+ # Examples:
10
+ #
11
+ # repo:dockerfiles:ansible/Dockerfile_template[]
12
+ # repo:dockerfiles:ansible/Dockerfile_template:2[]
13
+ # repo:dockerfiles:ansible/Dockerfile_template:5[branch="AS_v0.0.10"]
14
+ # repo:dockerfiles:ansible/Dockerfile_template[line="5",branch="AS_v0.0.10"]
15
+ #
16
+
17
+ url = ''
18
+ file = ''
19
+ line = ''
20
+ formattedurl = ''
21
+ text = ''
22
+
23
+ Extensions.register do
24
+ inline_macro do
25
+ named :repo
26
+
27
+ process do |parent, target, attrs|
28
+ if parent.context.to_s == 'cell'
29
+ warn %([Hell in a cell] cell with repo link must have 'asciidoc format')
30
+ end
31
+
32
+ repo = target.match(/^.+?(?=:)/).to_s
33
+ file = target.match(/(?<=:).+/).to_s
34
+
35
+ text = file
36
+ text = file.gsub(%r{/.+\//}, '') if file[%r{/\//}]
37
+
38
+ if target[/(?<=:)\d+$/]
39
+ line = "#L#{target.match(/(?<=:)\d+?$/)}"
40
+ file = file.sub(/:\d+$/, '')
41
+ elsif attrs['line']
42
+ line = "#L#{attrs['line']}"
43
+ else
44
+ line = ''
45
+ end
46
+
47
+ if attrs['branch']
48
+ branch = "tree/#{attrs['branch']}"
49
+ text = "#{text} (#{branch})"
50
+ label = 'warning'
51
+ else
52
+ branch = 'blob/master'
53
+ label = 'info'
54
+ end
55
+
56
+ text = attrs['title'].to_s if attrs['title']
57
+ text.gsub!(/:(?=\d+$)/, ' line ') if text[/(?<=:)\d+$/]
58
+
59
+ parent.document.attributes.each do |key, value|
60
+ next unless key[/^repo_/]
61
+ pattern = key.sub(/^repo_/, '')
62
+ if repo == pattern
63
+ formattedurl = "#{value}/#{branch}/#{file}#{line}"
64
+ else
65
+ url = ''
66
+ end
67
+ end
68
+
69
+ html = %(<a href=\"#{formattedurl}\" style=\"padding-right:2px;\">
70
+ <span class=\"label label-#{label}\" style=\"font-weight: 400;
71
+ font-size:smaller;\">
72
+ <i class=\"fa fa-github fa-lg\"></i>
73
+ #{text}
74
+ </span>
75
+ </a>)
76
+
77
+ (create_pass_block parent, html, attrs).render
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,22 @@
1
+ require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
2
+ require_relative 'utils/labels'
3
+ require_relative 'utils/block'
4
+
5
+ include ::Asciidoctor
6
+
7
+ Extensions.register do
8
+ inline_macro do
9
+ named :task
10
+
11
+ process do |parent, target, attrs|
12
+ pattern =
13
+ (parent.document.attr 'task-pattern') ||
14
+ 'https://jira.numberfour.eu/browse/%s'
15
+ url = pattern % target
16
+ # Some utility functions used by similar inline macros
17
+ label = Labels.getstatus(attrs)
18
+ html = Context.form(attrs, target, url, label)
19
+ (create_pass_block parent, html, attrs).render
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ module Jekyll
2
+ # A Liquid Template Filter for using regular expressions
3
+ module RegexFilter
4
+ def replace_regex(input, regex_string, replace_string)
5
+ regex = Regexp.new regex_string
6
+ input.gsub regex, replace_string
7
+ end
8
+ end
9
+ end
10
+
11
+ Liquid::Template.register_filter(Jekyll::RegexFilter)
@@ -0,0 +1,22 @@
1
+ require 'asciidoctor/extensions'
2
+
3
+ include ::Asciidoctor
4
+ # Preprocessor that strips the << tags
5
+ # FIXME: may break conversion if line ends with >>
6
+
7
+ req = '<<req-'
8
+ brackets = /<<|>>/
9
+ repl = ''
10
+
11
+ Extensions.register do
12
+ preprocessor do
13
+ process do |_document, reader|
14
+ return reader if reader.eof?
15
+ replacement_lines = reader.read_lines.map do |line|
16
+ (line.include? req) ? (line.grepl brackets, repl) : line
17
+ end
18
+ reader.unshift_lines replacement_lines
19
+ reader
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,136 @@
1
+ require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal'
2
+
3
+ include ::Asciidoctor
4
+
5
+ adoc_files = Dir.glob('**/*.adoc')
6
+ exts = '(\.adoc|\.md|\.html)'
7
+
8
+ rpath = nil
9
+ rtext = nil
10
+ reqs = []
11
+ inc_reqs = []
12
+ com_reqs = []
13
+ incs = []
14
+ xrefs = []
15
+ xref_base = ''
16
+
17
+ blockrx = %r(^\/{4,}$)
18
+ linerx = %r{^//(?=[^/]|$)}
19
+
20
+ orphan = false
21
+
22
+ # Retrieve this via document attribute
23
+ docsdir = '_docs'
24
+
25
+ def trim(s)
26
+ s.gsub!(/_docs\//, '')
27
+ s.gsub!(/(\.adoc|\.md|\.html)/, '')
28
+ end
29
+
30
+ adoc_files.each do |file_name|
31
+ lc = 0
32
+ inc = false
33
+
34
+ File.read(file_name).each_line do |li|
35
+ lc += 1
36
+
37
+ incommentblock ^= true if li[blockrx]
38
+ commented = true if li[linerx]
39
+ inc = true if li[/published: false/]
40
+
41
+ # Match Requirement Blocks [req,ABC-123,version=n]
42
+ if li[/\[\s*req\s*,\s*id\s*=\s*(\w+-?[0-9]+)\s*,.*/]
43
+
44
+ rid = li.chop.match(/id\s*=\s*\w+-?([0-9]+)/i).captures[0]
45
+ path = file_name.sub(/^#{docsdir}\//, '')
46
+ path = path.sub!(/#{exts}/, '')
47
+ item = [rid, li.chop, path, file_name, lc]
48
+
49
+ if commented || incommentblock
50
+ com_reqs.push item
51
+ elsif inc
52
+ inc_reqs.push item
53
+ else
54
+ reqs.push item
55
+ end
56
+
57
+ # Match all <<xrefs>>
58
+ elsif li[/\<\<\S.+?(\,\S)?\>\>/]
59
+
60
+ xref = li.chop.match(/\<\<(\S.+?)(\,\S)?\>\>/i).captures[0]
61
+ path = file_name.sub(/^#{docsdir}\//, '')
62
+ path = path.sub!(/#{exts}/, '')
63
+ item = [xref, path, file_name, lc]
64
+ xrefs.push item
65
+
66
+ # Collect all includes
67
+ elsif li[/^include::.+.adoc\[\]/]
68
+
69
+ inc_file = li.chop.match(/(?<=^include::).+.adoc(?=\[\])/i).to_s
70
+ path = inc_file.sub(/^#{docsdir}\//, '')
71
+ path = path.sub(/#{exts}/, '')
72
+ parent = file_name
73
+ item = [inc_file, path, parent, lc]
74
+ incs.push item
75
+
76
+ end
77
+ end
78
+ end
79
+
80
+ # Sort included reqs and correct the path to the include parent
81
+ inc_reqs.each do |rid, rli, rpath, _rfile, _rline|
82
+ incs.each do |incfile, incpath, parent, lc|
83
+ next unless rpath == incpath
84
+ trim(parent)
85
+ item = [rid, rli, parent, incfile, lc]
86
+ reqs.push item
87
+ end
88
+ end
89
+
90
+ # Sort (in-place) by numberic ID
91
+ reqs.sort_by!(&:first)
92
+
93
+ Extensions.register do
94
+ inline_macro do
95
+ named :requirement_autoxref
96
+
97
+ # Regex-based, will match "See Req-ROPR-123 for..."
98
+ match /(Req-\w+-?\d+)/
99
+
100
+ # match id with Req-\w+-?(\d+)
101
+ process do |parent, target|
102
+ t = target.sub(/^Req-\w+-?/, '')
103
+
104
+ orphan = true if reqs.empty?
105
+
106
+ reqs.each do |id, text, path, _file_name, _line|
107
+ orphan = false
108
+
109
+ if id == t
110
+ rpath = path
111
+ rtext = text.gsub(/\A\[req,id=/, '')
112
+ rtext = rtext.gsub(/,version=\d\]$/, '')
113
+ break
114
+ else
115
+ orphan = true
116
+ end
117
+ end
118
+
119
+ link = target.sub(/^Req-/, '')
120
+ xref_base = (parent.document.attr 'xref-base')
121
+ uri = "#{xref_base}/#{rpath}/index.html##{link}"
122
+ o = ' <span class=\"label label-info\">'
123
+ c = ' </span>'
124
+
125
+ if orphan
126
+ # docfile = parent.document.attr 'docname'
127
+ # warn %(asciidoctor: WARNING: #{name || node.node_name} orphaned #{target} in #{docfile})
128
+ (create_pass_block parent, %(<strong>#{target}</strong>), {},
129
+ content_model: :raw).convert
130
+ else
131
+ (create_anchor parent, %(#{o} Req. #{rtext} #{c}),
132
+ type: :link, target: uri).convert
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,115 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/extensions'
3
+
4
+ exts = "(\.adoc|\.md|\.html)"
5
+ docsdir = '_docs'
6
+
7
+ title = nil
8
+ chapter = nil
9
+ doctitle = nil
10
+
11
+ reqs = []
12
+ rows = []
13
+ # For commented requirements
14
+ coms = []
15
+
16
+ # For includes
17
+ inc_reqs = []
18
+ incs = []
19
+
20
+ CommentBlockRx = %r(^\/{4,}$)
21
+ CommentLineRx = %r{^//(?=[^/]|$)}
22
+
23
+ def trim(s)
24
+ s.gsub!(/_docs\//, '')
25
+ s.gsub!(/(\.adoc|\.md|\.html)/, '')
26
+ end
27
+
28
+ adoc_files = Dir.glob('**/*.adoc')
29
+ adoc_files.each do |f|
30
+ inc = false
31
+ commented = false
32
+
33
+ File.read(f).each_line do |li|
34
+ incommentblock ^= true if li[CommentBlockRx]
35
+ commented = true if li[CommentLineRx]
36
+ inc = true if li[/published: false/]
37
+
38
+ doctitle = /(?<=title:\s).+/.match(li) if li[/^title:\s+\w.+/]
39
+ chapter = /(?<=chapter:\s).+/.match(li) if li[/^chapter:\s+\w.+/]
40
+
41
+ if li[/\[\s*req\s*,\s*id\s*=\s*\w+-?[0-9]+\s*,.*/]
42
+ title.sub!(/^\./, '')
43
+ req = [li.chop, f, title, chapter, doctitle]
44
+
45
+ if commented || incommentblock
46
+ coms.push(req)
47
+ elsif inc
48
+ inc_reqs.push(req)
49
+ else
50
+ reqs.push(req)
51
+ end
52
+
53
+ # Collect all includes
54
+ elsif li[/^include::.+.adoc\[\]/]
55
+
56
+ inc_file = li.chop.match(/(?<=^include::).+.adoc(?=\[\])/i).to_s
57
+ path = inc_file.sub(/^#{docsdir}\//, '')
58
+ path = path.sub(/#{exts}/, '')
59
+ parent = f
60
+ item = [inc_file, path, parent]
61
+ incs.push item
62
+
63
+ end
64
+ title = li
65
+ end
66
+ end
67
+
68
+ # Sort included reqs and correct the path to the parent (including doc)
69
+ # Push this back into 'normal' requirements array for regular processing
70
+ inc_reqs.each do |l, f, title, chapter, doctitle|
71
+ incs.each do |incfile, _incpath, parent|
72
+ if f == incfile
73
+ item = [l, parent, title, chapter, doctitle]
74
+ reqs.push item
75
+ end
76
+ end
77
+ end
78
+
79
+ reqs.uniq!
80
+
81
+ i = 0
82
+ reqs.each do |req, f, title, chapter, doctitle|
83
+ i += 1
84
+
85
+ id = /[^,]*\s*id\s*=\s*(\w+-?[0-9]+)\s*,.*/.match(req)[1]
86
+ version = /(?<=version=)\d+/.match(req)
87
+
88
+ f.gsub!(/^_docs\//, '')
89
+ f.gsub!(/.adoc$/, '')
90
+
91
+ link = "#{f}/index##{id}"
92
+ ref = "<a class=\"link\" href=\"#{link}\"><emphasis role=\"strong\">#{title}</emphasis> </a>"
93
+ breadcrumb = "<a href=\"#{f}\">#{chapter} / #{doctitle}</a>"
94
+ row = "<tr> <th scope=\"row\">#{i}</th> <td>#{id}</td><td>#{version}</td> <td>#{ref}</td> <td>#{breadcrumb}</td> </tr>"
95
+
96
+ rows.push(row)
97
+ end
98
+
99
+ Asciidoctor::Extensions.register do
100
+ block_macro :requirements do
101
+ process do |parent, _target, _attrs|
102
+ content = %(<h2 id="requirements"><a class="anchor" href="#requirements"></a><a class="link" href="#requirements">Requirements</a></h2>
103
+ <div class="panel panel-default"> <div class="panel-heading"><h4>Requirements</h4></div>
104
+ <table class="table"> <thead> <tr>
105
+ <th>#</th> <th>ID</th><th>Version</th> <th>Title</th> <th>Document</th>
106
+ </tr> </thead>
107
+ <tbody>
108
+ #{rows.join}
109
+ </tbody>
110
+ </table> </div>)
111
+
112
+ create_pass_block parent, content, {}
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,51 @@
1
+ require "asciidoctor/extensions" unless RUBY_ENGINE == "opal"
2
+
3
+ include ::Asciidoctor
4
+
5
+ Extensions.register do
6
+ block do
7
+ named :req
8
+ on_contexts :open, :paragraph, :example, :listing, :sidebar, :pass
9
+ name_positional_attributes "number", "version"
10
+
11
+ process do |parent, reader, attrs|
12
+ # Add pass characters here to prevent html character replacements for < > tags
13
+ pass = "+++"
14
+ attrs["name"] = "requirement"
15
+ attrs["caption"] = "Requirement: "
16
+ id = attrs["id"]
17
+ nl = ""
18
+
19
+ begin
20
+ # downcase the title and replace spaces with underscores.
21
+ # Also replacing special HTML entities:
22
+ # &quot; = "
23
+ # &amp; = &
24
+ downcased_title = attrs["title"].downcase.tr(" ", "_").gsub('"', "&quot;")
25
+ san_title = attrs["title"].gsub(/&/, "&amp;")
26
+ rescue Exception => msg
27
+ puts msg
28
+ # If no title exists on the Req block, throw an exception
29
+ puts "[ERROR] Requirement block title missing"
30
+ end
31
+
32
+ alt = %(
33
+ <div class=\"panel panel-primary\">
34
+ <div class=\"panel-heading\">
35
+ <h3 class=\"panel-title\">
36
+ <a class=\"anchor\" href=\"##{id}\"></a>
37
+ <a class=\"link\" href=\"##{id}\"><emphasis role=\"strong\">Requirement: #{id}:</emphasis> #{san_title} </a> (ver. #{attrs['version']})
38
+ </h3>
39
+ </div>
40
+ <div class=\"panel-body\">)
41
+
42
+ close = "</div></div>"
43
+
44
+ # concatenate all generated lines and prepend before the original content
45
+ concat_lines = reader.lines.unshift(pass, alt, pass, nl)
46
+ concat_lines.push(nl, pass, close, pass)
47
+
48
+ create_block parent, :admonition, concat_lines, attrs, content_model: :compound
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,15 @@
1
+ require "asciidoctor/extensions" unless RUBY_ENGINE == "opal"
2
+
3
+ include ::Asciidoctor
4
+
5
+ class TodoBlock < Extensions::BlockProcessor
6
+ use_dsl
7
+ named :TODO
8
+ on_contexts :open, :paragraph, :example, :listing, :sidebar, :pass
9
+
10
+ def process parent, reader, attrs
11
+ attrs['name'] = 'todo'
12
+ attrs['caption'] = 'Todo'
13
+ create_block parent, :admonition, reader.lines, attrs, content_model: :compound
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Context
2
+ def self.form(attributes, target, url, label)
3
+ block = false
4
+ block = true if attributes.key? "block"
5
+
6
+ if target[0] == "\:"
7
+ block = true
8
+ target[0] = ""
9
+ end
10
+
11
+ if block
12
+ html = "<div style=\"float:right;padding-left:0.1em;\"><a href=\"#{url}\"><span class=\"label label-#{label}\">#{target}</span></a></div>"
13
+ else
14
+ html = "<a href=\"#{url}\"><span class=\"label label-#{label}\">#{target}</span></a>"
15
+ end
16
+ return html
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module Labels
2
+ def self.getstatus(attrs)
3
+ status = attrs["status"]
4
+ if status == ("done" || "closed")
5
+ label = "success"
6
+ elsif status == "open"
7
+ label = "warning"
8
+ else
9
+ status = "unknown"
10
+ label = "default"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module JekyllAspec
2
+ VERSION = "0.0.1.pre"
3
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "extensions/html_postprocessor"
2
+ require_relative "extensions/autoxrefs"
3
+ require_relative "extensions/inline_callout_macro"
4
+ require_relative "extensions/inline_cwiki_macro"
5
+ require_relative "extensions/inline_repo_macro"
6
+ require_relative "extensions/inline_task_macro"
7
+ require_relative "extensions/req_preprocessor"
8
+ require_relative "extensions/req_refs"
9
+ require_relative "extensions/requirement_appendix"
10
+ require_relative "extensions/requirement_block"
11
+ require_relative "extensions/todo_block"
12
+
13
+ require "jekyll_aspec/version"
14
+
15
+ Extensions.register do
16
+ block TodoBlock
17
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll_aspec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre
5
+ platform: ruby
6
+ authors:
7
+ - bsmith-n4
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-09-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: asciidoctor
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - brian.smith@numberfour.eu
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - jekyll_aspec.gemspec
86
+ - lib/extensions/autoxrefs.rb
87
+ - lib/extensions/html_postprocessor.rb
88
+ - lib/extensions/inline_callout_macro.rb
89
+ - lib/extensions/inline_cwiki_macro.rb
90
+ - lib/extensions/inline_repo_macro.rb
91
+ - lib/extensions/inline_task_macro.rb
92
+ - lib/extensions/replace_regex.rb
93
+ - lib/extensions/req_preprocessor.rb
94
+ - lib/extensions/req_refs.rb
95
+ - lib/extensions/requirement_appendix.rb
96
+ - lib/extensions/requirement_block.rb
97
+ - lib/extensions/todo_block.rb
98
+ - lib/extensions/utils/block.rb
99
+ - lib/extensions/utils/labels.rb
100
+ - lib/jekyll_aspec.rb
101
+ - lib/jekyll_aspec/version.rb
102
+ homepage: https://github.com/bsmith-n4/jekyll_aspec
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">"
118
+ - !ruby/object:Gem::Version
119
+ version: 1.3.1
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.6.12
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: Asciidoctor extensions for use as a Jekyll plugin
126
+ test_files: []