tocer 12.2.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "tocer/identity"
4
+ require "refinements/structs"
4
5
 
5
6
  module Tocer
6
7
  module CLI
7
8
  module Parsers
8
9
  # Handles parsing of Command Line Interface (CLI) core options.
9
10
  class Core
10
- def self.call(options: {}, client: CLIENT) = new(options: options, client: client).call
11
+ using Refinements::Structs
11
12
 
12
- def initialize options: {}, client: CLIENT
13
- @options = options
13
+ def self.call(...) = new(...).call
14
+
15
+ def initialize configuration = Configuration::Loader.call, client: Parser::CLIENT
16
+ @configuration = configuration
14
17
  @client = client
15
18
  end
16
19
 
@@ -18,12 +21,13 @@ module Tocer
18
21
  client.banner = "#{Identity::LABEL} - #{Identity::SUMMARY}"
19
22
  client.separator "\nUSAGE:\n"
20
23
  collate
21
- arguments.empty? ? arguments : client.parse!(arguments)
24
+ client.parse arguments
25
+ configuration
22
26
  end
23
27
 
24
28
  private
25
29
 
26
- attr_reader :options, :client
30
+ attr_reader :configuration, :client
27
31
 
28
32
  def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
29
33
 
@@ -34,25 +38,31 @@ module Tocer
34
38
  %i[edit view],
35
39
  "Manage gem configuration: edit or view."
36
40
  ) do |action|
37
- options[:config] = action
41
+ configuration.merge! action_config: action
38
42
  end
39
43
  end
40
44
 
41
- def add_build
42
- client.on "-b", "--build [PATH]", %(Build table of contents. Default path: ".") do |value|
43
- options[:build] = value || "."
45
+ def add_insert
46
+ root_dir = configuration.root_dir
47
+
48
+ client.on(
49
+ "-i",
50
+ "--insert [PATH]",
51
+ %(Insert/update table of contents. Default: "#{root_dir}".)
52
+ ) do |path|
53
+ configuration.merge! action_insert: true, root_dir: path || root_dir
44
54
  end
45
55
  end
46
56
 
47
57
  def add_version
48
58
  client.on "-v", "--version", "Show gem version." do
49
- options[:version] = Identity::VERSION_LABEL
59
+ configuration.merge! action_version: true
50
60
  end
51
61
  end
52
62
 
53
63
  def add_help
54
64
  client.on "-h", "--help", "Show this message." do
55
- options[:help] = true
65
+ configuration.merge! action_help: true
56
66
  end
57
67
  end
58
68
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Tocer
6
+ module CLI
7
+ module Parsers
8
+ # Handles parsing of Command Line Interface (CLI) flags.
9
+ class Flag
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration = Configuration::Loader.call, client: Parser::CLIENT
15
+ @configuration = configuration
16
+ @client = client
17
+ end
18
+
19
+ def call arguments = []
20
+ client.separator "\nOPTIONS:\n"
21
+ private_methods.sort.grep(/add_/).each { |method| __send__ method }
22
+ client.parse arguments
23
+ configuration
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :configuration, :client
29
+
30
+ def add_label
31
+ client.on(
32
+ "--label [LABEL]",
33
+ %(Add label. Default: "#{configuration.label}".)
34
+ ) do |value|
35
+ configuration.merge! label: value if value
36
+ end
37
+ end
38
+
39
+ def add_include
40
+ client.on(
41
+ "--includes [a,b,c]",
42
+ Array,
43
+ %(Add include patterns. Default: #{configuration.includes}.)
44
+ ) do |items|
45
+ configuration.merge! includes: items if items
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -4,39 +4,35 @@ module Tocer
4
4
  module CLI
5
5
  # The main Command Line Interface (CLI) object.
6
6
  class Shell
7
- PROCESSORS = {config: Processors::Config.new, build: Processors::Build.new}.freeze
7
+ ACTIONS = {config: Actions::Config.new, insert: Actions::Insert.new}.freeze
8
8
 
9
- def initialize parser: Parsers::Assembler.new, processors: PROCESSORS
9
+ def initialize parser: Parser.new, actions: ACTIONS
10
10
  @parser = parser
11
- @processors = processors
11
+ @actions = actions
12
12
  end
13
13
 
14
14
  def call arguments = []
15
- parse arguments
16
-
17
- case options
18
- in config: action then process_config action
19
- in build: path then process_build path
20
- in version: then puts version
21
- else usage
22
- end
15
+ perform parser.call(arguments)
16
+ rescue OptionParser::ParseError => error
17
+ puts error.message
23
18
  end
24
19
 
25
20
  private
26
21
 
27
- attr_reader :parser, :processors
22
+ attr_reader :parser, :actions
28
23
 
29
- def parse arguments = []
30
- parser.call arguments
31
- rescue StandardError => error
32
- puts error.message
24
+ def perform configuration
25
+ case configuration
26
+ in action_config: Symbol => action then process_config action
27
+ in action_insert: true then process_insert configuration
28
+ in action_version: true then puts Identity::VERSION_LABEL
29
+ else usage
30
+ end
33
31
  end
34
32
 
35
- def process_config(action) = processors.fetch(:config).call(action)
36
-
37
- def process_build(path) = processors.fetch(:build).call(path, options)
33
+ def process_config(action) = actions.fetch(:config).call(action)
38
34
 
39
- def options = parser.to_h
35
+ def process_insert(configuration) = actions.fetch(:insert).call(configuration)
40
36
 
41
37
  def usage = puts(parser.to_s)
42
38
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tocer
4
+ module Configuration
5
+ # Defines the content of the configuration for use throughout the gem.
6
+ Content = Struct.new(
7
+ :action_config,
8
+ :action_help,
9
+ :action_insert,
10
+ :action_version,
11
+ :includes,
12
+ :label,
13
+ :root_dir,
14
+ keyword_init: true
15
+ ) do
16
+ def initialize *arguments
17
+ super
18
+ freeze
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,4 @@
1
1
  :label: "## Table of Contents"
2
2
  :includes:
3
3
  - "README.md"
4
+ :root_dir: "."
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "refinements/structs"
5
+ require "runcom"
6
+ require "yaml"
7
+
8
+ module Tocer
9
+ module Configuration
10
+ # Represents the fully assembled Command Line Interface (CLI) configuration.
11
+ class Loader
12
+ using Refinements::Structs
13
+
14
+ DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
15
+ CLIENT = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
16
+
17
+ def self.call = new.call
18
+
19
+ def self.with_defaults = new(client: DEFAULTS)
20
+
21
+ def initialize content: Content.new, client: CLIENT
22
+ @content = content
23
+ @client = client
24
+ end
25
+
26
+ def call = content.merge(**client.to_h)
27
+
28
+ private
29
+
30
+ attr_reader :content, :client
31
+ end
32
+ end
33
+ end
@@ -17,6 +17,8 @@ module Tocer
17
17
  @message = message
18
18
  end
19
19
 
20
+ def comments = "#{start_tag}\n#{finish_tag}\n"
21
+
20
22
  def start_index(lines) = self.class.index(lines, start_id)
21
23
 
22
24
  def start_tag = comment(start_id, message)
@@ -25,6 +27,8 @@ module Tocer
25
27
 
26
28
  def finish_tag = comment(finish_id, message)
27
29
 
30
+ def empty?(lines) = (finish_index(lines) - start_index(lines)) == 1
31
+
28
32
  def prependable?(lines) = start_index(lines).zero? && finish_index(lines).zero?
29
33
 
30
34
  private
@@ -5,7 +5,7 @@ module Tocer
5
5
  module Identity
6
6
  NAME = "tocer"
7
7
  LABEL = "Tocer"
8
- VERSION = "12.2.0"
8
+ VERSION = "13.0.0"
9
9
  VERSION_LABEL = "#{LABEL} #{VERSION}".freeze
10
10
  SUMMARY = "A command line interface for generating table of contents for Markdown files."
11
11
  end
@@ -13,7 +13,7 @@ module Tocer
13
13
 
14
14
  def self.setup = new.install
15
15
 
16
- def initialize configuration: CLI::Configuration::Loader.new.call, runner: Runner.new
16
+ def initialize configuration = Configuration::Loader.call, runner: Runner.new
17
17
  @configuration = configuration
18
18
  @runner = runner
19
19
  end
@@ -21,7 +21,7 @@ module Tocer
21
21
  def install
22
22
  desc "Add/Update Table of Contents (README)"
23
23
  task :toc, %i[label includes] do |_task, arguments|
24
- runner.call(**configuration.merge(**arguments.to_h).to_h)
24
+ runner.call configuration.merge(**arguments.to_h)
25
25
  end
26
26
  end
27
27
 
data/lib/tocer/runner.rb CHANGED
@@ -7,21 +7,20 @@ module Tocer
7
7
  class Runner
8
8
  using Refinements::Pathnames
9
9
 
10
- def initialize configuration: CLI::Configuration::Loader.call, writer: Writer.new
11
- @configuration = configuration
10
+ def initialize writer: Writer.new
12
11
  @writer = writer
13
12
  end
14
13
 
15
- def call root_dir: ".", label: configuration.label, includes: configuration.includes
16
- Pathname(root_dir).files(%({#{includes.join ","}}))
17
- .each do |path|
18
- yield path if block_given?
19
- writer.call path, label: label
20
- end
14
+ def call configuration = Configuration::Loader.call
15
+ Pathname(configuration.root_dir).files(%({#{configuration.includes.join ","}}))
16
+ .each do |path|
17
+ yield path if block_given?
18
+ writer.call path, label: configuration.label
19
+ end
21
20
  end
22
21
 
23
22
  private
24
23
 
25
- attr_reader :configuration, :writer
24
+ attr_reader :writer
26
25
  end
27
26
  end
@@ -11,8 +11,9 @@ module Tocer
11
11
  end
12
12
 
13
13
  def call markdown
14
- transformers.find { |pattern, transformer| break transformer if pattern.match? markdown }
15
- .then { |transformer| transformer.new markdown }
14
+ transformers.find do |pattern, transformer|
15
+ break transformer.new(markdown) if pattern.match? markdown
16
+ end
16
17
  end
17
18
 
18
19
  private
data/lib/tocer/writer.rb CHANGED
@@ -24,7 +24,7 @@ module Tocer
24
24
  @builder = builder
25
25
  end
26
26
 
27
- def call path, label: CLI::Configuration::Loader.call.label
27
+ def call path, label: Configuration::Loader.call.label
28
28
  path.rewrite do |body|
29
29
  lines = body.each_line.to_a
30
30
  builder.prependable?(lines) ? prepend(lines, label) : replace(lines, label)
@@ -41,14 +41,22 @@ module Tocer
41
41
  klass = self.class
42
42
 
43
43
  klass.add(
44
- start_index: start_index,
44
+ start_index:,
45
45
  old_lines: klass.remove(start_index, finish_index, lines),
46
- new_lines: content(lines[finish_index, lines.length], label)
46
+ new_lines: new_lines(lines, label, finish_index)
47
47
  ).join
48
48
  end
49
49
 
50
+ def new_lines lines, label, finish_index
51
+ if builder.unbuildable?(lines)
52
+ builder.comments
53
+ else
54
+ content(lines[finish_index, lines.length], label)
55
+ end
56
+ end
57
+
50
58
  def prepend(lines, label) = [content(lines, label), lines.join].compress.join("\n")
51
59
 
52
- def content(lines, label) = builder.call(lines, label: label)
60
+ def content(lines, label) = builder.call(lines, label:)
53
61
  end
54
62
  end
data/lib/tocer.rb CHANGED
@@ -1,20 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "tocer/identity"
4
- require "tocer/elements/comment_block"
5
- require "tocer/parsers/header"
6
- require "tocer/transformers/link"
7
- require "tocer/transformers/text"
8
- require "tocer/transformers/finder"
9
- require "tocer/builder"
10
- require "tocer/writer"
11
- require "tocer/runner"
12
- require "tocer/cli/configuration/content"
13
- require "tocer/cli/configuration/loader"
14
- require "tocer/cli/parsers"
15
- require "tocer/cli/parsers/build"
16
- require "tocer/cli/parsers/core"
17
- require "tocer/cli/parsers/assembler"
18
- require "tocer/cli/processors/build"
19
- require "tocer/cli/processors/config"
20
- require "tocer/cli/shell"
3
+ require "zeitwerk"
4
+
5
+ Zeitwerk::Loader.for_gem.then do |loader|
6
+ loader.inflector.inflect "cli" => "CLI"
7
+ loader.ignore "#{__dir__}/rake/setup.rb"
8
+ loader.setup
9
+ end
10
+
11
+ # Main namespace.
12
+ module Tocer
13
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tocer
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.2.0
4
+ version: 13.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,7 +28,7 @@ cert_chain:
28
28
  lkHilIrX69jq8wMPpBhlaw2mRmeSL50Wv5u6xVBvOHhXFSP1crXM95vfLhLyRYod
29
29
  W2A=
30
30
  -----END CERTIFICATE-----
31
- date: 2021-11-20 00:00:00.000000000 Z
31
+ date: 2021-12-29 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: refinements
@@ -36,28 +36,42 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '8.5'
39
+ version: '9.0'
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '8.5'
46
+ version: '9.0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: runcom
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '7.0'
53
+ version: '8.0'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '7.0'
60
+ version: '8.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: zeitwerk
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.5'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.5'
61
75
  description:
62
76
  email:
63
77
  - brooke@alchemists.io
@@ -73,16 +87,15 @@ files:
73
87
  - exe/tocer
74
88
  - lib/tocer.rb
75
89
  - lib/tocer/builder.rb
76
- - lib/tocer/cli/configuration/content.rb
77
- - lib/tocer/cli/configuration/defaults.yml
78
- - lib/tocer/cli/configuration/loader.rb
79
- - lib/tocer/cli/parsers.rb
80
- - lib/tocer/cli/parsers/assembler.rb
81
- - lib/tocer/cli/parsers/build.rb
90
+ - lib/tocer/cli/actions/config.rb
91
+ - lib/tocer/cli/actions/insert.rb
92
+ - lib/tocer/cli/parser.rb
82
93
  - lib/tocer/cli/parsers/core.rb
83
- - lib/tocer/cli/processors/build.rb
84
- - lib/tocer/cli/processors/config.rb
94
+ - lib/tocer/cli/parsers/flag.rb
85
95
  - lib/tocer/cli/shell.rb
96
+ - lib/tocer/configuration/content.rb
97
+ - lib/tocer/configuration/defaults.yml
98
+ - lib/tocer/configuration/loader.rb
86
99
  - lib/tocer/elements/comment_block.rb
87
100
  - lib/tocer/identity.rb
88
101
  - lib/tocer/parsers/header.rb
@@ -95,7 +108,7 @@ files:
95
108
  - lib/tocer/writer.rb
96
109
  homepage: https://www.alchemists.io/projects/tocer
97
110
  licenses:
98
- - Apache-2.0
111
+ - Hippocratic-3.0
99
112
  metadata:
100
113
  bug_tracker_uri: https://github.com/bkuhlmann/tocer/issues
101
114
  changelog_uri: https://www.alchemists.io/projects/tocer/changes.html
@@ -110,14 +123,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
123
  requirements:
111
124
  - - "~>"
112
125
  - !ruby/object:Gem::Version
113
- version: '3.0'
126
+ version: '3.1'
114
127
  required_rubygems_version: !ruby/object:Gem::Requirement
115
128
  requirements:
116
129
  - - ">="
117
130
  - !ruby/object:Gem::Version
118
131
  version: '0'
119
132
  requirements: []
120
- rubygems_version: 3.2.31
133
+ rubygems_version: 3.3.3
121
134
  signing_key:
122
135
  specification_version: 4
123
136
  summary: A command line interface for generating table of contents for Markdown files.
metadata.gz.sig CHANGED
Binary file
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Tocer
4
- module CLI
5
- module Configuration
6
- # Defines the content of the configuration for use throughout the gem.
7
- Content = Struct.new :label, :includes, keyword_init: true
8
- end
9
- end
10
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pathname"
4
- require "refinements/structs"
5
- require "runcom"
6
- require "yaml"
7
-
8
- module Tocer
9
- module CLI
10
- module Configuration
11
- # Represents the fully assembled Command Line Interface (CLI) configuration.
12
- class Loader
13
- using Refinements::Structs
14
-
15
- DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
16
- CLIENT = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
17
-
18
- def self.call = new.call
19
-
20
- def initialize content: Content.new, client: CLIENT
21
- @content = content
22
- @client = client
23
- end
24
-
25
- def call = content.merge(**client.to_h)
26
-
27
- private
28
-
29
- attr_reader :content, :client
30
- end
31
- end
32
- end
33
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Tocer
4
- module CLI
5
- module Parsers
6
- # Assembles and parses all Command Line Interface (CLI) options.
7
- class Assembler
8
- SECTIONS = [Core, Build].freeze # Order is important.
9
-
10
- def initialize configuration: CLI::Configuration::Loader.call,
11
- sections: SECTIONS,
12
- client: CLIENT
13
- @options = configuration.to_h
14
- @sections = sections
15
- @client = client
16
- end
17
-
18
- def call arguments = []
19
- sections.each { |parser| parser.call client: client, options: options }
20
- client.parse! arguments
21
- options
22
- end
23
-
24
- def to_h = options
25
-
26
- def to_s = client.to_s
27
-
28
- private
29
-
30
- attr_reader :options, :sections, :client
31
- end
32
- end
33
- end
34
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Tocer
4
- module CLI
5
- module Parsers
6
- # Handles parsing of Command Line Interface (CLI) build options.
7
- class Build
8
- def self.call options: {}, configuration: Configuration::Loader.call, client: CLIENT
9
- new(options: options, configuration: configuration, client: client).call
10
- end
11
-
12
- def initialize options: {}, configuration: Configuration::Loader.call, client: CLIENT
13
- @options = options
14
- @configuration = configuration
15
- @client = client
16
- end
17
-
18
- def call arguments = []
19
- client.separator "\nBUILD OPTIONS:\n"
20
- private_methods.sort.grep(/add_/).each { |method| __send__ method }
21
- arguments.empty? ? arguments : client.parse!(arguments)
22
- end
23
-
24
- private
25
-
26
- attr_reader :options, :configuration, :client
27
-
28
- def add_label
29
- client.on(
30
- "-l",
31
- "--label [LABEL]",
32
- %(Label. Default: "#{CLI::Configuration::Loader.call.label}".)
33
- ) do |value|
34
- options[:label] = value || configuration.to_h.fetch(:label)
35
- end
36
- end
37
-
38
- def add_include
39
- client.on(
40
- "-i",
41
- "--includes [a,b,c]",
42
- Array,
43
- %(Include pattern list. Default: #{CLI::Configuration::Loader.call.includes}.)
44
- ) do |value|
45
- list = Array value
46
- options[:includes] = list.empty? ? configuration.to_h.fetch(:includes) : list
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "optparse"
4
-
5
- module Tocer
6
- module CLI
7
- module Parsers
8
- CLIENT = OptionParser.new nil, 40, " "
9
- end
10
- end
11
- end