tocer 0.1.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ced1fb93f4c52c60a2ea5269d5dbb26f6987fb3a
4
- data.tar.gz: 9526ee10285dead69f802fbd995f48dd8c22061b
3
+ metadata.gz: 2f12d5a3b405216b970f03b881e0a36c00e0091f
4
+ data.tar.gz: 898e0ba35499767b75fe50e88f15e62f6a95bb6f
5
5
  SHA512:
6
- metadata.gz: 21eb3f82c3020bc95a939f01d02f63752a5b060750606e68398f9e9cb8419f603998391dab13b71474df195771686f24742fc86c3c88737892064a0e2dbdafcf
7
- data.tar.gz: b9bcc33e6ce0dbed48268305c7ea499ee765d4d614571f2497340d8264f63ce552643d35deb59c29c78a1e3edefb39cb37b0f980500a2b42790c81940f2b9d4d
6
+ metadata.gz: 6da1ab64f2fba3c688711ddc88e6c732e6c19e2b29f4da278f8c4d9cff7fbb6d4f028a6969b042eed9539cce04e9ab1de2407d98d71537b3c239c4d706f6219f
7
+ data.tar.gz: 615fa828848a718049deec38252626d94d9a4d279a618109afa2c743580e5441f9c694d38077122ceedc8a6e4aa5de455b7deacfb55da240a1b841eb64db120a
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -9,14 +9,16 @@
9
9
 
10
10
  Tocer (a.k.a. Table of Contenter) is command line interface for generating table of contents for Markdown files.
11
11
 
12
- <!-- START doctoc generated TOC please keep comment here to allow auto update -->
13
- <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
12
+ <!-- Tocer[start]: Auto-generated, don't remove. -->
13
+
14
14
  # Table of Contents
15
15
 
16
16
  - [Features](#features)
17
17
  - [Requirements](#requirements)
18
18
  - [Setup](#setup)
19
19
  - [Usage](#usage)
20
+ - [Command Line Interface (CLI)](#command-line-interface-cli)
21
+ - [Customization](#customization)
20
22
  - [Tests](#tests)
21
23
  - [Versioning](#versioning)
22
24
  - [Code of Conduct](#code-of-conduct)
@@ -25,13 +27,13 @@ Tocer (a.k.a. Table of Contenter) is command line interface for generating table
25
27
  - [History](#history)
26
28
  - [Credits](#credits)
27
29
 
28
- <!-- END doctoc generated TOC please keep comment here to allow auto update -->
30
+ <!-- Tocer[finish]: Auto-generated, don't remove. -->
29
31
 
30
32
  # Features
31
33
 
32
34
  - Supports Markdown ATX-style headers. Example: `# Header`.
33
35
  - Does not support header suffixes. Example: `# Header #`.
34
- - Does not support header previxes without spaces. Example: `#Header`.
36
+ - Does not support header prefixes without spaces. Example: `#Header`.
35
37
  - Prepends table of contents to Markdown documents that don't have table of contents.
36
38
  - Replaces/updates Markdown documents that have existing table of contents.
37
39
 
@@ -56,6 +58,8 @@ For an insecure install, type the following (not recommended):
56
58
 
57
59
  # Usage
58
60
 
61
+ ## Command Line Interface (CLI)
62
+
59
63
  From the command line, type: `tocer help`
60
64
 
61
65
  tocer -e, [--edit] # Edit Tocer settings in default editor.
@@ -66,8 +70,8 @@ From the command line, type: `tocer help`
66
70
  To add Tocer support, add the following at the correct position within your Markdown files:
67
71
 
68
72
  ```
69
- <!-- Tocer[start]: Auto-generated, don't remove. -->
70
- <!-- Tocer[finish]: Auto-generated, don't remove. -->
73
+ <!-- Tocer[start] -->
74
+ <!-- Tocer[finish] -->
71
75
  ```
72
76
 
73
77
  Alternatively, you can run `tocer -g <file_path>` on a file that does not have Tocer support and it will prepend the above
@@ -77,6 +81,25 @@ In the case that Tocer has already auto-generated a table of contents for a Mark
77
81
  contents has become stale, or placement of the table of contents has changed you can re-run Tocer on that file to auto-
78
82
  update it with new table of contents.
79
83
 
84
+ ## Customization
85
+
86
+ If desired, this gem supports global customization via the `~/.tocerrc` file. Order of precedence is determined in the
87
+ following order (with the last one taking top priority):
88
+
89
+ 0. Global `~/.tocerrc`.
90
+ 0. CLI option. Example: `tocer --generate README.md --label "Custom Label"`
91
+
92
+ Any setting provided to the CLI during runtime would trump the global setting. The global setting is the weakest of all
93
+ but great for situations where custom settings should be applied to *all* projects.
94
+
95
+ The `~/.tocerrc` uses the following default settings:
96
+
97
+ :label: "# Table of Contents"
98
+
99
+ Each `~/.tocerrc` setting can be configured as follows:
100
+
101
+ - `label`: The header label for the table of contents. Default: "# Table of Contents".
102
+
80
103
  # Tests
81
104
 
82
105
  To test, run:
data/lib/tocer.rb CHANGED
@@ -1,5 +1,8 @@
1
+ require "tocer/elements/comment_block"
2
+ require "tocer/parsers/header"
3
+ require "tocer/transformers/link"
4
+ require "tocer/transformers/text"
1
5
  require "tocer/builder"
2
- require "tocer/commenter"
6
+ require "tocer/configuration"
3
7
  require "tocer/identity"
4
- require "tocer/transformer"
5
8
  require "tocer/writer"
data/lib/tocer/builder.rb CHANGED
@@ -1,32 +1,52 @@
1
1
  module Tocer
2
- # Builds table of contents for a document in Markdown.
2
+ # Builds a table of contents for a Markdown document.
3
3
  class Builder
4
- def initialize lines, label: "# Table of Contents", transformer: Transformer, commenter: Commenter
4
+ def initialize lines, label: "# Table of Contents", comment_block: Elements::CommentBlock
5
5
  @lines = lines
6
6
  @label = label
7
- @transformer = transformer
8
- @commenter = commenter.new
7
+ @comment_block = comment_block.new
8
+ @url_count = Hash.new { |hash, key| hash[key] = 0 }
9
9
  end
10
10
 
11
11
  def headers
12
- lines.select { |line| line.start_with? "#" }
12
+ lines.select { |line| line.start_with? Parsers::Header.punctuation }
13
13
  end
14
14
 
15
15
  def build
16
16
  return "" if headers.empty?
17
17
 
18
- content = "#{commenter.start}\n\n"
18
+ content = "#{comment_block.start}\n\n"
19
19
  content << "#{label}\n\n"
20
20
  content << headers_as_links.join("\n")
21
- content << "\n\n#{commenter.finish}\n\n"
21
+ content << "\n\n#{comment_block.finish}\n\n"
22
22
  end
23
23
 
24
24
  private
25
25
 
26
- attr_reader :lines, :label, :transformer, :commenter
26
+ attr_reader :lines, :label, :comment_block, :url_count
27
+
28
+ def acquire_transfomer header
29
+ case
30
+ when header =~ /\[.+\]\(.+\)/
31
+ Transformers::Link.new header
32
+ else
33
+ Transformers::Text.new header
34
+ end
35
+ end
36
+
37
+ def url_suffix url
38
+ url_count[url].zero? ? "" : url_count[url]
39
+ end
40
+
41
+ def transform header
42
+ transformer = acquire_transfomer header
43
+ link = transformer.transform url_suffix: url_suffix(transformer.url)
44
+ url_count[transformer.url] += 1
45
+ link
46
+ end
27
47
 
28
48
  def headers_as_links
29
- headers.map { |header| transformer.new(header).transform }
49
+ headers.map { |header| transform header }
30
50
  end
31
51
  end
32
52
  end
data/lib/tocer/cli.rb CHANGED
@@ -13,13 +13,15 @@ module Tocer
13
13
 
14
14
  def initialize args = [], options = {}, config = {}
15
15
  super args, options, config
16
+ @configuration = Configuration.new
16
17
  end
17
18
 
18
19
  desc "-g, [--generate=GENERATE]", "Generate table of contents."
19
20
  map %w(-g --generate) => :generate
21
+ method_option :label, aliases: "-l", desc: "Custom label", type: :string, default: "# Table of Contents"
20
22
  def generate file_path
21
- writer = Writer.new file_path
22
- writer.write
23
+ update_configuration! options
24
+ Writer.new(file_path, label: configuration.label).write
23
25
  say "Generated table of contents: #{file_path}."
24
26
  end
25
27
 
@@ -42,5 +44,14 @@ module Tocer
42
44
  def help task = nil
43
45
  say && super
44
46
  end
47
+
48
+ private
49
+
50
+ attr_reader :configuration
51
+
52
+ def update_configuration! options
53
+ return if options[:label] == "# Table of Contents"
54
+ configuration.label = options[:label]
55
+ end
45
56
  end
46
57
  end
@@ -0,0 +1,26 @@
1
+ module Tocer
2
+ # Default configuration for gem with support for custom settings.
3
+ class Configuration
4
+ attr_reader :file_path
5
+ attr_writer :label
6
+
7
+ def initialize file_path: File.join(ENV["HOME"], Identity.file_name)
8
+ @file_path = file_path
9
+ @settings = load_settings
10
+ end
11
+
12
+ def label
13
+ @label ||= settings.fetch(:label, "# Table of Contents")
14
+ end
15
+
16
+ private
17
+
18
+ attr_reader :settings
19
+
20
+ def load_settings
21
+ return {} unless File.exist?(file_path)
22
+ yaml = YAML.load_file file_path
23
+ yaml.is_a?(Hash) ? yaml : {}
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ module Tocer
2
+ module Elements
3
+ # Represents a table of contents start and finish comment block.
4
+ class CommentBlock
5
+ def initialize start_id: "Tocer[start]", finish_id: "Tocer[finish]", message: "Auto-generated, don't remove."
6
+ @start_id = start_id
7
+ @finish_id = finish_id
8
+ @message = message
9
+ end
10
+
11
+ def start
12
+ comment start_id, message
13
+ end
14
+
15
+ def start_index collection
16
+ index collection, start_id
17
+ end
18
+
19
+ def finish
20
+ comment finish_id, message
21
+ end
22
+
23
+ def finish_index collection
24
+ index collection, finish_id
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :start_id, :finish_id, :message
30
+
31
+ def comment id, message
32
+ "<!-- #{id}: #{message} -->"
33
+ end
34
+
35
+ def index collection, id
36
+ collection.index { |line| line =~ /\<\!\-\-.*#{Regexp.escape id}.*\-\-\>/ }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -10,7 +10,7 @@ module Tocer
10
10
  end
11
11
 
12
12
  def self.version
13
- "0.1.0"
13
+ "1.0.0"
14
14
  end
15
15
 
16
16
  def self.version_label
@@ -0,0 +1,26 @@
1
+ module Tocer
2
+ module Parsers
3
+ # Represents a Markdown header.
4
+ class Header
5
+ def self.punctuation
6
+ "#"
7
+ end
8
+
9
+ def initialize markdown
10
+ @markdown = markdown
11
+ end
12
+
13
+ def prefix
14
+ String markdown[/#{self.class.punctuation}{1,}/]
15
+ end
16
+
17
+ def content
18
+ markdown[prefix.length + 1, markdown.length].strip
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :markdown
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ require "refinements/array_extensions"
2
+
3
+ module Tocer
4
+ module Transformers
5
+ # Transforms a Markdown header (embedded link) into a table of contents link.
6
+ class Link
7
+ using Refinements::ArrayExtensions
8
+
9
+ def initialize text, header: Parsers::Header
10
+ @header = header.new text
11
+ end
12
+
13
+ def label
14
+ header.content.gsub(embedded_link, embedded_link_label)
15
+ end
16
+
17
+ def url
18
+ label.downcase.gsub(/\s/, "-").gsub(/[^\w\-]+/, "")
19
+ end
20
+
21
+ def transform url_suffix: ""
22
+ modified_url = [url, url_suffix.to_s].compress.join "-"
23
+ "#{indented_bullet}[#{label}](##{modified_url})"
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :header
29
+
30
+ def embedded_link_label
31
+ header.content[/\[(.*)\]/, 1]
32
+ end
33
+
34
+ def embedded_link_url
35
+ header.content[/\((.*)\)/, 1]
36
+ end
37
+
38
+ def embedded_link
39
+ "[#{embedded_link_label}](#{embedded_link_url})"
40
+ end
41
+
42
+ def prefix_to_spaces
43
+ Array.new(header.prefix.length, " ").join
44
+ end
45
+
46
+ def indented_bullet
47
+ prefix_to_spaces.gsub(/\s{2}$/, "- ")
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,39 @@
1
+ require "refinements/array_extensions"
2
+
3
+ module Tocer
4
+ module Transformers
5
+ # Transforms a Markdown header (plain text) into a table of contents link.
6
+ class Text
7
+ using Refinements::ArrayExtensions
8
+
9
+ def initialize text, header: Parsers::Header
10
+ @header = header.new text
11
+ end
12
+
13
+ def label
14
+ header.content
15
+ end
16
+
17
+ def url
18
+ label.downcase.gsub(/\s/, "-").gsub(/[^\w\-]+/, "")
19
+ end
20
+
21
+ def transform url_suffix: ""
22
+ modified_url = [url, url_suffix.to_s].compress.join "-"
23
+ "#{indented_bullet}[#{label}](##{modified_url})"
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :header
29
+
30
+ def prefix_to_spaces
31
+ Array.new(header.prefix.length, " ").join
32
+ end
33
+
34
+ def indented_bullet
35
+ prefix_to_spaces.gsub(/\s{2}$/, "- ")
36
+ end
37
+ end
38
+ end
39
+ end
data/lib/tocer/writer.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  module Tocer
2
2
  # Writes table of contents to a Markdown document.
3
3
  class Writer
4
- def initialize file_path, builder: Builder, commenter: Commenter
4
+ def initialize file_path, label: "# Table of Contents", builder: Builder, comment_block: Elements::CommentBlock
5
5
  @file_path = file_path
6
6
  @file_lines = File.open(file_path).to_a
7
+ @label = label
7
8
  @builder = builder
8
- setup_indexes commenter.new, @file_lines
9
+ setup_indexes comment_block.new, @file_lines
9
10
  end
10
11
 
11
12
  def write
@@ -15,15 +16,15 @@ module Tocer
15
16
 
16
17
  private
17
18
 
18
- attr_reader :file_path, :file_lines, :start_index, :finish_index, :builder, :commenter
19
+ attr_reader :file_path, :file_lines, :label, :start_index, :finish_index, :builder, :comment_block
19
20
 
20
- def setup_indexes commenter, lines
21
- @start_index = commenter.start_index lines
22
- @finish_index = commenter.finish_index lines
21
+ def setup_indexes comment_block, lines
22
+ @start_index = comment_block.start_index lines
23
+ @finish_index = comment_block.finish_index lines
23
24
  end
24
25
 
25
26
  def content lines
26
- builder.new(lines).build
27
+ builder.new(lines, label: label).build
27
28
  end
28
29
 
29
30
  def remove_toc lines
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: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -30,36 +30,50 @@ cert_chain:
30
30
  aSif+qBc6oHD7EQWPF5cZkzkIURuwNwPBngZGxIKaMAgRhjGFXzUMAaq++r59cS9
31
31
  xTfQ4k6fglKEgpnLAXiKdo2c8Ym+X4rIKFfedQ==
32
32
  -----END CERTIFICATE-----
33
- date: 2015-11-15 00:00:00.000000000 Z
33
+ date: 2015-11-21 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: thor
37
37
  requirement: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: '0.19'
42
42
  type: :runtime
43
43
  prerelease: false
44
44
  version_requirements: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ">="
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '0'
48
+ version: '0.19'
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: thor_plus
51
51
  requirement: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ">="
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '0'
55
+ version: '2.1'
56
56
  type: :runtime
57
57
  prerelease: false
58
58
  version_requirements: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ">="
60
+ - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '0'
62
+ version: '2.1'
63
+ - !ruby/object:Gem::Dependency
64
+ name: refinements
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.0'
63
77
  - !ruby/object:Gem::Dependency
64
78
  name: rake
65
79
  requirement: !ruby/object:Gem::Requirement
@@ -301,13 +315,16 @@ files:
301
315
  - lib/tocer.rb
302
316
  - lib/tocer/builder.rb
303
317
  - lib/tocer/cli.rb
304
- - lib/tocer/commenter.rb
318
+ - lib/tocer/configuration.rb
319
+ - lib/tocer/elements/comment_block.rb
305
320
  - lib/tocer/identity.rb
321
+ - lib/tocer/parsers/header.rb
306
322
  - lib/tocer/tasks/rspec.rake
307
323
  - lib/tocer/tasks/rubocop.rake
308
- - lib/tocer/transformer.rb
324
+ - lib/tocer/transformers/link.rb
325
+ - lib/tocer/transformers/text.rb
309
326
  - lib/tocer/writer.rb
310
- homepage: https://www.alchemists.io
327
+ homepage: https://github.com/bkuhlmann/tocer
311
328
  licenses:
312
329
  - MIT
313
330
  metadata: {}
metadata.gz.sig CHANGED
Binary file
@@ -1,38 +0,0 @@
1
- module Tocer
2
- # Represents table of contents start and finish comments.
3
- class Commenter
4
- def initialize start_id: "Tocer[start]", finish_id: "Tocer[finish]", message: "Auto-generated, don't remove."
5
- @start_id = start_id
6
- @finish_id = finish_id
7
- @message = message
8
- end
9
-
10
- def start
11
- comment start_id, message
12
- end
13
-
14
- def start_index collection
15
- index collection, start
16
- end
17
-
18
- def finish
19
- comment finish_id, message
20
- end
21
-
22
- def finish_index collection
23
- index collection, finish
24
- end
25
-
26
- private
27
-
28
- attr_reader :start_id, :finish_id, :message
29
-
30
- def comment id, message
31
- "<!-- #{id}: #{message} -->"
32
- end
33
-
34
- def index collection, text
35
- collection.index { |line| line =~ /#{Regexp.escape text}/ }
36
- end
37
- end
38
- end
@@ -1,38 +0,0 @@
1
- module Tocer
2
- # Transforms Markdown headers into anchored links.
3
- class Transformer
4
- def initialize text
5
- @text = text
6
- end
7
-
8
- def pounds
9
- String text[/\#{1,}/]
10
- end
11
-
12
- def label
13
- return "" if text.empty?
14
- text[pounds.length + 1, text.length].strip
15
- end
16
-
17
- def bullet
18
- return "" if pounds.empty?
19
- pounds_to_spaces(pounds).gsub(/\s{2}$/, "- ")
20
- end
21
-
22
- def url
23
- label.downcase.gsub(/\s/, "-").gsub(/[^\w\-\+\&]+/, "")
24
- end
25
-
26
- def transform
27
- "#{bullet}[#{label}](##{url})"
28
- end
29
-
30
- private
31
-
32
- attr_reader :text
33
-
34
- def pounds_to_spaces pounds
35
- Array.new(pounds.length, " ").join
36
- end
37
- end
38
- end