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.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/README.md +56 -0
- data/lib/jekyll-titles-from-content.rb +9 -0
- data/lib/jekyll-titles-from-content/context.rb +15 -0
- data/lib/jekyll-titles-from-content/filters.rb +13 -0
- data/lib/jekyll-titles-from-content/generator.rb +141 -0
- data/lib/jekyll-titles-from-content/version.rb +5 -0
- metadata +197 -0
checksums.yaml
ADDED
@@ -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
|
data/LICENSE.md
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Jekyll Titles from Content
|
2
|
+
|
3
|
+
[](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,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
|
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: []
|