jekyll-vitepress-theme 1.10.0 → 1.10.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 +4 -4
- data/assets/css/vitepress-overrides.css +1 -1
- data/lib/jekyll/vitepress_theme/hooks.rb +1 -20
- data/lib/jekyll/vitepress_theme/last_updated.rb +154 -0
- data/lib/jekyll/vitepress_theme/llms.rb +1 -2
- data/lib/jekyll/vitepress_theme/markdown_export.rb +2 -3
- data/lib/jekyll/vitepress_theme/seo.rb +1 -2
- data/lib/jekyll/vitepress_theme/version.rb +1 -1
- data/lib/jekyll-vitepress-theme.rb +1 -0
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0fa9bd9f39f9a07a853282a881aff54b24f4adde9c87f9c2f03b89bcafff8617
|
|
4
|
+
data.tar.gz: 19d2551ffa4497e178771471091d3655dd0678e6cbcd823e79eefd6c617546ef
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5041e3e3a4019083374bba8ead0db79724322337d945605168214d3e430ac225c925a2b41040154431fd55da644fdcf0f42c2058daf99d326903f1ea3a77c61
|
|
7
|
+
data.tar.gz: 87e47129bd88e563ba4187118029c1de8311a7662cc7233432a05a8dc3911013b84c0b930bb582c79dd88bf23ad4d570326b9d93756db22016720f36eed38466
|
|
@@ -3,7 +3,7 @@ require 'rouge'
|
|
|
3
3
|
|
|
4
4
|
module Jekyll
|
|
5
5
|
module VitePressTheme
|
|
6
|
-
# rubocop:disable Metrics/ModuleLength
|
|
6
|
+
# rubocop:disable-next Metrics/ModuleLength
|
|
7
7
|
module Sidebar
|
|
8
8
|
module_function
|
|
9
9
|
|
|
@@ -243,7 +243,6 @@ module Jekyll
|
|
|
243
243
|
)
|
|
244
244
|
end
|
|
245
245
|
end
|
|
246
|
-
# rubocop:enable Metrics/ModuleLength
|
|
247
246
|
|
|
248
247
|
module SearchIndex
|
|
249
248
|
module_function
|
|
@@ -319,24 +318,6 @@ module Jekyll
|
|
|
319
318
|
end
|
|
320
319
|
end
|
|
321
320
|
|
|
322
|
-
module LastUpdated
|
|
323
|
-
module_function
|
|
324
|
-
|
|
325
|
-
def source_file_time(site, path)
|
|
326
|
-
return nil unless path
|
|
327
|
-
|
|
328
|
-
source_path = if Pathname.new(path).absolute?
|
|
329
|
-
path
|
|
330
|
-
else
|
|
331
|
-
File.join(site.source, path)
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
return nil unless File.file?(source_path)
|
|
335
|
-
|
|
336
|
-
File.mtime(source_path).utc
|
|
337
|
-
end
|
|
338
|
-
end
|
|
339
|
-
|
|
340
321
|
module RougeStyles
|
|
341
322
|
module_function
|
|
342
323
|
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
require 'pathname'
|
|
5
|
+
|
|
6
|
+
module Jekyll
|
|
7
|
+
module VitePressTheme
|
|
8
|
+
# Dates each page by the last commit that touched its source file, read
|
|
9
|
+
# from one `git log` pass per build. Files Git cannot date reliably
|
|
10
|
+
# (untracked, locally modified, outside the repository, or older than a
|
|
11
|
+
# shallow clone's history) use their modification time instead.
|
|
12
|
+
module LastUpdated
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
FIELD_SEPARATOR = "\x1e"
|
|
16
|
+
|
|
17
|
+
# Git's view of the files under a site source: commit times keyed by
|
|
18
|
+
# real path, plus the paths whose working copy differs from HEAD.
|
|
19
|
+
class GitIndex
|
|
20
|
+
def self.empty
|
|
21
|
+
new({}, [])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(times, modified)
|
|
25
|
+
@times = times
|
|
26
|
+
@modified = modified.to_h { |path| [path, true] }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def time_for(path)
|
|
30
|
+
return nil if @modified.key?(path)
|
|
31
|
+
|
|
32
|
+
@times[path]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def source_file_time(site, path)
|
|
37
|
+
source_path = resolved_source_path(site, path)
|
|
38
|
+
return nil unless source_path
|
|
39
|
+
|
|
40
|
+
git_index(site).time_for(source_path) || File.mtime(source_path).utc
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def resolved_source_path(site, path)
|
|
44
|
+
return nil unless path
|
|
45
|
+
|
|
46
|
+
source_path = Pathname.new(path).absolute? ? path : File.join(site.source, path)
|
|
47
|
+
return nil unless File.file?(source_path)
|
|
48
|
+
|
|
49
|
+
File.realpath(source_path)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def git_index(site)
|
|
53
|
+
@git_indexes ||= {}
|
|
54
|
+
@git_indexes[site] ||= build_git_index(site.source)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def reset(site)
|
|
58
|
+
@git_indexes&.delete(site)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def build_git_index(source)
|
|
62
|
+
source = File.realpath(source)
|
|
63
|
+
root = repository_root(source)
|
|
64
|
+
return GitIndex.empty unless root
|
|
65
|
+
|
|
66
|
+
pathspec = relative_pathspec(source, root)
|
|
67
|
+
boundaries = shallow_boundaries(root)
|
|
68
|
+
warn_shallow if boundaries.any?
|
|
69
|
+
|
|
70
|
+
GitIndex.new(commit_times(root, pathspec, boundaries), modified_paths(root, pathspec))
|
|
71
|
+
rescue SystemCallError, ArgumentError => e
|
|
72
|
+
Jekyll.logger.debug('jekyll-vitepress-theme', "Git dates unavailable: #{e.message}")
|
|
73
|
+
GitIndex.empty
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def repository_root(source)
|
|
77
|
+
root = git(source, 'rev-parse', '--show-toplevel').to_s.strip
|
|
78
|
+
root.empty? ? nil : File.realpath(root)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def relative_pathspec(source, root)
|
|
82
|
+
Pathname.new(source).relative_path_from(Pathname.new(root)).to_s
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def commit_times(root, pathspec, boundaries)
|
|
86
|
+
log = git(root, 'log', '--no-renames', "--format=#{FIELD_SEPARATOR}%H %ct", '--name-only', '-z', '--', pathspec)
|
|
87
|
+
return {} unless log
|
|
88
|
+
|
|
89
|
+
log.split(FIELD_SEPARATOR).each_with_object({}) do |entry, times|
|
|
90
|
+
sha, time, files = parse_log_entry(entry)
|
|
91
|
+
next if files.empty? || boundaries.include?(sha)
|
|
92
|
+
|
|
93
|
+
files.each do |file|
|
|
94
|
+
path = File.join(root, file)
|
|
95
|
+
times[path] = time if times[path].nil? || time > times[path]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def parse_log_entry(entry)
|
|
101
|
+
header, files = entry.split("\0", 2)
|
|
102
|
+
sha, timestamp = header.to_s.split
|
|
103
|
+
return [sha, nil, []] if files.nil?
|
|
104
|
+
|
|
105
|
+
[sha, Time.at(Integer(timestamp)).utc, files.delete_prefix("\n").split("\0").reject(&:empty?)]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def modified_paths(root, pathspec)
|
|
109
|
+
status = git(root, 'status', '--porcelain=v1', '-z', '--untracked-files=no', '--', pathspec)
|
|
110
|
+
return [] unless status
|
|
111
|
+
|
|
112
|
+
entries = status.split("\0")
|
|
113
|
+
paths = []
|
|
114
|
+
until entries.empty?
|
|
115
|
+
entry = entries.shift
|
|
116
|
+
paths << File.join(root, entry[3..])
|
|
117
|
+
entries.shift if entry.start_with?('R', 'C')
|
|
118
|
+
end
|
|
119
|
+
paths
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def shallow_boundaries(root)
|
|
123
|
+
return [] unless git(root, 'rev-parse', '--is-shallow-repository')&.strip == 'true'
|
|
124
|
+
|
|
125
|
+
shallow_file = git(root, 'rev-parse', '--git-path', 'shallow')&.strip
|
|
126
|
+
return [] unless shallow_file
|
|
127
|
+
|
|
128
|
+
shallow_file = File.expand_path(shallow_file, root)
|
|
129
|
+
return [] unless File.file?(shallow_file)
|
|
130
|
+
|
|
131
|
+
File.read(shallow_file).split
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def warn_shallow
|
|
135
|
+
Jekyll.logger.warn(
|
|
136
|
+
'jekyll-vitepress-theme',
|
|
137
|
+
'Shallow Git clone: pages last changed before the clone\'s history use their file ' \
|
|
138
|
+
'modification time for "Last updated". Fetch the full history (fetch-depth: 0) for accurate dates.'
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def git(directory, *args)
|
|
143
|
+
output, status = Open3.capture2('git', '-C', directory, *args, err: File::NULL)
|
|
144
|
+
status.success? ? output : nil
|
|
145
|
+
rescue SystemCallError
|
|
146
|
+
nil
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
Jekyll::Hooks.register :site, :after_reset do |site|
|
|
153
|
+
Jekyll::VitePressTheme::LastUpdated.reset(site)
|
|
154
|
+
end
|
|
@@ -4,7 +4,7 @@ module Jekyll
|
|
|
4
4
|
module VitePressTheme
|
|
5
5
|
# Generates the proposed llms.txt index and its full-text companion from
|
|
6
6
|
# the same canonical, indexable content used by the theme's SEO layer.
|
|
7
|
-
# rubocop:disable Metrics/AbcSize, Metrics/ModuleLength
|
|
7
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/ModuleLength
|
|
8
8
|
module LLMS
|
|
9
9
|
module_function
|
|
10
10
|
|
|
@@ -231,6 +231,5 @@ module Jekyll
|
|
|
231
231
|
value.is_a?(Hash) ? value : {}
|
|
232
232
|
end
|
|
233
233
|
end
|
|
234
|
-
# rubocop:enable Metrics/AbcSize, Metrics/ModuleLength
|
|
235
234
|
end
|
|
236
235
|
end
|
|
@@ -11,7 +11,7 @@ module Jekyll
|
|
|
11
11
|
# the exported .md files, and llms-full.txt all share it. Fenced code
|
|
12
12
|
# blocks and code spans pass through untouched, and a page without HTML
|
|
13
13
|
# comes back unchanged.
|
|
14
|
-
# rubocop:disable Metrics/AbcSize, Metrics/ModuleLength
|
|
14
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/ModuleLength
|
|
15
15
|
module MarkdownExport
|
|
16
16
|
module_function
|
|
17
17
|
|
|
@@ -277,7 +277,7 @@ module Jekyll
|
|
|
277
277
|
def dedent(text)
|
|
278
278
|
lines = text.split("\n", -1)
|
|
279
279
|
indents = lines.drop(1).reject { |line| line.strip.empty? || line.match?(/\A[ \t]*#{BLOCK_CODE_PATTERN.source}/) }
|
|
280
|
-
|
|
280
|
+
.map { |line| line[/\A[ \t]*/].length }
|
|
281
281
|
indent = indents.min.to_i
|
|
282
282
|
return text if indent.zero?
|
|
283
283
|
|
|
@@ -632,6 +632,5 @@ module Jekyll
|
|
|
632
632
|
nil
|
|
633
633
|
end
|
|
634
634
|
end
|
|
635
|
-
# rubocop:enable Metrics/AbcSize, Metrics/ModuleLength
|
|
636
635
|
end
|
|
637
636
|
end
|
|
@@ -10,7 +10,7 @@ module Jekyll
|
|
|
10
10
|
# Generates the metadata shared by the HTML head, sitemap, and robots.txt.
|
|
11
11
|
# Keeping those outputs on one canonical URL resolver prevents contradictory
|
|
12
12
|
# indexing signals across theme consumers.
|
|
13
|
-
# rubocop:disable Metrics/AbcSize, Metrics/ModuleLength
|
|
13
|
+
# rubocop:disable-next Metrics/AbcSize, Metrics/ModuleLength
|
|
14
14
|
module SEO
|
|
15
15
|
module_function
|
|
16
16
|
|
|
@@ -588,6 +588,5 @@ module Jekyll
|
|
|
588
588
|
CGI.escapeHTML(value.to_s)
|
|
589
589
|
end
|
|
590
590
|
end
|
|
591
|
-
# rubocop:enable Metrics/AbcSize, Metrics/ModuleLength
|
|
592
591
|
end
|
|
593
592
|
end
|
|
@@ -3,4 +3,5 @@ require_relative 'jekyll/vitepress_theme/version'
|
|
|
3
3
|
require_relative 'jekyll/vitepress_theme/markdown_export'
|
|
4
4
|
require_relative 'jekyll/vitepress_theme/seo'
|
|
5
5
|
require_relative 'jekyll/vitepress_theme/llms'
|
|
6
|
+
require_relative 'jekyll/vitepress_theme/last_updated'
|
|
6
7
|
require_relative 'jekyll/vitepress_theme/hooks'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jekyll-vitepress-theme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.10.
|
|
4
|
+
version: 1.10.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carmine Paolino
|
|
@@ -56,20 +56,20 @@ dependencies:
|
|
|
56
56
|
requirements:
|
|
57
57
|
- - ">="
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: '
|
|
59
|
+
version: '4.1'
|
|
60
60
|
- - "<"
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: '
|
|
62
|
+
version: '6.0'
|
|
63
63
|
type: :runtime
|
|
64
64
|
prerelease: false
|
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
66
|
requirements:
|
|
67
67
|
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: '
|
|
69
|
+
version: '4.1'
|
|
70
70
|
- - "<"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
|
-
version: '
|
|
72
|
+
version: '6.0'
|
|
73
73
|
description: Jekyll VitePress Theme brings VitePress-style documentation UX, search,
|
|
74
74
|
structured metadata, and Jekyll-native extensions to Ruby static sites.
|
|
75
75
|
email:
|
|
@@ -177,6 +177,7 @@ files:
|
|
|
177
177
|
- assets/vendor/turbo.js
|
|
178
178
|
- lib/jekyll-vitepress-theme.rb
|
|
179
179
|
- lib/jekyll/vitepress_theme/hooks.rb
|
|
180
|
+
- lib/jekyll/vitepress_theme/last_updated.rb
|
|
180
181
|
- lib/jekyll/vitepress_theme/llms.rb
|
|
181
182
|
- lib/jekyll/vitepress_theme/markdown_export.rb
|
|
182
183
|
- lib/jekyll/vitepress_theme/seo.rb
|