jekyll-koziolekweb-tags 0.2.0 → 0.4.0

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: ed61d38c76920fab927651b97700c9f928937bc3fb5de4670b527b4a017dac07
4
- data.tar.gz: 9bb5a329d41433716cd0c69e4d27dd3957e2a23351f909867f3fa5dafd1274f0
3
+ metadata.gz: a9e7fa5d6b1d9504b547aca1892fd816aedc77f01e94e85693647f5506977eb8
4
+ data.tar.gz: 598f5614d3d662f73d79002690eb7eba5bf209c06f74b9edfc664727849bac6f
5
5
  SHA512:
6
- metadata.gz: 10f070571ea4cc21926a7010ab24d89013117190b98de610fbbbe2b5c547a5c5eade5c3bf1350b3e86d2249bfa298ab7bf1d4150d1380758a8e4be9e2899fab8
7
- data.tar.gz: df3080ae27c1f76239feafcbd56aaf3835e57f5a50428d26c1ea9c070f021c0891e259b6265d289032b7c977c2f4937efb33d3ee727bbf54630e819550c15785
6
+ metadata.gz: 42f1c4a47b42ed0938f80f9c7acb9b8f25b3e68a0cdeee04c8ef771ca0b904b20de1ae22ee0c64f1c0acf785e211ff643627030ba5969a0050f1d2b0e3087596
7
+ data.tar.gz: d215cc40e893f808cc43f6cfaa490553eb0581a9962a95fa378ab50113453b13fc089658b0a63e6c2b9561eeac50a44aeb2019d46fc3f8c8fa57f65568ac273e
data/.tool-versions ADDED
@@ -0,0 +1,2 @@
1
+ #ruby 2.6.5
2
+ ruby 3.4.3
data/Gemfile CHANGED
@@ -6,5 +6,7 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
-
9
+ gem "minitest"
10
+ gem "liquid", "~> 4.0"
11
+ gem "shellwords"
10
12
  gem "jekyll", ENV["JEKYLL_VERSION"] if ENV["JEKYLL_VERSION"]
data/Rakefile CHANGED
@@ -1,4 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- task default: %i[]
4
+ require "rake/testtask"
5
+
6
+ # Definiowanie zadania testowego
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "test"
9
+ t.test_files = FileList["test/test_*.rb"]
10
+ t.warning = true
11
+ end
12
+
13
+ # Domyślne zadanie: uruchom testy
14
+ task default: :test
15
+
@@ -3,7 +3,7 @@
3
3
  module Jekyll
4
4
  module Koziolekweb
5
5
  module Tags
6
- VERSION = "0.2.0"
6
+ VERSION = "0.4.0"
7
7
  end
8
8
  end
9
9
  end
@@ -1,72 +1,219 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "liquid"
4
+ require "jekyll"
5
+ require "jekyll/converters/markdown"
6
+ require "shellwords"
7
+ require "yaml"
8
+ require "cgi"
3
9
  require_relative "tags/version"
4
10
 
5
11
  module Koziolekweb
6
12
  module Tags
7
13
  class Listing < Liquid::Block
8
- @@file_state = {}
9
-
10
14
  def initialize(tag_name, markup, tokens)
11
15
  super
12
-
13
- matched = /(\w+)\s+["'](.*?)["']/.match(markup)
14
-
16
+ matched = markup.strip.match(/\A(\w+)\s+["'](.+?)["']\z/)
15
17
  if matched
16
18
  @lang = matched[1]
17
19
  @title = matched[2]
18
20
  else
19
- raise SyntaxError.new("
21
+ raise Liquid::SyntaxError, <<~ERROR.strip
20
22
  Invalid parameters for listing. Usage:
21
- {% listing lang 'title' %}
22
- code goes here
23
- {% endlisting %}
24
- got
25
- #{markup}")
23
+ {% listing lang 'title' %}
24
+ code goes here
25
+ {% endlisting %}
26
+ Got:
27
+ #{markup}
28
+ ERROR
26
29
  end
27
30
  end
28
31
 
29
32
  def render(context)
30
- current_file = context.registers[:page]["path"]
31
- @@file_state[current_file] ||= 0
32
- @@file_state[current_file] += 1
33
- content = super
34
- content_with_code_fence = "```#{@lang} #{content}```"
33
+ current_file = context.registers.dig(:page, "path") || "__global__"
34
+ context.registers[:listing_count] ||= {}
35
+ context.registers[:listing_count][current_file] ||= 0
36
+ listing_number = (context.registers[:listing_count][current_file] += 1)
37
+ content = super.chomp
35
38
 
36
- "<p class='listing'> Listing #{@@file_state[current_file]}. #{@title}</p>#{content_with_code_fence}"
39
+ markdown_converter = context.registers[:site].find_converter_instance(Jekyll::Converters::Markdown)
40
+ title_html = markdown_converter.convert(@title).strip.sub(%r{\A<p>(.*)</p>\z}, '\1')
41
+ markdown_code = "```#{@lang}\n#{content}\n```"
42
+ code_html = markdown_converter.convert(markdown_code).strip
43
+
44
+ <<~HTML
45
+ <p class='listing'> Listing #{listing_number}. #{title_html}</p>
46
+ #{code_html}
47
+ HTML
37
48
  end
38
49
  end
39
50
 
40
51
  class Offtop < Liquid::Block
52
+ VALID_DIRECTIONS = %w[right left].freeze
41
53
 
42
54
  def initialize(tag_name, markup, tokens)
43
55
  super
44
- @direction = markup
56
+ @params = parse_params(markup)
57
+
58
+ @direction = @params.fetch('direction', 'right').strip
59
+
60
+ unless self.class::VALID_DIRECTIONS.include?(@direction)
61
+ raise ArgumentError, "Invalid direction '#{@direction}'. Allowed values are: #{VALID_DIRECTIONS.join(', ')}"
62
+ end
45
63
  end
46
64
 
47
65
  def render(context)
48
66
  content = super
49
67
  "<aside class=\"offtopic f-#{@direction}\">#{content}</aside>"
50
68
  end
69
+
70
+ private
71
+
72
+ def parse_params(text)
73
+ params = {}
74
+ text.scan(/(\w+)\s*:\s*("[^"]*"|\S+)/).each do |key, val|
75
+ val = val.delete_prefix('"').delete_suffix('"') if val.start_with?('"')
76
+ params[key] = val
77
+ end
78
+ params
79
+ end
51
80
  end
52
81
 
53
82
  class YtVideo < Liquid::Tag
54
83
  def initialize(tag_name, video_id, tokens)
55
84
  super
56
85
  @video_id = video_id.strip
86
+
87
+ if @video_id.empty? || !valid_video_id?(@video_id)
88
+ raise Liquid::SyntaxError, "Invalid video ID: #{@video_id.inspect}"
89
+ end
90
+
57
91
  end
58
92
 
59
93
  def render(_context)
60
94
  <<~HTML
61
- <div class="video">
62
- <iframe src="https://www.youtube-nocookie.com/embed/#{@video_id}" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
63
- </div>
64
- HTML
95
+ <div class="video">
96
+ <iframe title="Youtube Video" src="https://www.youtube-nocookie.com/embed/#{@video_id}" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
97
+ </div>
98
+ HTML
65
99
  end
100
+
101
+ private
102
+
103
+ def valid_video_id?(video_id)
104
+ video_id.match?(/\A[\w-]{11}\z/)
105
+ end
106
+
66
107
  end
108
+
109
+ class Book < Liquid::Tag
110
+ MIN_ARGS = 5
111
+
112
+ def initialize(tag_name, markup, tokens)
113
+ super
114
+
115
+ args = Shellwords.split(markup)
116
+ raise Liquid::SyntaxError, "Invalid usage" if args.size < self::MIN_ARGS
117
+
118
+ @title, @author, @year, @isbn, @cover_url = args[0..4].map { _1.delete('"') }
119
+
120
+ unless @year.match?(/\A\d{4}\z/)
121
+ raise Liquid::SyntaxError, "Invalid publication year: #{@year.inspect}"
122
+ end
123
+
124
+ lang_arg = args.find { |s| s.start_with?("lang:") }
125
+ @lang = lang_arg&.split(":", 2)&.last || "en"
126
+
127
+ unless @lang.match?(/\A[a-z]{2}\z/i)
128
+ raise Liquid::SyntaxError, "Invalid language code: #{@lang.inspect}"
129
+ end
130
+ # Inicjalizacja LanguageManager
131
+ lang_data_path = File.join(Dir.pwd, '_data', 'lang') # Katalog z plikami językowymi
132
+ config_path = File.join(Dir.pwd, '_config.yml') # Ścieżka do pliku `_config.yml`
133
+ @language_manager = Koziolekweb::LanguageSupport::LanguageManager.new(config_path, lang_data_path)
134
+ end
135
+
136
+ def render(_context)
137
+ title_html = CGI.escapeHTML(@title)
138
+ author_html = CGI.escapeHTML(@author)
139
+ year_html = CGI.escapeHTML(@year)
140
+ isbn_html = CGI.escapeHTML(@isbn.to_s)
141
+ label_title = @language_manager.translate('title', @lang, 'Tytuł')
142
+ label_author = @language_manager.translate('author', @lang, 'Autor')
143
+ label_year = @language_manager.translate('year', @lang, 'Rok')
144
+ label_isbn = @language_manager.translate('isbn', @lang, 'ISBN')
145
+ cover_alt = @language_manager.translate('cover_alt', @lang, 'Okładka książki %{title} autorstwa %{author}')
146
+ .gsub('%{title}', @title)
147
+ .gsub('%{author}', @author)
148
+
149
+ <<~HTML
150
+ <div class="book">
151
+ <img src="#{@cover_url}" alt="#{cover_alt}" title="#{@title}" class="cover" />
152
+ <div class="book_desc">
153
+ <ul>
154
+ <li><span>#{label_title}: </span>#{title_html}</li>
155
+ <li><span>#{label_author}: </span>#{author_html}</li>
156
+ <li><span>#{label_year}: </span>#{year_html}</li>
157
+ #{@isbn.nil? ? "" : "<li><span>#{label_isbn}: </span>#{isbn_html}</li>"}
158
+ </ul>
159
+ </div>
160
+ </div>
161
+ HTML
162
+ end
163
+ end
164
+ end
165
+
166
+ module LanguageSupport
167
+ class LanguageManager
168
+ attr_reader :default_language
169
+ def initialize(config_path, lang_data_path)
170
+ @dictionary_cache = {}
171
+ @config_path = config_path
172
+ @lang_data_path = lang_data_path
173
+ @default_language = load_default_language
174
+ end
175
+
176
+ # Pobiera tłumaczenie dla danego klucza
177
+ def translate(key, lang = nil, default_value = nil)
178
+ lang ||= default_language
179
+ load_dictionary(lang)[key] || default_value
180
+ end
181
+
182
+ private
183
+
184
+ # Wczytanie domyślnego języka z pliku `_config.yml`
185
+ def load_default_language
186
+ if File.exist?(@config_path)
187
+ config = YAML.load_file(@config_path)
188
+ config['lang'] || 'en'
189
+ else
190
+ 'en'
191
+ end
192
+ end
193
+
194
+ # Wczytuje słownik dla danego języka
195
+ def load_dictionary(lang)
196
+ @dictionary_cache[lang] ||=
197
+ begin
198
+ dictionary_path = File.join(@lang_data_path, "#{lang}.yml")
199
+ if File.exist?(dictionary_path)
200
+ YAML.safe_load(File.read(dictionary_path), aliases: true)
201
+ else
202
+ {}
203
+ end
204
+ end
205
+ end
206
+ end
207
+
67
208
  end
68
209
  end
69
210
 
70
- Liquid::Template.register_tag('listing', Koziolekweb::Tags::Listing)
71
- Liquid::Template.register_tag('offtop', Koziolekweb::Tags::Offtop)
72
- Liquid::Template.register_tag('yt_video', Koziolekweb::Tags::YtVideo)
211
+ %w[listing offtop yt_video book].each do |tag|
212
+ class_name = tag.split('_').map(&:capitalize).join
213
+ begin
214
+ klass = Koziolekweb::Tags.const_get(class_name)
215
+ Liquid::Template.register_tag(tag, klass)
216
+ rescue NameError
217
+ warn "[WARN] Tag '#{tag}' not registered: Koziolekweb::Tags::#{class_name} not defined"
218
+ end
219
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-koziolekweb-tags
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koziolek
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-10-17 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: jekyll
@@ -38,6 +37,7 @@ executables: []
38
37
  extensions: []
39
38
  extra_rdoc_files: []
40
39
  files:
40
+ - ".tool-versions"
41
41
  - CHANGELOG.md
42
42
  - Gemfile
43
43
  - README.md
@@ -51,7 +51,6 @@ licenses:
51
51
  metadata:
52
52
  source_code_uri: https://github.com/Koziolek/jekyll-koziolekweb-tags
53
53
  changelog_uri: https://github.com/Koziolek/jekyll-koziolekweb-tags/CHANGELOG.md
54
- post_install_message:
55
54
  rdoc_options: []
56
55
  require_paths:
57
56
  - lib
@@ -66,8 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
65
  - !ruby/object:Gem::Version
67
66
  version: '0'
68
67
  requirements: []
69
- rubygems_version: 3.3.4
70
- signing_key:
68
+ rubygems_version: 3.6.7
71
69
  specification_version: 4
72
70
  summary: Set of structural tags that helps to organise article.
73
71
  test_files: []