asciidoctor-defmastership 1.0.10 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50c94ef32fb04c7d26f51b2bf66bacc22cc769c9d242087dbea838c6e29abc89
4
- data.tar.gz: bbb7d84ab7db8e26f64f5eca89b724699f8dd89417fbf0015dbaf84081fbaefd
3
+ metadata.gz: '0093ece719f43a0ffb350e2b5e76072a2e3d964f176dc94fef8bf4ede6931409'
4
+ data.tar.gz: 32c7fef0e23be93c1ee75b3cf0a38ddbb4e1f55750c4bcff51b820a2dbcf1b57
5
5
  SHA512:
6
- metadata.gz: 85733bd136c5df20ae5d6003fa651fe418ca4038e0069c47edbe32ee8d57e50a9a8ae65ccd361343f716fca59d0957e782f9f83faa60bd914ea3283b0b76678c
7
- data.tar.gz: 3304a8381022cc29b118f0e6fc0fd6076abb7a669bdb9dc56b2dd2b649f9cf093dcae7ef9bd52cd3546090a396b34184af0a83657e37245642a7ad93f01acda2
6
+ metadata.gz: 9fddf00c32b5c86a5b5fc4b38d3d6ad171c44608b526f4b940fba03f627841ecc9a722ca301ce9385da8d21506f8c14ae91d5183cac05dc6beede691613347cb
7
+ data.tar.gz: a988eaeac8f79505cd06e6ac5ca7bff4bf1f799d3503c2da9eedc76a4648fb1f3fbba690caa8ffadab100f0c47516fac2a2f7d0157f11bf5d765743d7d1ecf9b
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ *~
2
+ /*_results.html
1
3
  /.bundle/
2
4
  /.yardoc
3
5
  /_yardoc/
data/.gitlab-ci.yml CHANGED
@@ -7,13 +7,50 @@ default:
7
7
  - gem install bundler --no-document
8
8
  - bundle install --jobs $(nproc) "${FLAGS[@]}"
9
9
 
10
+ bdd:
11
+ script:
12
+ - bundle exec rake test:features
13
+
14
+ yard documentation:
15
+ script:
16
+ - bundle exec rake yard
17
+ artifacts:
18
+ paths:
19
+ - doc
20
+
10
21
  unit tests:
11
22
  script:
12
23
  - bundle exec rake test:spec
13
24
 
14
- rubocop:
25
+ code quality:
26
+ script:
27
+ - bundle exec rake quality:all
28
+
29
+ bdd ruby2.7:
30
+ image: ruby:2.7
31
+ before_script:
32
+ - apt-get update
33
+ - ruby -v
34
+ - which ruby
35
+ - gem install bundler -v 2.4.22 --no-document
36
+ - bundle install --jobs $(nproc) "${FLAGS[@]}"
37
+ script:
38
+ - bundle exec rake test:features
39
+
40
+ bdd ruby3.0:
41
+ image: ruby:3.0
42
+ script:
43
+ - bundle exec rake test:features
44
+
45
+ bdd ruby3.1:
46
+ image: ruby:3.1
47
+ script:
48
+ - bundle exec rake test:features
49
+
50
+ bdd ruby3.2:
51
+ image: ruby:3.2
15
52
  script:
16
- - bundle exec rake quality:rubocop
53
+ - bundle exec rake test:features
17
54
 
18
55
  unit tests ruby2.7:
19
56
  image: ruby:2.7
@@ -40,3 +77,14 @@ unit tests ruby3.2:
40
77
  image: ruby:3.2
41
78
  script:
42
79
  - bundle exec rake test:spec
80
+
81
+ pages:
82
+ stage: deploy
83
+ script:
84
+ - mkdir public
85
+ - cp -r doc/* public
86
+ artifacts:
87
+ paths:
88
+ - public
89
+ only:
90
+ - master
data/Gemfile CHANGED
@@ -7,7 +7,13 @@ gemspec
7
7
 
8
8
  ruby RUBY_VERSION
9
9
 
10
+ # rubocop:disable Metrics/BlockLength
10
11
  group :development do
12
+ # cucumber steps for command line tests
13
+ gem 'aruba', '~> 2'
14
+ # bdd
15
+ gem 'cucumber', '~> 9'
16
+
11
17
  if RUBY_VERSION >= '3.0'
12
18
  # mutation testing
13
19
  plan = 'oss'
@@ -21,8 +27,13 @@ group :development do
21
27
  end
22
28
  # to parse provided Rakefile
23
29
  gem 'rake', '~> 13'
30
+
31
+ if RUBY_VERSION >= '3.0'
32
+ # needed by yard to render documentation
33
+ gem 'rdoc', '~> 6'
34
+ end
24
35
  # tdd
25
- gem 'rspec', '3.12'
36
+ gem 'rspec', '~> 3'
26
37
  # code need to be clean
27
38
  gem 'rubocop', '1.65'
28
39
  # code need to be clean
@@ -37,7 +48,13 @@ group :development do
37
48
  end
38
49
  # What is tdd without code coverage ?
39
50
  gem 'simplecov', '~> 0'
51
+
52
+ if RUBY_VERSION >= '3.0'
53
+ # to document code
54
+ gem 'yard', '~> 0'
55
+ end
40
56
  end
57
+ # rubocop:enable Metrics/BlockLength
41
58
 
42
59
  group :debugging do
43
60
  # Sometimes, we need to debug
data/README.adoc ADDED
@@ -0,0 +1,69 @@
1
+ = Asciidoctor::Defmastership
2
+
3
+ Asciidoctor Defmastership module is dedicated to preprocess asciidoctor files which have specific lines as follows:
4
+
5
+ * For comment lines do nothing
6
+ * For other lines check line against a vector of regexp and for each match replace the parsed lines with new content
7
+ * Follows a list of noticeable transformations, for a complete list refers to spec/unit/asciidoctor/def_mastership/preprocessor_spec.rb
8
+
9
+ * Lines like [define,requirement,XXYY] add title XXYY, anchor point and call style define.requirement located in stylesheet of renderer
10
+ * Add a dedicated style to checksums and option for visibility or not
11
+ * Add attribute to requirements
12
+
13
+ The style inserted by preprocessor can then be parsed whith appropriate stylesheet :
14
+ * html => CSS
15
+ * pdf => xsl+sty dblatex (ie docbook + latex)
16
+
17
+
18
+ == Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ [source, ruby]
23
+ ----
24
+ gem 'asciidoctor-defmastership'
25
+ ----
26
+
27
+ And then execute:
28
+
29
+ [source, bash]
30
+ ----
31
+ $ bundle
32
+ ----
33
+
34
+ Or install it yourself as:
35
+
36
+
37
+ [source, bash]
38
+ ----
39
+ $ gem install asciidoctor-defmastership
40
+ ----
41
+
42
+ == Usage
43
+
44
+ If `my_document.adoc` contains definitions blocks
45
+
46
+ [source, bash]
47
+ ----
48
+ $ asciidoctor -r asciidoctor-defmastership my_document.adoc
49
+ ----
50
+ == Development
51
+
52
+ Require asciidoctor module for preprocessor hooking
53
+
54
+ Require defmastership for REGEXP collections
55
+
56
+ - bin : minimal applications (console + setup) to test module
57
+ - lib : asciidoctor/defmastership, asciidoctor/defmastership/preprocessor is the main module
58
+
59
+ Preprocessor architecture :
60
+
61
+ * Process : Main entry point for parsing and replacing lines
62
+
63
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
64
+
65
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
66
+
67
+ == Contributing
68
+
69
+ Bug reports and pull requests are welcome on GitLab at https://gitlab.com/defmastership/asciidoctor-defmastership.
data/Rakefile CHANGED
@@ -1,16 +1,14 @@
1
1
  # Copyright (c) 2020 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
- require('bundler/gem_tasks')
5
- require('rspec/core/rake_task')
6
-
7
4
  Dir['tasks/**/*.rake'].each { |t| load t }
8
5
 
9
6
  desc 'Continous integration tasks'
10
7
  task :ci do
11
8
  [
12
9
  'test:spec',
13
- :rubocop
10
+ 'test:features',
11
+ 'quality:all'
14
12
  ].each do |name|
15
13
  puts "\n=== Running #{name}...\n"
16
14
  Rake::Task[name].invoke
@@ -3,7 +3,7 @@
3
3
 
4
4
  lib = File.expand_path('lib', __dir__)
5
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require('asciidoctor/defmastership/version')
6
+ require('asciidoctor-defmastership/version')
7
7
 
8
8
  Gem::Specification.new do |spec|
9
9
  spec.metadata = {
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
 
13
13
  spec.required_ruby_version = '>= 2.7'
14
14
  spec.name = 'asciidoctor-defmastership'
15
- spec.version = Asciidoctor::DefMastership::VERSION
15
+ spec.version = Asciidoctor::Defmastership::VERSION
16
16
  spec.authors = ['Jérôme Arbez-Gindre']
17
17
  spec.email = ['jeromearbezgindre@gmail.com']
18
18
  spec.licenses = ['MIT']
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
  applicable definitions references, link to other references
25
25
  (internal or external))
26
26
 
27
- spec.homepage = 'https://gitlab.com/jjag/asciidoctor-defmastership/'
27
+ spec.homepage = 'https://gitlab.com/defmastership/asciidoctor-defmastership/'
28
28
 
29
29
  # Specify which files should be added to the gem when it is released.
30
30
  # The `git ls-files -z` loads the files in the RubyGem that
@@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
37
37
  end
38
38
  spec.require_paths = ['lib']
39
39
 
40
- spec.add_dependency('asciidoctor', '~> 2')
41
- spec.add_dependency('defmastership', '>= 1.0.19')
40
+ spec.add_dependency('asciidoctor', '~> 2.0')
41
+ spec.add_dependency('defmastership-core', '>= 1.2.0')
42
+ spec.add_dependency('ostruct', '~> 0.6')
42
43
  end
data/bin/console CHANGED
@@ -2,7 +2,7 @@
2
2
  # Copyright (c) 2020 Jerome Arbez-Gindre
3
3
  # frozen_string_literal: true
4
4
 
5
- require('asciidoctor/defmastership')
5
+ require('asciidoctor-defmastership')
6
6
  require('bundler/setup')
7
7
 
8
8
  # You can add fixtures and/or initialization code here to make experimenting
@@ -0,0 +1,3 @@
1
+ ---
2
+ default: features --publish-quiet --format html -o features_results.html --format progress -x
3
+ wip: features --publish-quiet --format pretty -x -s --tags '@wip and not @pending'
data/config/mutant.yml CHANGED
@@ -1,26 +1,17 @@
1
1
  ---
2
+ usage: opensource
2
3
  includes:
3
4
  - lib
4
5
  integration:
5
6
  name: rspec
7
+ arguments:
8
+ - --options=config/rspec
9
+ - spec
6
10
  requires:
7
- - defmastership
11
+ - asciidoctor/defmastership
8
12
  matcher:
9
13
  subjects:
10
- - 'DefMastership*'
11
- # ignore:
12
- # - 'DefMastership::BatchModifier*'
13
- # - 'DefMastership::CSVFormatter*'
14
- # - 'DefMastership::CSVFormatterBody*'
15
- # - 'DefMastership::CSVFormatterHeader*'
16
- # - 'DefMastership::ChangeRefModifier*'
17
- # - 'DefMastership::Definition*'
18
- # - 'DefMastership::Document*'
19
- # - 'DefMastership::Modifier*'
20
- # - 'DefMastership::ModifierFactory*'
21
- # - 'DefMastership::ParsingState*'
22
- # - 'DefMastership::RenameIncludedFilesModifier*'
23
- # - 'DefMastership::UpdateDefChecksumModifier*'
24
- # - 'DefMastership::UpdateDefModifier*'
25
- # - 'DefMastership::UpdateDefVersionModifier*'
14
+ - 'Asciidoctor::Defmastership*'
15
+ # - 'Asciidoctor::Defmastership::Preprocessor*'
16
+ # - 'Asciidoctor::Defmastership::RegexpDispatcher*'
26
17
  # fail_fast: true
data/config/rubocop.yml CHANGED
@@ -55,13 +55,16 @@ Style/ConstantVisibility :
55
55
  Exclude:
56
56
  # there is one unique explicit constant visibility for all
57
57
  # constants
58
- - 'lib/asciidoctor/defmastership/extension.rb'
58
+ - 'lib/asciidoctor-defmastership/extension.rb'
59
59
 
60
60
  # rubocop-rspec options
61
61
  RSpec/MessageExpectation :
62
62
  Enabled: true
63
63
 
64
- RSpec/FilePath :
64
+ RSpec/SpecFilePathFormat :
65
+ Enabled: true
66
+
67
+ RSpec/SpecFilePathSuffix :
65
68
  Enabled: true
66
69
 
67
70
  RSpec/NestedGroups:
@@ -72,7 +75,9 @@ Layout/RedundantLineBreak:
72
75
 
73
76
  Style/DisableCopsWithinSourceCodeDirective:
74
77
  Enabled: true
75
- AllowedCops: ['Lint/InterpolationCheck']
78
+ AllowedCops: ['Lint/InterpolationCheck', 'Naming/FileName']
79
+ Exclude:
80
+ - 'Gemfile'
76
81
 
77
82
  Layout/EndOfLine:
78
83
  EnforcedStyle: lf
@@ -1,12 +1,4 @@
1
1
  # Copyright (c) 2020 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
- if RUBY_ENGINE == 'opal'
5
- require('asciidoctor/defmastership/preprocessor')
6
- else
7
- require_relative('defmastership/preprocessor')
8
- end
9
-
10
- Asciidoctor::Extensions.register do
11
- preprocessor Asciidoctor::DefMastership::Preprocessor
12
- end
4
+ require('asciidoctor-defmastership')
@@ -0,0 +1,239 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ # :nocov:
5
+ require('asciidoctor/extensions') unless RUBY_ENGINE == 'opal'
6
+ # :nocov:
7
+
8
+ # An extension that allow to define applicable definitions
9
+ #
10
+ # Usage
11
+ # :tag-mylabel-color: yellow
12
+ # :tag-otherlabel-color: red
13
+ #
14
+ #
15
+ # [define, requirement, TOTO-0001, [mylabel, otherlabel]]
16
+ # --
17
+ # The system shall allow to do lots of things.
18
+ # --
19
+ #
20
+ # or
21
+ #
22
+ # [define, requirement, TOTO-0001]
23
+ # This shall be nice.
24
+ #
25
+ require('asciidoctor-defmastership/regexp_dispatcher')
26
+ require('defmastership/core/constants')
27
+ require('defmastership/core/parsing_state')
28
+
29
+ module Asciidoctor
30
+ # Module to host Defmastership preprocessor
31
+ module Defmastership
32
+ # Preprocessor to replace adoc statements
33
+ # This class smells of :reek:InstanceVariableAssumption.
34
+ # Not an issue because process is the only method used by Asciidoctor
35
+ class Preprocessor < Asciidoctor::Extensions::Preprocessor
36
+ REGEXPS = {
37
+ eref_config: ::Defmastership::Core::DMRegexp::EREF_CONFIG,
38
+ definition: ::Defmastership::Core::DMRegexp::DEFINITION,
39
+ eref_def: ::Defmastership::Core::DMRegexp::EREF_DEF,
40
+ iref_def: ::Defmastership::Core::DMRegexp::IREF_DEF,
41
+ attr_set: ::Defmastership::Core::DMRegexp::ATTR_SET,
42
+ variable_def: ::Defmastership::Core::DMRegexp::VARIABLE_DEF
43
+ }.freeze
44
+
45
+ private_constant :REGEXPS
46
+
47
+ # @param _config [Hash] configuration Hash for this preprocessor instance
48
+ def initialize(_config = {})
49
+ super
50
+ @has_url = Set.new
51
+ @variables = {}
52
+ @parsing_state = ::Defmastership::Core::ParsingState.new
53
+ end
54
+
55
+ # Entry point for the plugin call
56
+ #
57
+ # @param _document [Asciidoctor::Document] the current document
58
+ # @param reader [Asciidoctor::Reader] to retrieve lines from AsciiDoc source file
59
+ # This method smells of :reek:FeatureEnvy
60
+ def process(_document, reader)
61
+ return reader if reader.eof?
62
+
63
+ reader.unshift_lines(parse_and_replace(reader.read_lines))
64
+ end
65
+
66
+ # Process a definition line
67
+ #
68
+ # @param _line [String] the original line
69
+ # @param match [MatchData] the match data from the matching Regexp
70
+ # @return [Array<String>] the lines to replace the original line
71
+ def build_definition(_line, match)
72
+ Helper::DefinitionStringBuilder.new(match, show_explicit_checksum(match)).str_a
73
+ end
74
+
75
+ # Process a variable setting line
76
+ #
77
+ # @param line [String] the original line
78
+ # @param match [MatchData] the match data from the matching Regexp
79
+ # @return [Array<String>] the lines to replace the original line
80
+ def variable_set(line, match)
81
+ @variables.merge!(Helper.variable_hash(match))
82
+ [line]
83
+ end
84
+
85
+ # Process a set url line
86
+ #
87
+ # @param line [String] the original line
88
+ # @param match [MatchData] the match data from the matching Regexp
89
+ # @return [Array<String>] the lines to replace the original line
90
+ def set_eref_url_if_any(line, match)
91
+ @has_url.add(match[:reference]) if Helper.valid_eref_url?(match)
92
+ [line]
93
+ end
94
+
95
+ # Process an external ref line
96
+ #
97
+ # @param _line [String] the original line
98
+ # @param match [MatchData] the match data from the matching Regexp
99
+ # @return [Array<String>] the lines to replace the original line
100
+ def build_external_ref(_line, match)
101
+ return [] unless show_ext_ref(match)
102
+
103
+ extrefs = match[:extrefs].split(/\s*,\s*/)
104
+ extref_line = extrefs.map { |ref| build_link(ref, match) }
105
+ ["[.external_reference]\#{eref-#{match[:reference]}-prefix} #{extref_line.join(', ')}.#"]
106
+ end
107
+
108
+ # Process an internal ref line
109
+ #
110
+ # @param line [String] the original line
111
+ # @param _match [MatchData] the match data from the matching Regexp
112
+ # @return [Array<String>] the lines to replace the original line
113
+ # This method smells of :reek:UtilityFunction
114
+ def build_internal_ref(line, _match)
115
+ [
116
+ line.gsub(REGEXPS.fetch(:iref_def)) do
117
+ intref = Regexp.last_match[:intref]
118
+ "<<#{intref},#{intref}>>"
119
+ end
120
+ ]
121
+ end
122
+
123
+ # Process an attribute setting line
124
+ #
125
+ # @param _line [String] the original line
126
+ # @param match [MatchData] the match data from the matching Regexp
127
+ # @return [Array<String>] the lines to replace the original line
128
+ # This method smells of :reek:UtilityFunction
129
+ def attribute_setting(_line, match)
130
+ [
131
+ '[.attribute]',
132
+ "{attr-#{match[:attr]}-prefix} #{match[:value]}."
133
+ ]
134
+ end
135
+
136
+ private
137
+
138
+ def build_regexp_dispatcher
139
+ regexp_dispatcher = RegexpDispatcher.new(self)
140
+ regexp_dispatcher
141
+ .add_rule(REGEXPS.fetch(:eref_config), :set_eref_url_if_any)
142
+ .add_rule(REGEXPS.fetch(:definition), :build_definition)
143
+ .add_rule(REGEXPS.fetch(:eref_def), :build_external_ref)
144
+ .add_rule(REGEXPS.fetch(:iref_def), :build_internal_ref)
145
+ .add_rule(REGEXPS.fetch(:attr_set), :attribute_setting)
146
+ .add_rule(REGEXPS.fetch(:variable_def), :variable_set)
147
+ end
148
+
149
+ def parse_and_replace(lines)
150
+ regexp_dispatcher = build_regexp_dispatcher
151
+ lines.reduce([]) do |new_lines, line|
152
+ next new_lines + [line] unless @parsing_state.enabled?(line)
153
+
154
+ next new_lines + regexp_dispatcher.replace(line)
155
+ end
156
+ end
157
+
158
+ def show_explicit_checksum(match)
159
+ match[:explicit_checksum] &&
160
+ !@variables['show-explicit-checksum'].eql?('disable') &&
161
+ !@variables["show-#{match[:type]}-explicit-checksum"].eql?('disable')
162
+ end
163
+
164
+ def build_link(ref, match)
165
+ refname = match[:reference]
166
+ return ref unless @has_url.include?(refname)
167
+
168
+ ref_pattern =
169
+ @variables["eref-#{refname}-ref-pattern"] || '#%s'
170
+ ref_str = format(ref_pattern, ref)
171
+
172
+ "link:{eref-#{refname}-url}#{ref_str}[#{ref}]"
173
+ end
174
+
175
+ def show_ext_ref(match)
176
+ !@variables['show-ext-ref'].eql?('disable') &&
177
+ !@variables["show-#{match[:reference]}-ext-ref"].eql?('disable')
178
+ end
179
+ end
180
+
181
+ # Proepocessors class Helpers
182
+ class Preprocessor
183
+ # Helpers for Preprocessor class
184
+ module Helper
185
+ # Isolate the definition macro
186
+ class DefinitionStringBuilder
187
+ # @param match [MatchData] match data from defintion Regexp
188
+ # @param show_explicit_checksum [Boolean] sepcify if we need to show checksums in rendered document
189
+ def initialize(match, show_explicit_checksum)
190
+ @match = match
191
+ @show_explicit_checksum = show_explicit_checksum
192
+ end
193
+
194
+ # @return [Array<String>] the lines to replace defininition's line
195
+ def str_a
196
+ explicit_checksum_str = " [.checksum]#(#{@match[:explicit_checksum]})#" if @show_explicit_checksum
197
+ explicit_version_str = Helper.explicit_version_str(@match[:explicit_version])
198
+ labels_str = Helper.labels_str(@match[:labels])
199
+ reference = @match[:reference]
200
+ [
201
+ ".#{reference}#{explicit_version_str}#{explicit_checksum_str}#{labels_str}",
202
+ "[##{reference}.define.#{@match[:type]}]"
203
+ ]
204
+ end
205
+ end
206
+
207
+ # @param match [MatchData] match data from external ref setting Regexp
208
+ # @return [Boolean] true if the match data includes a valid URL
209
+ def self.valid_eref_url?(match)
210
+ match[:symb] == 'url' && !match[:value].eql?('none')
211
+ end
212
+
213
+ # @param labels [Array[String]] List of labels of a definition
214
+ # @return [String] the replacement string for labels
215
+ def self.labels_str(labels)
216
+ return unless labels
217
+
218
+ labels_strings =
219
+ labels.split(/\s*,\s*/).reduce([]) do |acc, label|
220
+ acc << "[.tag.{tag-#{label}-color}]##{label}#"
221
+ end
222
+ " #{labels_strings.join(' ')}"
223
+ end
224
+
225
+ # @param explicit_version [String] an explicit version setting
226
+ # @return [String] the replacement string for explicit version
227
+ def self.explicit_version_str(explicit_version)
228
+ " [.version]#(#{explicit_version})#" if explicit_version
229
+ end
230
+
231
+ # @param match [MatchData] the match data from the matching variable setting Regexp
232
+ # @return [[Hash{String => Object}]] the hash corresponding to the variable setting
233
+ def self.variable_hash(match)
234
+ { match[:varname] => match[:value] }
235
+ end
236
+ end
237
+ end
238
+ end
239
+ end
@@ -8,27 +8,37 @@ require('asciidoctor/extensions') unless RUBY_ENGINE == 'opal'
8
8
  require('ostruct')
9
9
 
10
10
  module Asciidoctor
11
- module DefMastership
11
+ module Defmastership
12
12
  # Hosts several Text replacement rules
13
13
  class RegexpDispatcher
14
14
  # Class to link a regexp with a method
15
15
  Rule = Struct.new(:regexp, :method_symbol)
16
16
  private_constant :Rule
17
17
 
18
- def initialize(effective_subs)
19
- @effective_subs = effective_subs
18
+ # @param client [Object] the object that will receive method call on regexp matches
19
+ def initialize(client)
20
+ @client = client
20
21
  @rules = []
21
22
  end
22
23
 
24
+ # Add a rule
25
+ #
26
+ # @param regexp [Regexp] the regexp for this rule
27
+ # @param method_symbol [Symbol] the symbol for the method call
28
+ # @return [RegexpDispatcher] self to allow add_rule calls chain
23
29
  def add_rule(regexp, method_symbol)
24
30
  @rules << Rule.new(regexp, method_symbol)
25
31
  self
26
32
  end
27
33
 
34
+ # Add a rule
35
+ #
36
+ # @param line [String] the original line
37
+ # @return [Array<String>] the lines to replace the original line
28
38
  def replace(line)
29
39
  @rules.each do |rule|
30
40
  matches = rule.regexp.match(line)
31
- return @effective_subs.public_send(rule.method_symbol, line, matches) if matches
41
+ return @client.public_send(rule.method_symbol, line, matches) if matches
32
42
  end
33
43
  [line]
34
44
  end
@@ -3,8 +3,9 @@
3
3
 
4
4
  module Asciidoctor
5
5
  # main application module
6
- module DefMastership
7
- VERSION = '1.0.10'
6
+ module Defmastership
7
+ # [String] Gem version
8
+ VERSION = '1.1.1'
8
9
  public_constant :VERSION
9
10
  end
10
11
  end
@@ -0,0 +1,15 @@
1
+ # rubocop:disable Naming/FileName
2
+ # Copyright (c) 2020 Jerome Arbez-Gindre
3
+ # frozen_string_literal: true
4
+
5
+ if RUBY_ENGINE == 'opal'
6
+ require('asciidoctor-defmastership/preprocessor')
7
+ else
8
+ require_relative('asciidoctor-defmastership/preprocessor')
9
+ end
10
+
11
+ Asciidoctor::Extensions.register do
12
+ preprocessor Asciidoctor::Defmastership::Preprocessor
13
+ end
14
+
15
+ # rubocop:enable Naming/FileName
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2024 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ namespace 'documentation' do
5
+ require('yard')
6
+
7
+ YARD::Rake::YardocTask.new do |task|
8
+ task.files = ['lib/**/*.rb']
9
+ task.options = ['--fail-on-warning', '--verbose']
10
+ task.stats_options = ['--list-undoc']
11
+ end
12
+ rescue LoadError
13
+ task(:yard) do
14
+ puts('Install Yard to run its rake tasks')
15
+ end
16
+ end
17
+
18
+ desc 'Synonym for documentation:yard'
19
+ task(yard: 'documentation:yard')
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2023 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ require('bundler/gem_tasks')
data/tasks/test.rake CHANGED
@@ -1,6 +1,8 @@
1
1
  # Copyright (c) 2023 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
+ require('cucumber/rake/task')
5
+ require('rake/clean')
4
6
  require('rspec/core/rake_task')
5
7
 
6
8
  namespace 'test' do
@@ -8,8 +10,15 @@ namespace 'test' do
8
10
  t.rspec_opts = ['--options config/rspec']
9
11
  end
10
12
 
13
+ CLEAN << 'features_results.html'
14
+
15
+ Cucumber::Rake::Task.new(:features)
16
+ Cucumber::Rake::Task.new('features:wip') do |t|
17
+ t.cucumber_opts = ['--profile wip']
18
+ end
19
+
11
20
  desc 'Runs all unit tests and acceptance tests'
12
- task(all: ['test:spec'])
21
+ task(all: ['test:spec', 'test:features'])
13
22
  end
14
23
 
15
24
  desc 'Synonym for test:spec'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-defmastership
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.10
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jérôme Arbez-Gindre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-18 00:00:00.000000000 Z
11
+ date: 2024-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: defmastership
28
+ name: defmastership-core
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.0.19
33
+ version: 1.2.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.0.19
40
+ version: 1.2.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: ostruct
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
41
55
  description: |-
42
56
  asciidoctor-defmastership allows to define
43
57
  applicable definitions references, link to other references
@@ -50,33 +64,29 @@ extra_rdoc_files: []
50
64
  files:
51
65
  - ".gitignore"
52
66
  - ".gitlab-ci.yml"
53
- - ".rspec"
54
- - ".rubocop.yml"
55
- - ".travis.yml"
56
67
  - Gemfile
57
68
  - LICENCE
58
- - README.md
69
+ - README.adoc
59
70
  - Rakefile
60
71
  - asciidoctor-defmastership.gemspec
61
72
  - bin/console
62
73
  - bin/setup
74
+ - config/cucumber.yml
63
75
  - config/mutant.yml
64
76
  - config/reek.yml
65
77
  - config/rspec
66
78
  - config/rubocop.yml
67
- - example/.config.adoc
68
- - example/.gitignore
69
- - example/example.adoc
70
- - example/howto.sh
79
+ - lib/asciidoctor-defmastership.rb
80
+ - lib/asciidoctor-defmastership/preprocessor.rb
81
+ - lib/asciidoctor-defmastership/regexp_dispatcher.rb
82
+ - lib/asciidoctor-defmastership/version.rb
71
83
  - lib/asciidoctor/defmastership.rb
72
- - lib/asciidoctor/defmastership/preprocessor.rb
73
- - lib/asciidoctor/defmastership/regexp_dispatcher.rb
74
- - lib/asciidoctor/defmastership/version.rb
75
84
  - tasks/console.rake
76
- - tasks/package.task
85
+ - tasks/documentation.rake
86
+ - tasks/package.rake
77
87
  - tasks/smelling_code.rake
78
88
  - tasks/test.rake
79
- homepage: https://gitlab.com/jjag/asciidoctor-defmastership/
89
+ homepage: https://gitlab.com/defmastership/asciidoctor-defmastership/
80
90
  licenses:
81
91
  - MIT
82
92
  metadata:
@@ -96,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
106
  - !ruby/object:Gem::Version
97
107
  version: '0'
98
108
  requirements: []
99
- rubygems_version: 3.4.10
109
+ rubygems_version: 3.5.22
100
110
  signing_key:
101
111
  specification_version: 4
102
112
  summary: asciidoctor extension to handle applicable definition references
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,79 +0,0 @@
1
- # The behavior of RuboCop can be controlled via the .rubocop.yml
2
- # configuration file. It makes it possible to enable/disable
3
- # certain cops (checks) and to alter their behavior if they accept
4
- # any parameters. The file can be placed either in your home
5
- # directory or in some project directory.
6
- #
7
- # RuboCop will start looking for the configuration file in the directory
8
- # where the inspected file is and continue its way up to the root directory.
9
- #
10
- # See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md
11
-
12
- require:
13
- - rubocop-performance
14
- - rubocop-rspec
15
- - rubocop-rake
16
-
17
- AllCops:
18
- TargetRubyVersion: 2.7
19
- EnabledByDefault: true
20
- DisplayCopNames: true
21
-
22
- Style/Copyright:
23
- Enabled: true
24
- Notice: 'Copyright (\(c\) )?202[0-9] Jerome Arbez-Gindre'
25
- AutocorrectNotice: '# Copyright (c) 2020 Jerome Arbez-Gindre'
26
-
27
- Lint/ConstantResolution: # Not available ins rubocop 0.81
28
- Enabled: false
29
-
30
- Style/DocumentationMethod:
31
- Enabled: false
32
-
33
- Style/StringHashKeys :
34
- Enabled: true
35
- Exclude:
36
- - '*.gemspec'
37
-
38
- Style/MissingElse:
39
- EnforcedStyle: case
40
-
41
- Metrics/ModuleLength :
42
- Exclude:
43
- - 'spec/**/*'
44
-
45
- Metrics/BlockLength :
46
- Exclude:
47
- - 'spec/**/*'
48
- - '*.gemspec'
49
-
50
- Security/Eval :
51
- Exclude:
52
- - 'Rakefile'
53
-
54
- Style/ConstantVisibility :
55
- Exclude:
56
- # there is one unique explicit constant visibility for all
57
- # constants
58
- - 'lib/asciidoctor/defmastership/extension.rb'
59
-
60
- # rubocop-rspec options
61
- RSpec/MessageExpectation :
62
- Enabled: true
63
-
64
- RSpec/FilePath :
65
- Enabled: true
66
-
67
- RSpec/NestedGroups:
68
- Max: 4
69
-
70
- Layout/RedundantLineBreak:
71
- Enabled: false
72
-
73
- Style/DisableCopsWithinSourceCodeDirective:
74
- Enabled: true
75
- AllowedCops: ['Lint/InterpolationCheck']
76
-
77
- Layout/EndOfLine:
78
- EnforcedStyle: lf
79
-
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.5.5
7
- before_install: gem install bundler -v 2.0.2
data/README.md DELETED
@@ -1,35 +0,0 @@
1
- # Asciidoctor::DefMastership
2
-
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/asciidoctor/defmastership`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
6
-
7
- ## Installation
8
-
9
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'asciidoctor-defmastership'
13
- ```
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install asciidoctor-defmastership
22
-
23
- ## Usage
24
-
25
- TODO: Write usage instructions here
26
-
27
- ## Development
28
-
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
-
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
-
33
- ## Contributing
34
-
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/asciidoctor-defmastership.
data/example/.config.adoc DELETED
@@ -1,2 +0,0 @@
1
- :eref-implements-prefix: Participate to:
2
- :eref-implements-url: ./the_other_document.html
data/example/.gitignore DELETED
@@ -1 +0,0 @@
1
- /example.html
data/example/example.adoc DELETED
@@ -1,57 +0,0 @@
1
- :toc: left
2
- :tag-performance-color: green
3
- :tag-chabada-color: fuchsia
4
- :attr-verifiedby-prefix: Verified by:
5
-
6
- include::.config.adoc[]
7
-
8
- = My beautiful document
9
-
10
- == Document content
11
- == Requirements
12
-
13
- [define, requirement, TOTO-0001, [performance]]
14
- --
15
- The system shall allow to do lots of things:
16
-
17
- * toto
18
- * titi
19
- --
20
- defs:attribute[verifiedby, Test compliqué]
21
-
22
- [define, requirement, TOTO-0002, [performance, chabada]]
23
- --
24
- The system shall allow to do these things too:
25
-
26
- * pouet
27
- * tagada
28
- * being able to reference defs:iref[TOTO-0001] and defs:iref[TOTO-0243]
29
- * having also external reference as below
30
- --
31
-
32
- defs:eref[implements, [SYSTEM-0012, SYSTEM-0014]]
33
-
34
- [define, requirement, TOTO-0003]
35
- The system shall be nice.
36
- And Also funny.
37
- --
38
- Not included !
39
- --
40
-
41
- ////
42
- Pouet tagada
43
- ////
44
-
45
-
46
-
47
-
48
- // [define, requirement, TOTO_0030]
49
- // --
50
- // The system shall allow to do eat chocolates from:
51
-
52
- // * Switzerland
53
- // * Belgium
54
- // --
55
-
56
- link:rspec_results.html[Unit tests results]
57
- link:coverage/index.html[Coverage analysis]
data/example/howto.sh DELETED
@@ -1 +0,0 @@
1
- bundle exec asciidoctor --trace -a linkcss -a stylesheet=definition.css -a stylesdir=../../asciidoctor-stylesheet-factory/stylesheets -r ../lib/asciidoctor/defmastership.rb example.adoc
@@ -1,192 +0,0 @@
1
- # Copyright (c) 2020 Jerome Arbez-Gindre
2
- # frozen_string_literal: true
3
-
4
- # :nocov:
5
- require('asciidoctor/extensions') unless RUBY_ENGINE == 'opal'
6
- # :nocov:
7
-
8
- # An extension that allow to define applicable definitions
9
- #
10
- # Usage
11
- # :tag-mylabel-color: yellow
12
- # :tag-otherlabel-color: red
13
- #
14
- #
15
- # [define, requirement, TOTO-0001, [mylabel, otherlabel]]
16
- # --
17
- # The system shall allow to do lots of things.
18
- # --
19
- #
20
- # or
21
- #
22
- # [define, requirement, TOTO-0001]
23
- # This shall be nice.
24
- #
25
- require('asciidoctor/defmastership/regexp_dispatcher')
26
- require('defmastership/constants')
27
- require('defmastership/parsing_state')
28
-
29
- module Asciidoctor
30
- # Module to host DefMastership preprocessor
31
- module DefMastership
32
- # Preprocessor to replace adoc statements
33
- # This class smells of :reek:InstanceVariableAssumption.
34
- # Not an issue because process is the only method used by Asciidoctor
35
- class Preprocessor < Asciidoctor::Extensions::Preprocessor
36
- REGEXPS = {
37
- eref_config: ::DefMastership::DMRegexp::EREF_CONFIG,
38
- definition: ::DefMastership::DMRegexp::DEFINITION,
39
- eref_def: ::DefMastership::DMRegexp::EREF_DEF,
40
- iref_def: ::DefMastership::DMRegexp::IREF_DEF,
41
- attr_set: ::DefMastership::DMRegexp::ATTR_SET,
42
- variable_def: ::DefMastership::DMRegexp::VARIABLE_DEF
43
- }.freeze
44
-
45
- private_constant :REGEXPS
46
-
47
- def initialize(config = {})
48
- super
49
- @has_url = Set.new
50
- @variables = {}
51
- @parsing_state = ::DefMastership::ParsingState.new
52
- end
53
-
54
- def process(_document, reader)
55
- return reader if reader.eof?
56
-
57
- reader.unshift_lines(parse_and_replace(reader.read_lines))
58
- end
59
-
60
- def build_definition(_line, matches)
61
- Helper::DefinitionStringBuilder.new(matches, show_explicit_checksum(matches)).str
62
- end
63
-
64
- def variable_set(line, matches)
65
- @variables.merge!(Helper.variable_hash(matches))
66
- [line]
67
- end
68
-
69
- def set_eref_url_if_any(line, matches)
70
- @has_url.add(matches[:reference]) if Helper.valid_eref_url?(matches)
71
- [line]
72
- end
73
-
74
- def build_external_ref(_line, matches)
75
- return [] unless show_ext_ref(matches)
76
-
77
- extrefs = matches[:extrefs].split(/\s*,\s*/)
78
- extref_line = extrefs.map { |ref| build_link(ref, matches) }
79
- ["[.external_reference]\#{eref-#{matches[:reference]}-prefix} #{extref_line.join(', ')}.#"]
80
- end
81
-
82
- # This method smells of :reek:UtilityFunction
83
- def build_internal_ref(line, _matches)
84
- [
85
- line.gsub(REGEXPS.fetch(:iref_def)) do
86
- intref = Regexp.last_match[:intref]
87
- "<<#{intref},#{intref}>>"
88
- end
89
- ]
90
- end
91
-
92
- # This method smells of :reek:UtilityFunction
93
- def attribute_setting(_line, matches)
94
- [
95
- '[.attribute]',
96
- "{attr-#{matches[:attr]}-prefix} #{matches[:value]}."
97
- ]
98
- end
99
-
100
- private
101
-
102
- def build_subs
103
- subs = RegexpDispatcher.new(self)
104
- subs
105
- .add_rule(REGEXPS.fetch(:eref_config), :set_eref_url_if_any)
106
- .add_rule(REGEXPS.fetch(:definition), :build_definition)
107
- .add_rule(REGEXPS.fetch(:eref_def), :build_external_ref)
108
- .add_rule(REGEXPS.fetch(:iref_def), :build_internal_ref)
109
- .add_rule(REGEXPS.fetch(:attr_set), :attribute_setting)
110
- .add_rule(REGEXPS.fetch(:variable_def), :variable_set)
111
- end
112
-
113
- def parse_and_replace(lines)
114
- subs = build_subs
115
- lines.reduce([]) do |new_lines, line|
116
- next new_lines + [line] unless @parsing_state.enabled?(line)
117
-
118
- next new_lines + subs.replace(line)
119
- end
120
- end
121
-
122
- def show_explicit_checksum(matches)
123
- matches[:explicit_checksum] &&
124
- !@variables['show-explicit-checksum'].eql?('disable') &&
125
- !@variables["show-#{matches[:type]}-explicit-checksum"].eql?('disable')
126
- end
127
-
128
- def build_link(ref, matches)
129
- refname = matches[:reference]
130
- return ref unless @has_url.include?(refname)
131
-
132
- ref_pattern =
133
- @variables["eref-#{refname}-ref-pattern"] || '#%s'
134
- ref_str = format(ref_pattern, ref)
135
-
136
- "link:{eref-#{refname}-url}#{ref_str}[#{ref}]"
137
- end
138
-
139
- def show_ext_ref(matches)
140
- !@variables['show-ext-ref'].eql?('disable') &&
141
- !@variables["show-#{matches[:reference]}-ext-ref"].eql?('disable')
142
- end
143
- end
144
-
145
- # Proepocessors class Helpers
146
- class Preprocessor
147
- # Helpers for Preprocessor class
148
- module Helper
149
- # Isolate the definition macro
150
- class DefinitionStringBuilder
151
- def initialize(matches, show_explicit_checksum)
152
- @matches = matches
153
- @show_explicit_checksum = show_explicit_checksum
154
- end
155
-
156
- def str
157
- explicit_checksum_str = " [.checksum]#(#{@matches[:explicit_checksum]})#" if @show_explicit_checksum
158
- explicit_version_str = Helper.build_explicit_version_str(@matches[:explicit_version])
159
- labels_str = Helper.build_labels_str(@matches[:labels])
160
- reference = @matches[:reference]
161
- [
162
- ".#{reference}#{explicit_version_str}#{explicit_checksum_str}#{labels_str}",
163
- "[##{reference}.define.#{@matches[:type]}]"
164
- ]
165
- end
166
- end
167
-
168
- def self.valid_eref_url?(match)
169
- match[:symb] == 'url' && !match[:value].eql?('none')
170
- end
171
-
172
- def self.build_labels_str(labels)
173
- return unless labels
174
-
175
- labels_strings =
176
- labels.split(/\s*,\s*/).reduce([]) do |acc, label|
177
- acc << "[.tag.{tag-#{label}-color}]##{label}#"
178
- end
179
- " #{labels_strings.join(' ')}"
180
- end
181
-
182
- def self.build_explicit_version_str(explicit_version)
183
- " [.version]#(#{explicit_version})#" if explicit_version
184
- end
185
-
186
- def self.variable_hash(match)
187
- { match[:varname] => match[:value] }
188
- end
189
- end
190
- end
191
- end
192
- end
data/tasks/package.task DELETED
@@ -1,9 +0,0 @@
1
- # Copyright (c) 2023 Jerome Arbez-Gindre
2
- # frozen_string_literal: true
3
-
4
- require('rubygems')
5
- require('rubygems/package_task')
6
-
7
- spec = eval(File.read('asciidoctor-defmastership.gemspec'))
8
-
9
- Gem::PackageTask.new(spec)