jekyll-potion 1.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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +202 -0
  3. data/jekyll-potion.gemspec +17 -0
  4. data/lib/jekyll-potion/logger.rb +49 -0
  5. data/lib/jekyll-potion/models/favicon.rb +28 -0
  6. data/lib/jekyll-potion/models/page-potion.rb +86 -0
  7. data/lib/jekyll-potion/models/potion-page.rb +26 -0
  8. data/lib/jekyll-potion/models/potion-source-map-page.rb +15 -0
  9. data/lib/jekyll-potion/models/potion-static-file.rb +21 -0
  10. data/lib/jekyll-potion/potion.rb +136 -0
  11. data/lib/jekyll-potion/processor/base/jquery-3.6.0.min.js +2 -0
  12. data/lib/jekyll-potion/processor/base-template/code.js +40 -0
  13. data/lib/jekyll-potion/processor/base-template/navigation.js +43 -0
  14. data/lib/jekyll-potion/processor/base-template/tabs.js +38 -0
  15. data/lib/jekyll-potion/processor/header-template/header.js +31 -0
  16. data/lib/jekyll-potion/processor/make-base-javascript-processor.rb +59 -0
  17. data/lib/jekyll-potion/processor/make-date-processor.rb +30 -0
  18. data/lib/jekyll-potion/processor/make-empty-content-processor.rb +19 -0
  19. data/lib/jekyll-potion/processor/make-favicon-processor.rb +108 -0
  20. data/lib/jekyll-potion/processor/make-front-matter-processor.rb +21 -0
  21. data/lib/jekyll-potion/processor/make-header-link-processor.rb +103 -0
  22. data/lib/jekyll-potion/processor/make-navigation-processor.rb +55 -0
  23. data/lib/jekyll-potion/processor/make-og-tag-processor.rb +45 -0
  24. data/lib/jekyll-potion/processor/make-search-index-processor.rb +205 -0
  25. data/lib/jekyll-potion/processor/make-theme-processor.rb +197 -0
  26. data/lib/jekyll-potion/processor/make-title-processor.rb +53 -0
  27. data/lib/jekyll-potion/processor/rewrite-a-href-processor.rb +43 -0
  28. data/lib/jekyll-potion/processor/rewrite-img-processor.rb +42 -0
  29. data/lib/jekyll-potion/processor/search-template/search.js +123 -0
  30. data/lib/jekyll-potion/processor.rb +152 -0
  31. data/lib/jekyll-potion/site.rb +155 -0
  32. data/lib/jekyll-potion/tag.rb +176 -0
  33. data/lib/jekyll-potion/tags/alerts.rb +24 -0
  34. data/lib/jekyll-potion/tags/api.rb +105 -0
  35. data/lib/jekyll-potion/tags/code.rb +65 -0
  36. data/lib/jekyll-potion/tags/empty.rb +20 -0
  37. data/lib/jekyll-potion/tags/file.rb +22 -0
  38. data/lib/jekyll-potion/tags/link.rb +47 -0
  39. data/lib/jekyll-potion/tags/logo.rb +22 -0
  40. data/lib/jekyll-potion/tags/navigation.rb +35 -0
  41. data/lib/jekyll-potion/tags/pagination.rb +20 -0
  42. data/lib/jekyll-potion/tags/tabs.rb +62 -0
  43. data/lib/jekyll-potion/theme/proto/_includes/container.html +10 -0
  44. data/lib/jekyll-potion/theme/proto/_includes/head.html +4 -0
  45. data/lib/jekyll-potion/theme/proto/_includes/header.html +21 -0
  46. data/lib/jekyll-potion/theme/proto/_includes/image.html +5 -0
  47. data/lib/jekyll-potion/theme/proto/_includes/nav.html +3 -0
  48. data/lib/jekyll-potion/theme/proto/_includes/search.html +29 -0
  49. data/lib/jekyll-potion/theme/proto/_layouts/default.html +19 -0
  50. data/lib/jekyll-potion/theme/proto/_layouts/error.html +23 -0
  51. data/lib/jekyll-potion/theme/proto/_templates/alerts.liquid +4 -0
  52. data/lib/jekyll-potion/theme/proto/_templates/api.liquid +46 -0
  53. data/lib/jekyll-potion/theme/proto/_templates/api=description.liquid +3 -0
  54. data/lib/jekyll-potion/theme/proto/_templates/api=parameter.liquid +5 -0
  55. data/lib/jekyll-potion/theme/proto/_templates/api=response.liquid +7 -0
  56. data/lib/jekyll-potion/theme/proto/_templates/code.liquid +8 -0
  57. data/lib/jekyll-potion/theme/proto/_templates/empty.liquid +15 -0
  58. data/lib/jekyll-potion/theme/proto/_templates/file.liquid +8 -0
  59. data/lib/jekyll-potion/theme/proto/_templates/link.liquid +9 -0
  60. data/lib/jekyll-potion/theme/proto/_templates/logo.liquid +8 -0
  61. data/lib/jekyll-potion/theme/proto/_templates/navigation-page.liquid +14 -0
  62. data/lib/jekyll-potion/theme/proto/_templates/navigation.liquid +5 -0
  63. data/lib/jekyll-potion/theme/proto/_templates/pagination.liquid +30 -0
  64. data/lib/jekyll-potion/theme/proto/_templates/tabs.liquid +8 -0
  65. data/lib/jekyll-potion/theme/proto/_templates/tabs=content.liquid +5 -0
  66. data/lib/jekyll-potion/theme/proto/assets/css/main.scss +1254 -0
  67. data/lib/jekyll-potion/theme/proto/assets/css/syntax.css +80 -0
  68. data/lib/jekyll-potion/theme/proto/assets/js/jsrender.min.js +4 -0
  69. data/lib/jekyll-potion/theme/proto/assets/js/jsrender.min.js.map +1 -0
  70. data/lib/jekyll-potion/theme/proto/assets/js/main.js +237 -0
  71. data/lib/jekyll-potion/theme.rb +165 -0
  72. data/lib/jekyll-potion/util.rb +73 -0
  73. data/lib/jekyll-potion.rb +32 -0
  74. metadata +143 -0
@@ -0,0 +1,103 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ module Jekyll::Potion
5
+ class MakeHeaderLinkProcessor < Processor
6
+ priority :site_after_init, :normal
7
+ priority :page_post_render, Processor::PRIORITY_MAP[:low] - 2
8
+
9
+ SCRIPT_TEMPLATE_PATH = "header-template".freeze
10
+
11
+ SELECTOR_KEY = "selector".freeze
12
+ HASH_CLASS_KEY = "hash_class".freeze
13
+ COPY_CLASS_KEY = "copy_class".freeze
14
+
15
+ DEFAULT_CONFIG = {
16
+ SELECTOR_KEY => "data-header-link",
17
+ HASH_CLASS_KEY => "go-hash",
18
+ COPY_CLASS_KEY => "copy-link"
19
+ }
20
+
21
+ def initialize(site, theme, config, tags)
22
+ super
23
+
24
+ @base_dir = site[:processor_base_dir]
25
+ @script_files = []
26
+ end
27
+
28
+ def site_after_init(site)
29
+ Util.load_files(@base_dir, SCRIPT_TEMPLATE_PATH) { |base, dir, file_name|
30
+ script_file = @theme.assets_potion_page("", MakeBaseJavascriptProcessor::BASE_SCRIPT_PATH, file_name)
31
+ script_file.output = @site.load_template(File.join(base, dir, file_name)).render(Util.string_key_hash(@config))
32
+ @script_files << script_file
33
+ }
34
+ end
35
+
36
+ def page_post_render(page, html, modified)
37
+ if modified
38
+ update_a_tag_count = 0
39
+ create_a_tag_count = 0
40
+
41
+ html.css("h1", "h2", "h3", "h4", "h5", "h6")
42
+ .select { |h_tag| h_tag.has_attribute?("id") }
43
+ .each { |h_tag|
44
+ id = h_tag["id"]
45
+
46
+ next if id.strip.empty?
47
+
48
+ a_tag = h_tag.css("a").first
49
+
50
+ target_hash = ""
51
+
52
+ if a_tag.nil?
53
+ create_a_tag_count += 1
54
+ new_a_tag = Nokogiri::XML::Node.new("a", html)
55
+ new_a_tag["href"] = "##{id}"
56
+ target_hash = "##{id}"
57
+ new_a_tag.add_class(@config[:hash_class])
58
+ h_tag.add_child(new_a_tag)
59
+ else
60
+ update_a_tag_count += 1
61
+ if a_tag.has_attribute?("id")
62
+ a_tag["href"] = "##{a_tag["id"]}"
63
+ target_hash = "##{a_tag["id"]}"
64
+ else
65
+ a_tag["href"] = "##{id}"
66
+ target_hash = "##{id}"
67
+ end
68
+ a_tag.add_class(@config[:hash_class])
69
+ end
70
+
71
+ copy_link = Nokogiri::XML::Node.new("div", html)
72
+ copy_link.add_class(@config[:copy_class])
73
+
74
+ absolute_href = @site.base_absolute_url(page.url)
75
+
76
+ copy_link[@config[:selector]] = "#{absolute_href}#{target_hash}"
77
+ h_tag.add_child(copy_link)
78
+ }
79
+
80
+ @logger.trace("#{page.name} update header #{update_a_tag_count} a tags href update, #{create_a_tag_count} a tag create")
81
+ end
82
+
83
+ head = html.css("head").first
84
+
85
+ unless head.nil?
86
+ @script_files.each { |file|
87
+ script = Nokogiri::XML::Node.new("script", html)
88
+ script["type"] = "text/javascript"
89
+ script["src"] = @site.base_url(file.relative_path)
90
+ head.add_child(script)
91
+ }
92
+ end
93
+
94
+ yield html
95
+ end
96
+
97
+ def site_post_render(site)
98
+ @script_files.each { |file| @logger.trace("add base javascript file #{file.relative_path}") }
99
+ site.static_files -= @script_files
100
+ site.static_files.concat(@script_files)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,55 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ module Jekyll::Potion
5
+ class MakeNavigationProcessor < Processor
6
+ NAVIGATION_KEY = "navigation".freeze
7
+ DEPTH_ORDER = "depth_order".freeze
8
+
9
+ def initialize(site, theme, config, tags)
10
+ super
11
+ @root_potions = []
12
+ end
13
+
14
+ def site_post_read(site)
15
+ page_map = {}
16
+ potion_map = {}
17
+
18
+ @site.markdown_pages.each { |page|
19
+ def page.depth_order
20
+ self.data[DEPTH_ORDER] ||= 99999999
21
+ end
22
+
23
+ page_map[page.url] = page
24
+ potion_map[page.url] = PagePotion.new(@site.baseurl, page)
25
+ }
26
+
27
+ potion_map.values.each { |potion| potion.parent = potion_map[potion.parent_path] }
28
+
29
+ potion_map.values.group_by { |potion| potion.parent_path }.to_h
30
+ .each { |parent_path, children|
31
+ potion_map[parent_path].children = children.sort_by { |potion| potion.page.depth_order } if potion_map.has_key?(parent_path)
32
+ }
33
+
34
+ @root_potions = potion_map.values.select { |potion| potion.parent_path == "" }
35
+ .sort_by { |potion| potion.page.depth_order }
36
+
37
+ order = 0
38
+ @root_potions.each { |potion| order = potion.set_order(order) }
39
+
40
+ sorted_potions = potion_map.values
41
+ .select { |potion| not potion.order.nil? }
42
+ .sort_by { |potion| potion.order }
43
+
44
+ sorted_potions[1..sorted_potions.size].each_with_index { |potion, index|
45
+ potion.before = sorted_potions[index]
46
+ }
47
+
48
+ sorted_potions[0..sorted_potions.size - 2].each_with_index { |potion, index|
49
+ potion.after = sorted_potions[index + 1]
50
+ }
51
+
52
+ @site.navigation(@root_potions)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,45 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ module Jekyll::Potion
5
+ class MakeOgTagProcessor < Processor
6
+ priority :page_post_render, :normal
7
+
8
+ def page_post_render(page, html, modified)
9
+ head = html.css("head").first
10
+
11
+ unless head.nil?
12
+ or_url = Nokogiri::XML::Node.new("meta", html)
13
+ or_url["property"] = "og:url"
14
+ or_url["content"] = @site.full_url(page.url)
15
+ head.add_child(or_url)
16
+
17
+ or_type = Nokogiri::XML::Node.new("meta", html)
18
+ or_type["property"] = "og:type"
19
+ or_type["content"] = "website"
20
+ head.add_child(or_type)
21
+
22
+ og_title = Nokogiri::XML::Node.new("meta", html)
23
+ og_title["property"] = "og:title"
24
+ og_title["content"] = @site.page_title(page)
25
+ head.add_child(og_title)
26
+
27
+ if page.data.has_key?("description") and not page.data["description"].empty?
28
+ og_description = Nokogiri::XML::Node.new("meta", html)
29
+ og_description["property"] = "og:description"
30
+ og_description["content"] = page.data["description"]
31
+ head.add_child(og_description)
32
+ end
33
+
34
+ unless @site.empty?(:icon)
35
+ og_image = Nokogiri::XML::Node.new("meta", html)
36
+ og_image["property"] = "og:image"
37
+ og_image["content"] = @site.full_url(@site[:icon])
38
+ head.add_child(og_image)
39
+ end
40
+
41
+ yield html
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,205 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ require "nokogiri"
5
+ require "json"
6
+
7
+ module Jekyll::Potion
8
+ class PageIndex
9
+ def initialize(potion)
10
+ @url = potion.url
11
+ @order = potion.order
12
+ @indexes = []
13
+ end
14
+
15
+ def add_index(index)
16
+ @indexes << index
17
+ end
18
+
19
+ def count_sentences
20
+ @indexes.map { |index| index.count_sentences }.sum
21
+ end
22
+
23
+ def to_json(_)
24
+ JSON.pretty_generate(instance_variables.map { |var| [var.to_s.delete("@"), instance_variable_get(var)] }.to_h)
25
+ end
26
+
27
+ def self.title(titles)
28
+ titles.select { |title| !title.empty? }.map { |title| title.strip }.join(" > ").strip
29
+ end
30
+
31
+ def self.parse(skip_keyword, page, html, content_x_path)
32
+ potion = PagePotion.potion(page)
33
+
34
+ page_index = PageIndex.new(potion)
35
+
36
+ search_index = SearchIndex.from_potion(skip_keyword, potion)
37
+
38
+ titles = [page.data["title"], "", "", "", "", "", ""]
39
+
40
+ html.css(content_x_path).children.each { |tag|
41
+ search_index.parse(tag) { |heading|
42
+ page_index.add_index(search_index)
43
+
44
+ current = $1.to_i + 1
45
+
46
+ (current..7).each { |i| titles[i] = "" }
47
+
48
+ titles[current] = heading.text.strip
49
+
50
+ search_index = SearchIndex.from_hash(skip_keyword, self.title(titles), heading["id"])
51
+ search_index.add_sentence(heading.text.strip)
52
+ }
53
+ }
54
+
55
+ page_index
56
+ end
57
+ end
58
+
59
+ class SearchIndex
60
+ def initialize(skip_keyword, title, hash = "")
61
+ @skip_keyword = skip_keyword
62
+ @title = title
63
+ @hash = hash
64
+ @sentences = []
65
+
66
+ @hash = "##{@hash}" unless hash.nil? or hash.empty?
67
+ end
68
+
69
+ def add_sentence(sentence)
70
+ @sentences << sentence
71
+ end
72
+
73
+ def concat_sentences(sentences)
74
+ @sentences.concat(sentences)
75
+ end
76
+
77
+ def parse (tag, &block)
78
+ unless tag.has_attribute?(@skip_keyword)
79
+ if tag.name =~ /h(\d+)/ and not tag.text.strip.empty?
80
+ yield tag
81
+ return
82
+ end
83
+
84
+ case tag.name
85
+ when "ul", "ol"
86
+ tag.css("li").each { |li|
87
+ @sentences << li.text.strip unless li.text.strip.empty?
88
+ }
89
+ when "table"
90
+ if tag.classes.include?("rouge-table")
91
+ @sentences << tag.css("td.rouge-code").text.strip unless tag.css("td.rouge-code").text.strip.empty?
92
+ else
93
+ tag.css("thread").css("tr").each { |tr|
94
+ @sentences << tr.css("th").map { |td| td.text.strip }.join(" | ")
95
+ }
96
+ tag.css("tbody").css("tr").each { |tr|
97
+ @sentences << tr.css("td").map { |td| td.text.strip }.join(" | ")
98
+ }
99
+ end
100
+ when "pre"
101
+ if tag.classes.include?("highlight")
102
+ @sentences << tag.css("td.rouge-code").text.strip unless tag.css("td.rouge-code").text.strip.empty?
103
+ end
104
+ else
105
+ tag.children.each { |child_tag|
106
+ if child_tag.is_a?(Nokogiri::XML::Text) or child_tag.name == "p"
107
+ @sentences << child_tag.text.strip unless child_tag.text.strip.empty?
108
+ else
109
+ parse(child_tag, &block)
110
+ end
111
+ }
112
+ end
113
+ end
114
+ end
115
+
116
+ def count_sentences
117
+ @sentences.size
118
+ end
119
+
120
+ def to_json(_)
121
+ JSON.pretty_generate(
122
+ instance_variables
123
+ .filter { |var| not var.to_s == "@skip_keyword" }
124
+ .map { |var|
125
+ [var.to_s.delete("@"), instance_variable_get(var)]
126
+ }.to_h
127
+ )
128
+ end
129
+
130
+ def self.from_potion(skip_keyword, potion)
131
+ search_index = SearchIndex.new(skip_keyword, potion.title)
132
+ search_index.add_sentence(potion.title) unless potion.title.nil? or potion.title.empty?
133
+ search_index.add_sentence(potion.description) unless potion.description.nil? or potion.description.empty?
134
+ search_index
135
+ end
136
+
137
+ def self.from_hash(skip_keyword, title, hash)
138
+ search_index = SearchIndex.new(skip_keyword, title, hash)
139
+ search_index
140
+ end
141
+ end
142
+
143
+ class MakeSearchIndexProcessor < Processor
144
+ priority :page_post_render, :lowest
145
+
146
+ SCRIPT_TEMPLATE_PATH = "search-template".freeze
147
+ SEARCH_SCRIPT_NAME = "search.js".freeze
148
+
149
+ def initialize(site, theme, config, tags)
150
+ super
151
+
152
+ @base_dir = site[:processor_base_dir]
153
+ @base_path = MakeBaseJavascriptProcessor::BASE_SCRIPT_PATH
154
+
155
+ @script_files = []
156
+ @indexes = {}
157
+ end
158
+
159
+ def site_after_init(site)
160
+ config = {
161
+ "search_file" => @theme.base_assets_url(@base_path, @config[:search_file_name])
162
+ }
163
+ @script_file = @theme.assets_potion_page("", @base_path, SEARCH_SCRIPT_NAME)
164
+ @script_file.output = @site.load_template(File.join(@base_dir, SCRIPT_TEMPLATE_PATH, SEARCH_SCRIPT_NAME)).render(config)
165
+ @logger.trace("add base javascript file #{File.join(SCRIPT_TEMPLATE_PATH, SEARCH_SCRIPT_NAME)}")
166
+ end
167
+
168
+ def page_post_render(page, html, modified)
169
+ if modified
170
+ potion = PagePotion.potion(page)
171
+
172
+ return if potion.nil?
173
+
174
+ page_index = PageIndex.parse(@config[:skip_keyword], page, html, @theme[:content_x_path])
175
+ @indexes[page.url] = page_index
176
+
177
+ @logger.trace("make search index", "#{page.name}[#{page_index.count_sentences}]")
178
+ end
179
+
180
+ head = html.css("head").first
181
+
182
+ unless head.nil?
183
+ script = Nokogiri::XML::Node.new("script", html)
184
+ script["type"] = "text/javascript"
185
+ script["src"] = @site.base_url(@script_file.relative_path)
186
+ head.add_child(script)
187
+ end
188
+
189
+ yield html
190
+ end
191
+
192
+ def site_post_render(site)
193
+ index_file = @theme.assets_potion_page("", @base_path, @config[:search_file_name])
194
+ index_file.output = JSON.pretty_generate(@indexes.values)
195
+
196
+ site.pages -= [@script_file, index_file]
197
+
198
+ @logger.trace("add base javascript file #{@script_file.relative_path}")
199
+ @logger.trace("add search index file #{index_file.relative_path}")
200
+
201
+ site.pages << @script_file
202
+ site.pages << index_file
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,197 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ module Jekyll::Potion
5
+ class MakeThemeProcessor < Processor
6
+ priority :site_after_init, :highest
7
+ priority :page_post_render, Processor::PRIORITY_MAP[:low] - 1
8
+
9
+ JS_PATTERN = %r!^\.js$!i.freeze
10
+ CSS_PATTERN = %r!^\.css$!i.freeze
11
+ SCSS_PATTERN = Jekyll::Converters::Scss::EXTENSION_PATTERN
12
+
13
+ def initialize(site, theme, config, tags)
14
+ super
15
+ init
16
+ end
17
+
18
+ def init
19
+ @js_files = []
20
+ @css_files = []
21
+ @static_files = []
22
+ end
23
+
24
+ def site_after_init(site)
25
+ permalink = find_default_scope(site)
26
+ if permalink.nil?
27
+ site.config["defaults"] << default_scope
28
+ else
29
+ if permalink.has_key?("values")
30
+ permalink["values"]["layout"] = @theme[:default_layout]
31
+ else
32
+ permalink["values"] = { "layout" => @theme[:default_layout] }
33
+ end
34
+
35
+ permalink["values"]["permalink"] = @site[:permalink] unless @site.empty?(:permalink)
36
+ end
37
+
38
+ unless @site.empty?(:index_page)
39
+ index = find_index_scope(site)
40
+
41
+ if index.nil?
42
+ site.config["defaults"] << index_scope
43
+ else
44
+ if index.has_key?("values")
45
+ index["values"]["permalink"] = ""
46
+ else
47
+ index["values"] = { "permalink" => "" }
48
+ end
49
+ end
50
+ end
51
+
52
+ site.includes_load_paths << @theme[:includes_dir]
53
+ site.config["sass"]["sass_dir"] = @theme[:assets][:scss_source_dir]
54
+
55
+ site.theme = @theme
56
+ end
57
+
58
+ def include_scss_file?(file_name)
59
+ @theme[:assets][:scss_files].include?(file_name)
60
+ end
61
+
62
+ def site_post_read(site)
63
+ init
64
+
65
+ Util.load_files(@theme[:assets][:source_dir]) { |base, dir, file_name|
66
+ case
67
+ when scss_matches(file_name) && @theme[:assets][:scss_files].include?(file_name)
68
+ scss_file = @theme.assets_scss_potion_page(base, dir, file_name)
69
+ scss_map = @theme.assets_map_page(scss_file)
70
+ @css_files << scss_file
71
+ @static_files << scss_map
72
+ @logger.trace("detect scss file #{File.join(@theme[:assets][:source_dir], dir, scss_file.name)}")
73
+ @logger.trace("detect scss map file #{File.join(@theme[:assets][:source_dir], dir, scss_map.name)}")
74
+ when js_matches(file_name)
75
+ js_file = @theme.assets_static_file(base, dir, file_name)
76
+ @js_files << js_file
77
+ @logger.trace("detect javascript file #{File.join(@theme[:assets][:source_dir], dir, file_name)}")
78
+ when css_matches(file_name)
79
+ css_file = @theme.assets_static_file(base, dir, file_name)
80
+ @css_files << css_file
81
+ @logger.trace("detect css file #{File.join(@theme[:assets][:source_dir], dir, file_name)}")
82
+ else
83
+ @static_files << @theme.assets_static_file(base, dir, file_name)
84
+ @logger.trace("detect static file #{File.join(@theme[:assets][:source_dir], dir, file_name)}")
85
+ end
86
+ }
87
+ end
88
+
89
+ def page_post_render(page, html, modified)
90
+ head = html.css("head").first
91
+
92
+ unless head.nil?
93
+ priority_files = @theme[:assets][:priority_files]
94
+
95
+ priority_files.each { |priority_filepath|
96
+ file = @css_files.find { |file| priority_filepath == file.relative_path }
97
+ head.add_child(css_meta(file, html)) unless file.nil?
98
+ }
99
+
100
+ @css_files.each { |file|
101
+ next if priority_files.include?(file.relative_path)
102
+ head.add_child(css_meta(file, html))
103
+ }
104
+
105
+ priority_files.each { |priority_filepath|
106
+ file = @js_files.find { |file| priority_filepath == file.relative_path }
107
+ head.add_child(js_meta(file, html)) unless file.nil?
108
+ }
109
+
110
+ @js_files.each { |file|
111
+ next if priority_files.include?(file.relative_path)
112
+ head.add_child(js_meta(file, html))
113
+ }
114
+
115
+ yield html
116
+ end
117
+ end
118
+
119
+ def css_meta(file, html)
120
+ link = Nokogiri::XML::Node.new("link", html)
121
+ link["rel"] = "stylesheet"
122
+ link["href"] = @site.base_url(file.relative_path)
123
+ link
124
+ end
125
+
126
+ def js_meta(file, html)
127
+ script = Nokogiri::XML::Node.new("script", html)
128
+ script["type"] = "text/javascript"
129
+ script["src"] = @site.base_url(file.relative_path)
130
+ script
131
+ end
132
+
133
+ def find_scope(site, path)
134
+ site.config["defaults"].find { |default| default.has_key?("scope") && default["scope"].has_key?("path") && default["scope"]["path"] == path }
135
+ end
136
+
137
+ def find_default_scope(site)
138
+ find_scope(site, "")
139
+ end
140
+
141
+ def find_index_scope(site)
142
+ find_scope(site, @site[:index_page])
143
+ end
144
+
145
+ def default_scope
146
+ default_scope = {
147
+ "scope" => {
148
+ "path" => ""
149
+ },
150
+ "values" => {
151
+ "layout" => Potion[:theme][:default_layout]
152
+ }
153
+ }
154
+ default_scope["values"]["permalink"] = @site[:permalink] unless @site.empty?(:permalink)
155
+ default_scope
156
+ end
157
+
158
+ def index_scope
159
+ {
160
+ "scope" => {
161
+ "path" => @site[:index_page]
162
+ },
163
+ "values" => {
164
+ "permalink" => ""
165
+ }
166
+ }
167
+ end
168
+
169
+ def js_matches(file_name)
170
+ File.extname(file_name).match?(JS_PATTERN)
171
+ end
172
+
173
+ def css_matches(file_name)
174
+ File.extname(file_name).match?(CSS_PATTERN)
175
+ end
176
+
177
+ def scss_matches(file_name)
178
+ File.extname(file_name).match?(SCSS_PATTERN)
179
+ end
180
+
181
+ def site_post_render(site)
182
+ static_files = [@css_files, @js_files, @static_files].flatten
183
+
184
+ in_theme_static_files = site.static_files.select { |file| file.relative_path.start_with?("/#{@theme[:path]}") }
185
+
186
+ in_theme_static_files.each { |file| @logger.trace("remove previous theme static file #{file.relative_path}") }
187
+
188
+ site.static_files -= in_theme_static_files
189
+ site.static_files -= static_files
190
+
191
+ static_files.each { |file| @logger.trace("add theme static file #{file.relative_path}") }
192
+
193
+ site.static_files.concat(static_files)
194
+ end
195
+ end
196
+
197
+ end
@@ -0,0 +1,53 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ module Jekyll::Potion
5
+ class MakeTitleProcessor < Processor
6
+ priority :page_post_render, :high
7
+
8
+ TITLE_REGEX = %r! \A\s* (?: \#{1,3}\s+(.*)(?:\s+\#{1,3})? | (.*)\r?\n[-=]+\s* )$ !x.freeze
9
+
10
+ def site_post_read(site)
11
+ @site.markdown_pages.each { |page|
12
+ if page.data["title"].nil?
13
+ page.data["title"] = make_title(page)
14
+ page.content = page.content.gsub(TITLE_REGEX, "").strip
15
+ end
16
+ }
17
+ end
18
+
19
+ def page_post_render(page, html, modified)
20
+ head = html.css("head").first
21
+
22
+ unless head.nil?
23
+ title_value = @site.page_title(page)
24
+
25
+ meta = Nokogiri::XML::Node.new("meta", html)
26
+ meta["http-equiv"] = "Title"
27
+ meta["content"] = title_value
28
+ head.add_child(meta)
29
+
30
+ if page.data.has_key?("description") and not page.data["description"].empty?
31
+ meta = Nokogiri::XML::Node.new("meta", html)
32
+ meta["http-equiv"] = "Description"
33
+ meta["content"] = page.data["description"]
34
+ head.add_child(meta)
35
+ end
36
+
37
+ title = Nokogiri::XML::Node.new("title", html)
38
+ title.content = title_value
39
+ head.add_child(title)
40
+
41
+ yield html
42
+ end
43
+ end
44
+
45
+ def make_title(page)
46
+ if page.content.to_s =~ TITLE_REGEX
47
+ $1 || $2
48
+ else
49
+ page.data["title"]
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,43 @@
1
+ # SPDX-FileCopyrightText: Copyright 2022 SK TELECOM CO., LTD.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+
4
+ module Jekyll::Potion
5
+ class RewriteAHrefProcessor < Processor
6
+ HTTP_SCHEME = %r!\Ahttp(s)?://!im.freeze
7
+ ABSOLUTE_PATH = %r!\A/!im.freeze
8
+ HASH_SCHEME = %r!\A#!im.freeze
9
+
10
+ def page_post_render(page, html, modified)
11
+ if modified
12
+ href_count = 0
13
+ hash_count = 0
14
+
15
+ html.css("a[href]").each { |a_tag|
16
+ href = a_tag["href"]
17
+
18
+ next if a_tag.has_attribute?(@config[:skip_keyword])
19
+ next if href.strip.empty?
20
+ next if href =~ HTTP_SCHEME
21
+
22
+ if a_tag.has_attribute?(@config[:index_page_keyword])
23
+ a_tag["href"] = @site.index_url
24
+ elsif href =~ HASH_SCHEME
25
+ hash_count += 1
26
+ a_tag.add_class(@config[:hash_link_class])
27
+ elsif href !~ ABSOLUTE_PATH
28
+ a_tag["href"] = @site.base_absolute_url(File.dirname(page.path), href)
29
+ end
30
+
31
+ href_count += 1
32
+ a_tag.add_class(@config[:internal_link_class])
33
+ }
34
+
35
+ if href_count > 0 || hash_count > 0
36
+ @logger.trace("#{page.name} #{href_count} a tags replace absolute path") if href_count > 0
37
+ @logger.trace("#{page.name} #{hash_count} hashed a tags add class") if hash_count > 0
38
+ yield html
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end