jekyll-koziolekweb-tags 0.3.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: 43266d61852a499977df46bd3d4626c0368b121dc1d962857c41b0308470bf20
4
- data.tar.gz: f5f7fcdcade5cdead24b51f2cf2cd46a06cf3d71f42c0d9cdfb37ff441ba9749
3
+ metadata.gz: a9e7fa5d6b1d9504b547aca1892fd816aedc77f01e94e85693647f5506977eb8
4
+ data.tar.gz: 598f5614d3d662f73d79002690eb7eba5bf209c06f74b9edfc664727849bac6f
5
5
  SHA512:
6
- metadata.gz: 5f8d6d2baee780bcfdc57cb95a4daea148c5a3650a309f0842fdee46b9bbf8179732685ea9fe3e8a97576ef22593851f1a2044a187e20754229f20ca0230536f
7
- data.tar.gz: 31c0a52191c88d868658edecfb63432844f9953609bcacdc6df4c25419d3a71dd85a80cfabb070125ba49228b6b2d6a119780e452aae0e77054b7aa877e2c543
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.3.0"
6
+ VERSION = "0.4.0"
7
7
  end
8
8
  end
9
9
  end
@@ -1,73 +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}```"
35
- title_with_parese = "#{@title}"
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
36
38
 
37
- "<p class='listing'> Listing #{@@file_state[current_file]}. #{@title_with_parese}</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
38
48
  end
39
49
  end
40
50
 
41
51
  class Offtop < Liquid::Block
52
+ VALID_DIRECTIONS = %w[right left].freeze
42
53
 
43
54
  def initialize(tag_name, markup, tokens)
44
55
  super
45
- @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
46
63
  end
47
64
 
48
65
  def render(context)
49
66
  content = super
50
67
  "<aside class=\"offtopic f-#{@direction}\">#{content}</aside>"
51
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
52
80
  end
53
81
 
54
82
  class YtVideo < Liquid::Tag
55
83
  def initialize(tag_name, video_id, tokens)
56
84
  super
57
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
+
58
91
  end
59
92
 
60
93
  def render(_context)
61
94
  <<~HTML
62
- <div class="video">
63
- <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>
64
- </div>
65
- 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
66
99
  end
100
+
101
+ private
102
+
103
+ def valid_video_id?(video_id)
104
+ video_id.match?(/\A[\w-]{11}\z/)
105
+ end
106
+
67
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
+
68
208
  end
69
209
  end
70
210
 
71
- Liquid::Template.register_tag('listing', Koziolekweb::Tags::Listing)
72
- Liquid::Template.register_tag('offtop', Koziolekweb::Tags::Offtop)
73
- 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.3.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: 2025-05-15 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,11 +37,11 @@ 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
44
44
  - Rakefile
45
- - jekyll-koziolekweb-tags.gemspec
46
45
  - lib/jekyll/koziolekweb/tags.rb
47
46
  - lib/jekyll/koziolekweb/tags/version.rb
48
47
  - sig/jekyll/koziolekweb/tags.rbs
@@ -52,7 +51,6 @@ licenses:
52
51
  metadata:
53
52
  source_code_uri: https://github.com/Koziolek/jekyll-koziolekweb-tags
54
53
  changelog_uri: https://github.com/Koziolek/jekyll-koziolekweb-tags/CHANGELOG.md
55
- post_install_message:
56
54
  rdoc_options: []
57
55
  require_paths:
58
56
  - lib
@@ -67,8 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
65
  - !ruby/object:Gem::Version
68
66
  version: '0'
69
67
  requirements: []
70
- rubygems_version: 3.4.10
71
- signing_key:
68
+ rubygems_version: 3.6.7
72
69
  specification_version: 4
73
70
  summary: Set of structural tags that helps to organise article.
74
71
  test_files: []
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/jekyll/koziolekweb/tags/version"
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = "jekyll-koziolekweb-tags"
7
- spec.version = Jekyll::Koziolekweb::Tags::VERSION
8
- spec.authors = ["Koziolek"]
9
- spec.email = ["bjkuczynski@gmail.com"]
10
-
11
- spec.summary = "Set of structural tags that helps to organise article."
12
- spec.description = "Here you will find a set of tags that allow you to create code listings with numbering, notes using the <aside> element and more."
13
- spec.homepage = "https://github.com/Koziolek/jekyll-koziolekweb-tags"
14
- spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.4.0"
16
- spec.add_dependency "jekyll", ">= 3.7", "< 5.0"
17
-
18
- # Specify which files should be added to the gem when it is released.
19
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
- spec.files = Dir.chdir(__dir__) do
21
- `git ls-files -z`.split("\x0").reject do |f|
22
- (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
23
- end
24
- end
25
- spec.bindir = "exe"
26
- spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
-
28
- spec.metadata["source_code_uri"] = "https://github.com/Koziolek/jekyll-koziolekweb-tags"
29
- spec.metadata["changelog_uri"] = "https://github.com/Koziolek/jekyll-koziolekweb-tags/CHANGELOG.md"
30
-
31
-
32
- spec.require_paths = ["lib"]
33
-
34
- # Uncomment to register a new dependency of your gem
35
- # spec.add_dependency "example-gem", "~> 1.0"
36
-
37
- # For more information and examples about making a new gem, check out our
38
- # guide at: https://bundler.io/guides/creating_gem.html
39
- end