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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe14ff0d5fdef3e958e33fdb1d0af6325209f095c352b5c7b09e42cc4da38316
4
- data.tar.gz: cc2bc43f7102cde80e9dc6b54dbe8834febca38d906dde8aa47b1835275c2068
3
+ metadata.gz: 0fa9bd9f39f9a07a853282a881aff54b24f4adde9c87f9c2f03b89bcafff8617
4
+ data.tar.gz: 19d2551ffa4497e178771471091d3655dd0678e6cbcd823e79eefd6c617546ef
5
5
  SHA512:
6
- metadata.gz: 62f45b83d078559a6065716a1d37170cf53043acbdc568760bef9c94e8c2dc90bc9bc37e070c1d50d4480d9abcc95f8c0ae7b286c7e4576a0ec312c35a2bce91
7
- data.tar.gz: 8040cd095339494a138568eeeb021056985f43656c48db23ad4a00489a2a249fd259d79d299178ad2f19923ed79c02ecdc118dfe24f4c217daaa5fc10bd0366e
6
+ metadata.gz: b5041e3e3a4019083374bba8ead0db79724322337d945605168214d3e430ac225c925a2b41040154431fd55da644fdcf0f42c2058daf99d326903f1ea3a77c61
7
+ data.tar.gz: 87e47129bd88e563ba4187118029c1de8311a7662cc7233432a05a8dc3911013b84c0b930bb582c79dd88bf23ad4d570326b9d93756db22016720f36eed38466
@@ -985,7 +985,7 @@ body.vp-search-open {
985
985
  height: 100%;
986
986
  padding: 18px;
987
987
  object-fit: contain;
988
- filter: drop-shadow(-2px 4px 6px rgba(0, 0, 0, 0.2));
988
+ filter: drop-shadow(-2px 4px 6px rgb(0, 0, 0, 0.2));
989
989
  transform: translate(-50%, -50%);
990
990
  }
991
991
 
@@ -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
- .map { |line| line[/\A[ \t]*/].length }
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
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  module VitePressTheme
3
- VERSION = "1.10.0".freeze
3
+ VERSION = "1.10.1".freeze
4
4
  end
5
5
  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.0
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: '3.0'
59
+ version: '4.1'
60
60
  - - "<"
61
61
  - !ruby/object:Gem::Version
62
- version: '5.0'
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: '3.0'
69
+ version: '4.1'
70
70
  - - "<"
71
71
  - !ruby/object:Gem::Version
72
- version: '5.0'
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