jekyll-titles-from-content 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ff8a481d7cdb1d7b6f9aa7dc89237c2161ff4a961a7223660306397c1805c5e0
4
+ data.tar.gz: 1643e62e6242c0732b70df2fd0318b18bf0ec5a0e26a14cc6289db4ae4846c15
5
+ SHA512:
6
+ metadata.gz: 88dbff3cc44e0b615698eb92d688a7fbd3fea8da2de8fac572c14dd3bf1f047da3ed333953e518a0712951987bd710b31ca98894117c70ac3082f3aff3092954
7
+ data.tar.gz: b715015864a05e78f124b67fefb412658a6e1060a82b8de2c4f176902abdc88e772eb8d923f625fabc8772bb9aa97636f1a9d784dc50eb64a1be7482192ca0e1
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Colin Seymour
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,56 @@
1
+ # Jekyll Titles from Content
2
+
3
+ [![Actions Status](https://github.com/lildude/jekyll-titles-from-content/workflows/Testing/badge.svg)](https://github.com/lildude/jekyll-titles-from-content/actions)
4
+
5
+ A Jekyll plugin to pull the page title from the first few words of the first line of the content if a title isn't set.
6
+
7
+ ## What it does
8
+
9
+ If you have a Jekyll page that doesn't have a title specified in the YAML Front Matter, this plugin instructs Jekyll to use that first few words of the content as the page's title.
10
+
11
+ ## Why
12
+
13
+ Because lots of plugins and templates rely on `page.title`. This doesn't play nicely with micro blogging which doesn't require a title.
14
+
15
+ ## Usage
16
+
17
+ 1. Add the following to your site's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'jekyll-titles-from-content'
21
+ ```
22
+
23
+ 2. Add the following to your site's config file:
24
+
25
+ ```yml
26
+ plugins:
27
+ - jekyll-titles-from-content
28
+ ```
29
+
30
+ Note: If you are using a Jekyll version less than 3.5.0, use the `gems` key instead of `plugins`.
31
+
32
+ ## Configuration
33
+
34
+ Configuration options are optional and placed in `_config.yml` under the `titles_from_content` key. They default to:
35
+
36
+ ```yml
37
+ titles_from_content:
38
+ enabled: true # Easily toggle the plugin from your configuration.
39
+ words: 5 # The number of words to use for the title.
40
+ collections: true # Apply the plugin to collections. Posts are collections.
41
+ dotdotdot: ... # The character(s) you'd like to append to truncated titles.
42
+ ```
43
+
44
+ ### Processing Collections
45
+
46
+ If you want to enable this plugin for collection items, set the `collections` option to `true`.
47
+
48
+ Since collection items (including posts) already have a title inferred from their filename, this option changes the behavior of this plugin to override the inferred title.
49
+
50
+ ### Disabling
51
+
52
+ Even if the plugin is enabled (e.g., via the `:jekyll_plugins` group in your Gemfile) you can disable it by setting the `enabled` key to `false`.
53
+
54
+ ### Credit
55
+
56
+ This plugin is heavily inspired by the [jekyll-titles-from-headings](https://github.com/benbalter/jekyll-titles-from-headings) plugin.
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require "jekyll-titles-from-content/generator"
5
+
6
+ module JekyllTitlesFromContent
7
+ autoload :Context, "jekyll-titles-from-content/context"
8
+ autoload :Filters, "jekyll-titles-from-content/filters"
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllTitlesFromContent
4
+ class Context
5
+ attr_reader :site
6
+
7
+ def initialize(site)
8
+ @site = site
9
+ end
10
+
11
+ def registers
12
+ { :site => site }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllTitlesFromContent
4
+ class Filters
5
+ include Jekyll::Filters
6
+ include Liquid::StandardFilters
7
+
8
+ def initialize(site)
9
+ @site = site
10
+ @context = JekyllTitlesFromContent::Context.new(site)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllTitlesFromContent
4
+ class Generator < Jekyll::Generator
5
+ attr_accessor :site
6
+
7
+ CONVERTER_CLASS = Jekyll::Converters::Markdown
8
+ STRIP_MARKUP_FILTERS = [:markdownify, :strip_html, :normalize_whitespace].freeze
9
+
10
+ # Regex to strip extra markup still present after markdownify
11
+ # (footnotes at the moment).
12
+ EXTRA_MARKUP_REGEX = %r!\[\^[^\]]*\]!.freeze
13
+
14
+ CONFIG_KEY = "titles_from_content"
15
+ ENABLED_KEY = "enabled"
16
+ WORDS_KEY = "words"
17
+ COLLECTIONS_KEY = "collections"
18
+ DOTDOTDOT_KEY = "dotdotdot"
19
+
20
+ safe true
21
+ priority :lowest
22
+
23
+ def initialize(site)
24
+ @site = site
25
+ end
26
+
27
+ def generate(site)
28
+ @site = site
29
+ return if disabled?
30
+
31
+ documents = site.pages
32
+ documents = site.pages + site.docs_to_write if collections?
33
+
34
+ documents.each do |document|
35
+ next unless should_add_title?(document)
36
+ next if document.is_a?(Jekyll::StaticFile)
37
+
38
+ document.data["title"] = title_for(document)
39
+ end
40
+ end
41
+
42
+ def should_add_title?(document)
43
+ markdown?(document) && !title?(document)
44
+ end
45
+
46
+ def title?(document)
47
+ !inferred_title?(document) && !document.data["title"].nil?
48
+ end
49
+
50
+ def markdown?(document)
51
+ markdown_converter.matches(document.extname)
52
+ end
53
+
54
+ def markdown_converter
55
+ @markdown_converter ||= site.find_converter_instance(CONVERTER_CLASS)
56
+ end
57
+
58
+ def truncate(string, count, cont = "")
59
+ spl = string.split
60
+ tr = spl.first(count).join(" ")
61
+ tr += cont if spl.length > count
62
+ tr
63
+ end
64
+
65
+ def title_for(document)
66
+ return document.data["title"] if title?(document)
67
+
68
+ first_line = document.content.split("\n").find { |l| l unless strip_markup(l).empty? }
69
+ return truncate(strip_markup(first_line), count, dotdotdot) unless first_line.nil?
70
+
71
+ document.data["title"] # If we can't produce a title, we use the inferred one.
72
+ rescue ArgumentError => e
73
+ raise e unless e.to_s.start_with?("invalid byte sequence in UTF-8")
74
+ end
75
+
76
+ private
77
+
78
+ def strip_markup(string)
79
+ STRIP_MARKUP_FILTERS.reduce(string) do |memo, method|
80
+ filters.public_send(method, memo)
81
+ end.gsub(EXTRA_MARKUP_REGEX, "")
82
+ end
83
+
84
+ def option(key)
85
+ site.config[CONFIG_KEY] && site.config[CONFIG_KEY][key]
86
+ end
87
+
88
+ def disabled?
89
+ option(ENABLED_KEY) == false
90
+ end
91
+
92
+ def collections?
93
+ option(COLLECTIONS_KEY) == true
94
+ end
95
+
96
+ def dotdotdot
97
+ option(DOTDOTDOT_KEY) || ""
98
+ end
99
+
100
+ def count
101
+ option(WORDS_KEY) || 5
102
+ end
103
+
104
+ # Documents (posts and collection items) have their title inferred from the filename.
105
+ #
106
+ # This is a terribly slow hack as we're reading the YAML for every document, but I can't find
107
+ # a better way of doing this as I can't find a method of obtaining the original unprocessed
108
+ # frontmatter.
109
+ def inferred_title?(document)
110
+ return false unless document.is_a?(Jekyll::Document)
111
+
112
+ meta = read_yaml(File.dirname(document.path), File.basename(document.path))
113
+ !meta.key?("title")
114
+ end
115
+
116
+ def filters
117
+ @filters ||= JekyllTitlesFromContent::Filters.new(site)
118
+ end
119
+
120
+ # This is a slightly modified version of Jekyll::Convertible.read_yaml
121
+ def read_yaml(base, name)
122
+ filename = File.join(base, name)
123
+
124
+ begin
125
+ content = File.read(filename)
126
+ if content =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
127
+ content = $POSTMATCH # rubocop:disable Lint/UselessAssignment
128
+ data = SafeYAML.load(Regexp.last_match(1))
129
+ end
130
+ rescue SyntaxError => e
131
+ Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
132
+ raise e if site.config["strict_front_matter"]
133
+ rescue StandardError => e
134
+ Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
135
+ raise e if site.config["strict_front_matter"]
136
+ end
137
+
138
+ data || {}
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllTitlesFromContent
4
+ VERSION = "0.0.1"
5
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-titles-from-content
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Colin Seymour
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-10-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.3'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.3'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: guard
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-minitest
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: kramdown-parser-gfm
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: minitest-color
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rake
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.71'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.71'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rubocop-jekyll
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.10'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.10'
145
+ - !ruby/object:Gem::Dependency
146
+ name: simplecov
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '0.19'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.19'
159
+ description:
160
+ email:
161
+ - colin@symr.io
162
+ executables: []
163
+ extensions: []
164
+ extra_rdoc_files: []
165
+ files:
166
+ - LICENSE.md
167
+ - README.md
168
+ - lib/jekyll-titles-from-content.rb
169
+ - lib/jekyll-titles-from-content/context.rb
170
+ - lib/jekyll-titles-from-content/filters.rb
171
+ - lib/jekyll-titles-from-content/generator.rb
172
+ - lib/jekyll-titles-from-content/version.rb
173
+ homepage: https://github.com/lildude/jekyll-titles-from-content
174
+ licenses:
175
+ - MIT
176
+ metadata: {}
177
+ post_install_message:
178
+ rdoc_options: []
179
+ require_paths:
180
+ - lib
181
+ required_ruby_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ required_rubygems_version: !ruby/object:Gem::Requirement
187
+ requirements:
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ requirements: []
192
+ rubygems_version: 3.0.3
193
+ signing_key:
194
+ specification_version: 4
195
+ summary: A Jekyll plugin to pull the page title from the first X words of the content,
196
+ when none is specified.
197
+ test_files: []