jekyll_aspec 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
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: []