jekyll-geo-kit 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/CHANGELOG.md +12 -0
- data/LICENSE +21 -0
- data/README.md +111 -0
- data/lib/jekyll-geo-kit/markdown_alternates/body.rb +74 -0
- data/lib/jekyll-geo-kit/markdown_alternates/config.rb +61 -0
- data/lib/jekyll-geo-kit/markdown_alternates/filters.rb +25 -0
- data/lib/jekyll-geo-kit/markdown_alternates/generator.rb +43 -0
- data/lib/jekyll-geo-kit/markdown_alternates/page.rb +27 -0
- data/lib/jekyll-geo-kit/markdown_alternates.rb +33 -0
- data/lib/jekyll-geo-kit/version.rb +7 -0
- data/lib/jekyll-geo-kit.rb +13 -0
- metadata +110 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 474d52c9e7b0c7dd088a685112ac2bd84a0e047e1c07991a648dc460620d4014
|
|
4
|
+
data.tar.gz: 4e3f157daadd1fc35543f485b908e66e60a2f913edb2d02350c15198cfbe9ea6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: fe744eb153718d96d5da26b9502e3d735b03d232e84421cf1667ad27633e5f4acf168fcc68198d2f8d3d5e96b65953ff50e5ddaaefc3648713becc59ab70fd31
|
|
7
|
+
data.tar.gz: b228bc8d8bf9d8258cbb274fcbfc855aa4193824974b21cdb094729fb3645b752b1b4f248ebb8eb826b941a62c31d87ec9e904e7cbd8d0db167734a2f6d2bcfd
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.1.0
|
|
6
|
+
|
|
7
|
+
- Extracted from `rahendablog.github.io`'s `_plugins/md_alternates.rb`.
|
|
8
|
+
- Generates a Markdown alternate at `/<slug>.md` for every written document in
|
|
9
|
+
the configured collections.
|
|
10
|
+
- Configurable through `markdown_alternates:` in `_config.yml`: `enabled`,
|
|
11
|
+
`collections`, `index`, `extension`, `skip_key`, `authors_data`.
|
|
12
|
+
- Adds the `markdown_alternate_url` Liquid filter.
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rahenda
|
|
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,111 @@
|
|
|
1
|
+
## About jekyll-geo-kit
|
|
2
|
+
|
|
3
|
+
A Jekyll plugin that serves every post as clean Markdown alongside its HTML, so
|
|
4
|
+
LLM crawlers and AI agents can read your content without parsing a page — GEO
|
|
5
|
+
(Generative Engine Optimization).
|
|
6
|
+
|
|
7
|
+
[](https://github.com/rahendatri/jekyll-geo-kit/actions/workflows/ci.yml)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Quick start
|
|
11
|
+
|
|
12
|
+
Add the gem to your site's `Gemfile`, in the `:jekyll_plugins` group so Bundler
|
|
13
|
+
loads it for you:
|
|
14
|
+
|
|
15
|
+
```ruby
|
|
16
|
+
group :jekyll_plugins do
|
|
17
|
+
gem "jekyll-geo-kit"
|
|
18
|
+
end
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then run `bundle install`.
|
|
22
|
+
|
|
23
|
+
If you prefer to list your plugins in configuration instead, add it to
|
|
24
|
+
`_config.yml`:
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
plugins:
|
|
28
|
+
- jekyll-geo-kit
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
That's it ! The plugin generates `.md` for every post.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Using GitHub Pages
|
|
35
|
+
|
|
36
|
+
`jekyll-geo-kit` is a third-party plugin, so GitHub's own Jekyll builder will not
|
|
37
|
+
run it.
|
|
38
|
+
|
|
39
|
+
Build your own workflow instead:
|
|
40
|
+
|
|
41
|
+
1. Use or adapt the example here : [custom-jekyll-github-action](https://github.com/rahendatri/rahendatri.github.io/blob/main/.github/workflows/jekyll.yml)
|
|
42
|
+
2. Activate the custom Github Pages workflow by choosing `Github Actions` in the following place: `<project-settings> / Pages / Build and Deployment / Source`
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## What it does
|
|
47
|
+
|
|
48
|
+
jekyll-geo-kit generates a Markdown alternate at `/<slug>.md` for every written
|
|
49
|
+
document in the configured collections. Each one contains:
|
|
50
|
+
|
|
51
|
+
* A pointer to your site index (`llms.txt` by default), so an agent that lands
|
|
52
|
+
on one document can discover the rest of the site
|
|
53
|
+
* The document's metadata as plain lines — title, canonical source URL,
|
|
54
|
+
publication date, resolved author name, language
|
|
55
|
+
* The description collapsed onto a single quoted line
|
|
56
|
+
* The body exactly as you wrote it, still in Markdown and never converted to
|
|
57
|
+
HTML
|
|
58
|
+
|
|
59
|
+
It also includes the `markdown_alternate_url` Liquid filter, so the
|
|
60
|
+
`<link rel="alternate" type="text/markdown">` you put in `head.html` derives its
|
|
61
|
+
path through the same logic the generator used and the two cannot drift apart.
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
> ## Site index
|
|
65
|
+
> Fetch the complete site index at: https://example.com/llms.txt
|
|
66
|
+
> Use it to discover every page on this site before exploring further.
|
|
67
|
+
|
|
68
|
+
# A published post
|
|
69
|
+
Source: https://example.com/2026/01/15/a-post.html
|
|
70
|
+
Published: 2026-01-15
|
|
71
|
+
Author: Rahenda
|
|
72
|
+
Language: en
|
|
73
|
+
|
|
74
|
+
> The post description, collapsed onto one line.
|
|
75
|
+
|
|
76
|
+
The body of the post, exactly as written, still in Markdown.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
While you could write this generator yourself, jekyll-geo-kit keeps the served
|
|
80
|
+
paths, the metadata format and the `rel=alternate` declaration in one place.
|
|
81
|
+
|
|
82
|
+
## What it doesn't do
|
|
83
|
+
|
|
84
|
+
jekyll-geo-kit only generates the Markdown documents and the filter that links
|
|
85
|
+
them. It does not write your `llms.txt` index — it links to whatever path you
|
|
86
|
+
point `index` at, and leaves creating that file to you or to another plugin.
|
|
87
|
+
|
|
88
|
+
It does not inject anything into your HTML. Declaring the alternates is a
|
|
89
|
+
one-line Liquid snippet you add to your own `head.html`, documented under
|
|
90
|
+
[Usage](docs/usage.md).
|
|
91
|
+
|
|
92
|
+
It does not convert HTML to Markdown. The alternates carry the document's
|
|
93
|
+
unrendered source body, so a document authored in Markdown round-trips exactly
|
|
94
|
+
while one authored in HTML is served as that HTML.
|
|
95
|
+
|
|
96
|
+
It covers collection documents — `posts` by default, any collection you
|
|
97
|
+
configure — and not standalone pages like `about.md`.
|
|
98
|
+
|
|
99
|
+
Being a third-party plugin, it does not run on GitHub's own Jekyll builder; see
|
|
100
|
+
[Using GitHub Pages](#using-github-pages) for the workflow that does.
|
|
101
|
+
|
|
102
|
+
## Documentation
|
|
103
|
+
|
|
104
|
+
For more information, see:
|
|
105
|
+
|
|
106
|
+
* [Usage](docs/usage.md)
|
|
107
|
+
* [Advanced usage](docs/advanced-usage.md)
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module GeoKit
|
|
5
|
+
module MarkdownAlternates
|
|
6
|
+
# The Markdown text served at /<slug>.md: a pointer to the site index, the
|
|
7
|
+
# document's metadata as plain lines, then its unrendered body.
|
|
8
|
+
class Body
|
|
9
|
+
def initialize(site, document, config)
|
|
10
|
+
@site = site
|
|
11
|
+
@document = document
|
|
12
|
+
@config = config
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def to_s
|
|
16
|
+
(banner + heading + description + content).join("\n")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def banner
|
|
22
|
+
index_url = @config.index_url
|
|
23
|
+
return [] if index_url.nil?
|
|
24
|
+
|
|
25
|
+
[
|
|
26
|
+
"> ## Site index",
|
|
27
|
+
"> Fetch the complete site index at: #{index_url}",
|
|
28
|
+
"> Use it to discover every page on this site before exploring further.",
|
|
29
|
+
"",
|
|
30
|
+
]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def heading
|
|
34
|
+
lines = ["# #{@document.data["title"]}"]
|
|
35
|
+
lines << "Source: #{MarkdownAlternates.absolute_url(@site, @document.url)}"
|
|
36
|
+
lines << "Published: #{date.strftime("%Y-%m-%d")}" if date
|
|
37
|
+
lines << "Author: #{author_name}" if author_name
|
|
38
|
+
lines << "Language: #{language}"
|
|
39
|
+
lines
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def description
|
|
43
|
+
text = @document.data["description"].to_s.strip.gsub(/\s+/, " ")
|
|
44
|
+
return [] if text.empty?
|
|
45
|
+
|
|
46
|
+
["", "> #{text}"]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def content
|
|
50
|
+
["", @document.content.to_s.strip, ""]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def date
|
|
54
|
+
@document.data["date"] || (@document.respond_to?(:date) ? @document.date : nil)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Prefers the matching entry in _data/<authors_data>.yml, then the site's
|
|
58
|
+
# single-author config.
|
|
59
|
+
def author_name
|
|
60
|
+
key = @document.data["author"].to_s
|
|
61
|
+
author = @site.data.dig(@config.authors_data, key) || {}
|
|
62
|
+
name = author["name"] if author.is_a?(Hash)
|
|
63
|
+
name ||= @site.config.dig("author", "name")
|
|
64
|
+
name ||= (key unless key.empty?)
|
|
65
|
+
name
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def language
|
|
69
|
+
@document.data["lang"] || @site.config["lang"] || "en"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module GeoKit
|
|
5
|
+
module MarkdownAlternates
|
|
6
|
+
# The `markdown_alternates:` block of _config.yml, with the defaults a site
|
|
7
|
+
# gets when it says nothing at all.
|
|
8
|
+
class Config
|
|
9
|
+
DEFAULTS = {
|
|
10
|
+
"enabled" => true,
|
|
11
|
+
"collections" => ["posts"],
|
|
12
|
+
"index" => "/llms.txt",
|
|
13
|
+
"extension" => ".md",
|
|
14
|
+
"skip_key" => "unlisted",
|
|
15
|
+
"authors_data" => "authors",
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
def initialize(site)
|
|
19
|
+
@site = site
|
|
20
|
+
overrides = site.config["markdown_alternates"]
|
|
21
|
+
@options = DEFAULTS.merge(overrides.is_a?(Hash) ? overrides : {})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def enabled?
|
|
25
|
+
@options["enabled"] != false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def collections
|
|
29
|
+
Array(@options["collections"]).map(&:to_s)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def extension
|
|
33
|
+
ext = @options["extension"].to_s
|
|
34
|
+
ext.empty? ? DEFAULTS["extension"] : ext
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Front-matter key that excludes a document from the alternates, e.g.
|
|
38
|
+
# `unlisted: true`. Set to nil/false to generate one for every document.
|
|
39
|
+
def skip_key
|
|
40
|
+
key = @options["skip_key"]
|
|
41
|
+
return nil if key.nil? || key == false || key.to_s.empty?
|
|
42
|
+
|
|
43
|
+
key.to_s
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def authors_data
|
|
47
|
+
@options["authors_data"].to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Absolute URL of the site index linked at the top of every alternate, or
|
|
51
|
+
# nil when the site has none and the banner should be left out.
|
|
52
|
+
def index_url
|
|
53
|
+
path = @options["index"]
|
|
54
|
+
return nil if path.nil? || path == false || path.to_s.empty?
|
|
55
|
+
|
|
56
|
+
MarkdownAlternates.absolute_url(@site, path)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module GeoKit
|
|
5
|
+
module MarkdownAlternates
|
|
6
|
+
# Liquid filter so a template links the alternate through the same path
|
|
7
|
+
# logic the generator used:
|
|
8
|
+
#
|
|
9
|
+
# <link rel="alternate" type="text/markdown"
|
|
10
|
+
# href="{{ page.url | markdown_alternate_url }}">
|
|
11
|
+
module Filters
|
|
12
|
+
def markdown_alternate_url(url)
|
|
13
|
+
site = @context.registers[:site]
|
|
14
|
+
extension = Config.new(site).extension
|
|
15
|
+
path = MarkdownAlternates.alternate_path(url, extension)
|
|
16
|
+
|
|
17
|
+
baseurl = site.config["baseurl"].to_s.chomp("/")
|
|
18
|
+
"#{baseurl}#{path}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Liquid::Template.register_filter(Jekyll::GeoKit::MarkdownAlternates::Filters)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module GeoKit
|
|
5
|
+
module MarkdownAlternates
|
|
6
|
+
class Generator < Jekyll::Generator
|
|
7
|
+
safe true
|
|
8
|
+
priority :low
|
|
9
|
+
|
|
10
|
+
def generate(site)
|
|
11
|
+
config = Config.new(site)
|
|
12
|
+
return unless config.enabled?
|
|
13
|
+
|
|
14
|
+
documents(site, config).each do |document|
|
|
15
|
+
next if skip?(document, config)
|
|
16
|
+
|
|
17
|
+
site.pages << Page.new(site, document, config)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def documents(site, config)
|
|
24
|
+
config.collections.flat_map do |label|
|
|
25
|
+
collection = site.collections[label]
|
|
26
|
+
collection ? collection.docs : []
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Leaves out drafts, `published: false`, output-less collections and
|
|
31
|
+
# anything the site marks with the configured skip key.
|
|
32
|
+
def skip?(document, config)
|
|
33
|
+
return true unless document.write?
|
|
34
|
+
|
|
35
|
+
key = config.skip_key
|
|
36
|
+
return false if key.nil?
|
|
37
|
+
|
|
38
|
+
document.data[key] == true
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module GeoKit
|
|
5
|
+
module MarkdownAlternates
|
|
6
|
+
# The generated page for one document's Markdown alternate.
|
|
7
|
+
#
|
|
8
|
+
# The source name ends in .txt on purpose: Jekyll picks its converter from
|
|
9
|
+
# the source extension, so a .txt name leaves the Markdown body alone, while
|
|
10
|
+
# the permalink decides the served path (/<slug>.md) and the output
|
|
11
|
+
# extension. GitHub Pages serves .md as text/markdown; charset=utf-8.
|
|
12
|
+
class Page < Jekyll::PageWithoutAFile
|
|
13
|
+
def initialize(site, document, config)
|
|
14
|
+
super(site, site.source, "", "#{document.basename_without_ext}.txt")
|
|
15
|
+
|
|
16
|
+
self.data = {
|
|
17
|
+
"layout" => nil,
|
|
18
|
+
"permalink" => MarkdownAlternates.alternate_path(document.url, config.extension),
|
|
19
|
+
"sitemap" => false,
|
|
20
|
+
"title" => document.data["title"],
|
|
21
|
+
}
|
|
22
|
+
self.content = Body.new(site, document, config).to_s
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "markdown_alternates/config"
|
|
4
|
+
require_relative "markdown_alternates/body"
|
|
5
|
+
require_relative "markdown_alternates/page"
|
|
6
|
+
require_relative "markdown_alternates/generator"
|
|
7
|
+
require_relative "markdown_alternates/filters"
|
|
8
|
+
|
|
9
|
+
# Markdown alternates: /<slug>.md for every published document.
|
|
10
|
+
#
|
|
11
|
+
# An AI agent that lands on a page can fetch the same text as Markdown instead
|
|
12
|
+
# of parsing the HTML, and finds a pointer to the site index at the top of it.
|
|
13
|
+
# Declare the pages from head.html with
|
|
14
|
+
# <link rel="alternate" type="text/markdown">.
|
|
15
|
+
module Jekyll
|
|
16
|
+
module GeoKit
|
|
17
|
+
module MarkdownAlternates
|
|
18
|
+
# Joins site.url and site.baseurl onto an absolute path. Jekyll's own
|
|
19
|
+
# absolute_url filter needs a Liquid context, so the generator does it here.
|
|
20
|
+
def self.absolute_url(site, path)
|
|
21
|
+
base = site.config["url"].to_s.chomp("/")
|
|
22
|
+
baseurl = site.config["baseurl"].to_s
|
|
23
|
+
baseurl = "" if baseurl == "/"
|
|
24
|
+
"#{base}#{baseurl.chomp("/")}#{path}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The served path of a document's Markdown alternate: /a/post/ -> /a/post.md
|
|
28
|
+
def self.alternate_path(url, extension = ".md")
|
|
29
|
+
url.to_s.sub(%r{\.html\z}, "").sub(%r{/\z}, "") + extension
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "jekyll"
|
|
4
|
+
|
|
5
|
+
require_relative "jekyll-geo-kit/version"
|
|
6
|
+
require_relative "jekyll-geo-kit/markdown_alternates"
|
|
7
|
+
|
|
8
|
+
# GEO (Generative Engine Optimization) features for a Jekyll site, one module
|
|
9
|
+
# per feature.
|
|
10
|
+
module Jekyll
|
|
11
|
+
module GeoKit
|
|
12
|
+
end
|
|
13
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jekyll-geo-kit
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Rahenda
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-10-24 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: '4.0'
|
|
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: '4.0'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: rake
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '13.0'
|
|
40
|
+
type: :development
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '13.0'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: rspec
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '3.13'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '3.13'
|
|
61
|
+
description: Generates /<slug>.md companions for each post, declared via rel=alternate
|
|
62
|
+
type=text/markdown, so LLM crawlers and AI agents can fetch clean Markdown instead
|
|
63
|
+
of parsing HTML. Each document links back to the site's llms.txt index.
|
|
64
|
+
email:
|
|
65
|
+
- rahendatri@users.noreply.github.com
|
|
66
|
+
executables: []
|
|
67
|
+
extensions: []
|
|
68
|
+
extra_rdoc_files: []
|
|
69
|
+
files:
|
|
70
|
+
- CHANGELOG.md
|
|
71
|
+
- LICENSE
|
|
72
|
+
- README.md
|
|
73
|
+
- lib/jekyll-geo-kit.rb
|
|
74
|
+
- lib/jekyll-geo-kit/markdown_alternates.rb
|
|
75
|
+
- lib/jekyll-geo-kit/markdown_alternates/body.rb
|
|
76
|
+
- lib/jekyll-geo-kit/markdown_alternates/config.rb
|
|
77
|
+
- lib/jekyll-geo-kit/markdown_alternates/filters.rb
|
|
78
|
+
- lib/jekyll-geo-kit/markdown_alternates/generator.rb
|
|
79
|
+
- lib/jekyll-geo-kit/markdown_alternates/page.rb
|
|
80
|
+
- lib/jekyll-geo-kit/version.rb
|
|
81
|
+
homepage: https://github.com/rahendatri/jekyll-geo-kit
|
|
82
|
+
licenses:
|
|
83
|
+
- MIT
|
|
84
|
+
metadata:
|
|
85
|
+
source_code_uri: https://github.com/rahendatri/jekyll-geo-kit
|
|
86
|
+
bug_tracker_uri: https://github.com/rahendatri/jekyll-geo-kit/issues
|
|
87
|
+
changelog_uri: https://github.com/rahendatri/jekyll-geo-kit/blob/main/CHANGELOG.md
|
|
88
|
+
keywords: jekyll, geo, generative-engine-optimization, llms-txt, markdown, ai-crawlers,
|
|
89
|
+
seo
|
|
90
|
+
post_install_message:
|
|
91
|
+
rdoc_options: []
|
|
92
|
+
require_paths:
|
|
93
|
+
- lib
|
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - ">="
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '3.0'
|
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
requirements: []
|
|
105
|
+
rubygems_version: 3.5.22
|
|
106
|
+
signing_key:
|
|
107
|
+
specification_version: 4
|
|
108
|
+
summary: 'GEO (Generative Engine Optimization) for Jekyll: serve every post as a Markdown
|
|
109
|
+
alternate'
|
|
110
|
+
test_files: []
|