jekyll-l10n 1.3.0 → 1.3.4
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/lib/jekyll-l10n/constants.rb +10 -10
- data/lib/jekyll-l10n/extraction/compendium_merger.rb +38 -17
- data/lib/jekyll-l10n/extraction/compendium_translator.rb +18 -18
- data/lib/jekyll-l10n/extraction/config_loader.rb +8 -8
- data/lib/jekyll-l10n/extraction/dom_attribute_extractor.rb +4 -4
- data/lib/jekyll-l10n/extraction/dom_text_extractor.rb +6 -6
- data/lib/jekyll-l10n/extraction/extractor.rb +15 -15
- data/lib/jekyll-l10n/extraction/html_string_extractor.rb +5 -5
- data/lib/jekyll-l10n/extraction/logger.rb +6 -6
- data/lib/jekyll-l10n/extraction/result_saver.rb +12 -12
- data/lib/jekyll-l10n/jekyll/generator.rb +14 -14
- data/lib/jekyll-l10n/jekyll/localized_page.rb +13 -13
- data/lib/jekyll-l10n/jekyll/post_write_html_reprocessor.rb +14 -14
- data/lib/jekyll-l10n/jekyll/post_write_processor.rb +7 -7
- data/lib/jekyll-l10n/jekyll/regeneration_checker.rb +10 -10
- data/lib/jekyll-l10n/jekyll/url_filter.rb +17 -17
- data/lib/jekyll-l10n/po_file/loader.rb +4 -4
- data/lib/jekyll-l10n/po_file/manager.rb +15 -15
- data/lib/jekyll-l10n/po_file/merger.rb +3 -3
- data/lib/jekyll-l10n/po_file/path_builder.rb +1 -1
- data/lib/jekyll-l10n/po_file/reader.rb +42 -50
- data/lib/jekyll-l10n/po_file/writer.rb +20 -20
- data/lib/jekyll-l10n/translation/block_text_extractor.rb +5 -5
- data/lib/jekyll-l10n/translation/html_translator.rb +20 -20
- data/lib/jekyll-l10n/translation/libre_translator.rb +29 -26
- data/lib/jekyll-l10n/translation/page_translation_loader.rb +8 -8
- data/lib/jekyll-l10n/translation/translator.rb +26 -26
- data/lib/jekyll-l10n/utils/debug_logger.rb +6 -6
- data/lib/jekyll-l10n/utils/error_handler.rb +2 -2
- data/lib/jekyll-l10n/utils/external_link_icon_preserver.rb +11 -11
- data/lib/jekyll-l10n/utils/file_operations.rb +5 -5
- data/lib/jekyll-l10n/utils/html_elements.rb +5 -5
- data/lib/jekyll-l10n/utils/html_parser.rb +2 -2
- data/lib/jekyll-l10n/utils/html_text_utils.rb +12 -12
- data/lib/jekyll-l10n/utils/logger_formatter.rb +6 -6
- data/lib/jekyll-l10n/utils/page_locales_config.rb +32 -32
- data/lib/jekyll-l10n/utils/po_entry_converter.rb +10 -12
- data/lib/jekyll-l10n/utils/site_config_accessor.rb +4 -4
- data/lib/jekyll-l10n/utils/text_normalizer.rb +2 -2
- data/lib/jekyll-l10n/utils/text_validator.rb +1 -1
- data/lib/jekyll-l10n/utils/translation_resolver.rb +3 -3
- data/lib/jekyll-l10n/utils/url_path_builder.rb +5 -5
- data/lib/jekyll-l10n/utils/url_transformer.rb +13 -13
- data/lib/jekyll-l10n/utils/xpath_reference_generator.rb +2 -2
- data/lib/jekyll-l10n/version.rb +1 -1
- data/lib/jekyll-l10n.rb +48 -48
- metadata +58 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9b061ddf1f9f9072efe9135d023d05d55d7dd8545bd34988ecae6f59e03a2e2
|
|
4
|
+
data.tar.gz: 6c8704fa0e33e96c8e9918d5f7539db8203f291b4a2608e8946846e86fea8a94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 709ab40d1a6f0ada0810751f54279d4c466d00349a46a9c7916d4a705289af6e8c142ebbd31fefd520c1205089f1f662354f702b381fe8bb44129ab4fde157fc
|
|
7
|
+
data.tar.gz: acda3c29b32433e2c3b1e90004690955b0da0219a8c896f8cfc28aa61e2ff190e238352e08e35cd606c4717524b8d6c731cd3efac673be115ec89ce89a9fdb32
|
|
@@ -22,27 +22,27 @@ module Jekyll
|
|
|
22
22
|
# Matches ISO 639-1 (2 letter language) with optional ISO 3166-1 (2 letter country)
|
|
23
23
|
# Examples: 'en', 'es', 'fr', 'pt_BR', 'zh_CN'
|
|
24
24
|
# @return [Regexp]
|
|
25
|
-
LOCALE_PATTERN =
|
|
25
|
+
LOCALE_PATTERN = /^[a-z]{2}(_[A-Z]{2})?$/.freeze
|
|
26
26
|
|
|
27
27
|
# ## Translation Fallback Modes
|
|
28
28
|
|
|
29
29
|
# Fallback mode: use original English text if translation not found
|
|
30
30
|
# @return [String] "english"
|
|
31
|
-
FALLBACK_MODE_ENGLISH =
|
|
31
|
+
FALLBACK_MODE_ENGLISH = 'english'
|
|
32
32
|
|
|
33
33
|
# Fallback mode: wrap untranslated text with markers (e.g., "[UNTRANSLATED] text")
|
|
34
34
|
# @return [String] "marker"
|
|
35
|
-
FALLBACK_MODE_MARKER =
|
|
35
|
+
FALLBACK_MODE_MARKER = 'marker'
|
|
36
36
|
|
|
37
37
|
# Fallback mode: leave text blank if no translation found
|
|
38
38
|
# @return [String] "empty"
|
|
39
|
-
FALLBACK_MODE_EMPTY =
|
|
39
|
+
FALLBACK_MODE_EMPTY = 'empty'
|
|
40
40
|
|
|
41
41
|
# ## Translation Markers
|
|
42
42
|
|
|
43
43
|
# Marker used to indicate untranslated strings in marker fallback mode
|
|
44
44
|
# @return [String] "[UNTRANSLATED]"
|
|
45
|
-
UNTRANSLATED_MARKER =
|
|
45
|
+
UNTRANSLATED_MARKER = '[UNTRANSLATED]'
|
|
46
46
|
|
|
47
47
|
# ## PO File Formatting (GNU Gettext Standard)
|
|
48
48
|
|
|
@@ -82,7 +82,7 @@ module Jekyll
|
|
|
82
82
|
|
|
83
83
|
# Default directory for storing PO translation files
|
|
84
84
|
# @return [String] "_locales"
|
|
85
|
-
DEFAULT_LOCALES_DIR =
|
|
85
|
+
DEFAULT_LOCALES_DIR = '_locales'
|
|
86
86
|
|
|
87
87
|
# Default fallback mode when translation is not found
|
|
88
88
|
# @return [String] "english"
|
|
@@ -90,14 +90,14 @@ module Jekyll
|
|
|
90
90
|
|
|
91
91
|
# Default HTML attributes to extract from elements (can be overridden per-page)
|
|
92
92
|
# @return [Array<String>] ["title", "alt", "aria-label", "placeholder", "aria-description"]
|
|
93
|
-
DEFAULT_TRANSLATABLE_ATTRIBUTES = %w
|
|
93
|
+
DEFAULT_TRANSLATABLE_ATTRIBUTES = %w[title alt aria-label placeholder aria-description].freeze
|
|
94
94
|
|
|
95
95
|
# ## LibreTranslate Integration Defaults
|
|
96
96
|
|
|
97
97
|
# Default LibreTranslate API endpoint URL
|
|
98
98
|
# Uses localhost:5000 as default for local development
|
|
99
99
|
# @return [String] "http://localhost:5000"
|
|
100
|
-
DEFAULT_LIBRETRANSLATE_API_URL =
|
|
100
|
+
DEFAULT_LIBRETRANSLATE_API_URL = 'http://localhost:5000'
|
|
101
101
|
|
|
102
102
|
# Default timeout (in seconds) for LibreTranslate API requests
|
|
103
103
|
# @return [Integer] 300 seconds (5 minutes)
|
|
@@ -130,12 +130,12 @@ module Jekyll
|
|
|
130
130
|
# Default source locale for LibreTranslate API
|
|
131
131
|
# The language of the original content being translated
|
|
132
132
|
# @return [String] "en" (English)
|
|
133
|
-
DEFAULT_LIBRETRANSLATE_SOURCE_LOCALE =
|
|
133
|
+
DEFAULT_LIBRETRANSLATE_SOURCE_LOCALE = 'en'
|
|
134
134
|
|
|
135
135
|
# Default text format for LibreTranslate API requests
|
|
136
136
|
# Either 'text' (plain text) or 'html' (preserves markup)
|
|
137
137
|
# @return [String] "html"
|
|
138
|
-
DEFAULT_LIBRETRANSLATE_FORMAT =
|
|
138
|
+
DEFAULT_LIBRETRANSLATE_FORMAT = 'html'
|
|
139
139
|
end
|
|
140
140
|
end
|
|
141
141
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
3
|
+
require_relative '../po_file/manager'
|
|
4
|
+
require_relative '../utils/page_locales_config'
|
|
5
|
+
require_relative '../utils/site_config_accessor'
|
|
6
6
|
|
|
7
7
|
module Jekyll
|
|
8
8
|
module L10n
|
|
@@ -34,7 +34,7 @@ module Jekyll
|
|
|
34
34
|
def initialize(site)
|
|
35
35
|
@site = site
|
|
36
36
|
with_locales_data = SiteConfigAccessor.extract_locales_data(@site)
|
|
37
|
-
@site_config = PageLocalesConfig.new({
|
|
37
|
+
@site_config = PageLocalesConfig.new({ 'with_locales_data' => with_locales_data })
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Merge page-specific PO files into compendia for all locales.
|
|
@@ -55,6 +55,7 @@ module Jekyll
|
|
|
55
55
|
private
|
|
56
56
|
|
|
57
57
|
# Process a single locale: merge existing compendium with new page translations
|
|
58
|
+
# Skips writing when translations are unchanged to avoid unnecessary file rewrites
|
|
58
59
|
def process_locale(locale, po_manager, config)
|
|
59
60
|
compendium_path = File.join(@site.source, config.locales_dir, "#{locale}.po")
|
|
60
61
|
existing_compendium = load_existing_compendium(compendium_path)
|
|
@@ -62,12 +63,27 @@ module Jekyll
|
|
|
62
63
|
|
|
63
64
|
combined = build_combined_hash(existing_compendium)
|
|
64
65
|
merge_into_combined(combined, merged)
|
|
65
|
-
combined_entries = format_compendium_entries(combined)
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
unless compendium_unchanged?(existing_compendium, combined)
|
|
68
|
+
combined_entries = format_compendium_entries(combined)
|
|
69
|
+
po_manager.save_compendium(locale, combined_entries)
|
|
70
|
+
end
|
|
68
71
|
cleanup_locale_directory(locale, config)
|
|
69
72
|
end
|
|
70
73
|
|
|
74
|
+
# Check if compendium content is unchanged (same msgids and msgstrs)
|
|
75
|
+
def compendium_unchanged?(existing_compendium, combined)
|
|
76
|
+
return false if existing_compendium.empty? && !combined.empty?
|
|
77
|
+
|
|
78
|
+
normalized_existing = build_combined_hash(existing_compendium)
|
|
79
|
+
return false unless normalized_existing.keys.sort == combined.keys.sort
|
|
80
|
+
|
|
81
|
+
combined.all? do |msgid, data|
|
|
82
|
+
existing = normalized_existing[msgid]
|
|
83
|
+
existing && existing[:msgstr] == data[:msgstr]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
71
87
|
# Load existing compendium translations or return empty hash if not found
|
|
72
88
|
def load_existing_compendium(compendium_path)
|
|
73
89
|
if File.exist?(compendium_path)
|
|
@@ -89,9 +105,9 @@ module Jekyll
|
|
|
89
105
|
# Normalize entry format to ensure consistent hash structure with :msgstr and :reference keys
|
|
90
106
|
def normalize_compendium_entry(data)
|
|
91
107
|
if data.is_a?(Hash)
|
|
92
|
-
{ :
|
|
108
|
+
{ msgstr: data[:msgstr], reference: data[:reference] }
|
|
93
109
|
else
|
|
94
|
-
{ :
|
|
110
|
+
{ msgstr: data, reference: nil }
|
|
95
111
|
end
|
|
96
112
|
end
|
|
97
113
|
|
|
@@ -108,20 +124,24 @@ module Jekyll
|
|
|
108
124
|
|
|
109
125
|
# Update reference for existing entry if new reference is available
|
|
110
126
|
def update_entry_reference(combined_entry, entry)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
127
|
+
return unless combined_entry[:reference].nil? && entry.is_a?(Hash) && entry[:reference]
|
|
128
|
+
|
|
129
|
+
combined_entry[:reference] = entry[:reference]
|
|
114
130
|
end
|
|
115
131
|
|
|
116
|
-
# Create new entry
|
|
132
|
+
# Create new entry preserving any existing translation and reference
|
|
117
133
|
def create_new_entry(entry)
|
|
118
|
-
|
|
134
|
+
if entry.is_a?(Hash)
|
|
135
|
+
{ msgstr: entry[:msgstr] || '', reference: entry[:reference] }
|
|
136
|
+
else
|
|
137
|
+
{ msgstr: '', reference: nil }
|
|
138
|
+
end
|
|
119
139
|
end
|
|
120
140
|
|
|
121
141
|
# Convert combined hash to array of entries suitable for PO file writing
|
|
122
142
|
def format_compendium_entries(combined)
|
|
123
143
|
combined.map do |msgid, data|
|
|
124
|
-
entry = { :
|
|
144
|
+
entry = { msgid: msgid, msgstr: data[:msgstr] }
|
|
125
145
|
entry[:reference] = data[:reference] if data[:reference]
|
|
126
146
|
entry
|
|
127
147
|
end
|
|
@@ -134,9 +154,10 @@ module Jekyll
|
|
|
134
154
|
FileUtils.rm_rf(locale_dir) if File.directory?(locale_dir)
|
|
135
155
|
end
|
|
136
156
|
|
|
137
|
-
private :process_locale, :
|
|
138
|
-
:
|
|
139
|
-
:create_new_entry, :format_compendium_entries,
|
|
157
|
+
private :process_locale, :compendium_unchanged?, :load_existing_compendium,
|
|
158
|
+
:build_combined_hash, :normalize_compendium_entry, :merge_into_combined,
|
|
159
|
+
:update_entry_reference, :create_new_entry, :format_compendium_entries,
|
|
160
|
+
:cleanup_locale_directory
|
|
140
161
|
end
|
|
141
162
|
end
|
|
142
163
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
3
|
+
require_relative '../po_file/manager'
|
|
4
|
+
require_relative '../utils/page_locales_config'
|
|
5
|
+
require_relative '../utils/po_entry_converter'
|
|
6
|
+
require_relative '../utils/site_config_accessor'
|
|
7
|
+
require_relative '../utils/logger_formatter'
|
|
8
|
+
require_relative '../translation/libre_translator'
|
|
9
9
|
|
|
10
10
|
module Jekyll
|
|
11
11
|
module L10n
|
|
@@ -34,7 +34,7 @@ module Jekyll
|
|
|
34
34
|
def initialize(site)
|
|
35
35
|
@site = site
|
|
36
36
|
with_locales_data = SiteConfigAccessor.extract_locales_data(@site)
|
|
37
|
-
@site_config = PageLocalesConfig.new({
|
|
37
|
+
@site_config = PageLocalesConfig.new({ 'with_locales_data' => with_locales_data })
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Translate compendia for all configured locales.
|
|
@@ -68,7 +68,7 @@ module Jekyll
|
|
|
68
68
|
|
|
69
69
|
def process_single_locale(locale, config, translator, po_manager)
|
|
70
70
|
compendium_path = File.join(@site.source, config.locales_dir, "#{locale}.po")
|
|
71
|
-
LoggerFormatter.debug_if_enabled(
|
|
71
|
+
LoggerFormatter.debug_if_enabled('CompendiumTranslator',
|
|
72
72
|
"Processing compendium file: #{compendium_path}")
|
|
73
73
|
return unless File.exist?(compendium_path)
|
|
74
74
|
|
|
@@ -86,29 +86,29 @@ module Jekyll
|
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def log_compendia_enabled_check(enabled)
|
|
89
|
-
msg =
|
|
90
|
-
LoggerFormatter.debug_if_enabled(
|
|
89
|
+
msg = 'translate_compendia_for_locale called, libretranslate_enabled:'
|
|
90
|
+
LoggerFormatter.debug_if_enabled('CompendiumTranslator', "#{msg} #{enabled}")
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
def log_compendium_stats(locale, po_entries, compendium_path)
|
|
94
94
|
msg = "Locale #{locale}: Loaded #{po_entries.length} entries from compendium"
|
|
95
|
-
LoggerFormatter.debug_if_enabled(
|
|
95
|
+
LoggerFormatter.debug_if_enabled('CompendiumTranslator', "#{msg} #{compendium_path}")
|
|
96
96
|
|
|
97
97
|
empty_count = count_empty_entries(po_entries)
|
|
98
98
|
LoggerFormatter.debug_if_enabled(
|
|
99
|
-
|
|
99
|
+
'CompendiumTranslator',
|
|
100
100
|
"Locale #{locale}: #{empty_count} empty msgstr entries to translate"
|
|
101
101
|
)
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
def log_translation_complete_for_locale(locale)
|
|
105
105
|
msg = "Locale #{locale}: Translation complete, saving compendium"
|
|
106
|
-
LoggerFormatter.debug_if_enabled(
|
|
106
|
+
LoggerFormatter.debug_if_enabled('CompendiumTranslator', msg)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
def log_compendium_saved(locale, compendium_path)
|
|
110
110
|
msg = "Locale #{locale}: Saved compendium to"
|
|
111
|
-
LoggerFormatter.debug_if_enabled(
|
|
111
|
+
LoggerFormatter.debug_if_enabled('CompendiumTranslator', "#{msg} #{compendium_path}")
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
def count_empty_entries(po_entries)
|
|
@@ -118,14 +118,14 @@ module Jekyll
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def log_translation_start(config)
|
|
121
|
-
locales = config.locales.join(
|
|
122
|
-
Jekyll.logger.info
|
|
121
|
+
locales = config.locales.join(', ')
|
|
122
|
+
Jekyll.logger.info 'Localization',
|
|
123
123
|
"Starting LibreTranslate translation for locales: #{locales}"
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
def log_translation_complete(config)
|
|
127
|
-
locales = config.locales.join(
|
|
128
|
-
Jekyll.logger.info
|
|
127
|
+
locales = config.locales.join(', ')
|
|
128
|
+
Jekyll.logger.info 'Localization',
|
|
129
129
|
"LibreTranslate translation complete for locales: #{locales}"
|
|
130
130
|
end
|
|
131
131
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative '../utils/page_locales_config'
|
|
4
4
|
|
|
5
5
|
module Jekyll
|
|
6
6
|
module L10n
|
|
@@ -69,10 +69,10 @@ module Jekyll
|
|
|
69
69
|
# @return [Hash, nil] Page front matter data if found, nil otherwise
|
|
70
70
|
def find_page_config_for_file(file_path)
|
|
71
71
|
@site.pages.each do |page|
|
|
72
|
-
next unless page.data[
|
|
72
|
+
next unless page.data['with_locales'] == true
|
|
73
73
|
|
|
74
|
-
page_output = page.output_ext ? page.destination(
|
|
75
|
-
next unless file_path.end_with?(page_output.sub(%r
|
|
74
|
+
page_output = page.output_ext ? page.destination('') : page.destination('/')
|
|
75
|
+
next unless file_path.end_with?(page_output.sub(%r{/$}, '/index.html'))
|
|
76
76
|
|
|
77
77
|
return page.data
|
|
78
78
|
end
|
|
@@ -88,10 +88,10 @@ module Jekyll
|
|
|
88
88
|
# @param file_path [String] Path to file to check
|
|
89
89
|
# @return [Boolean] True if file is in a locale subdirectory
|
|
90
90
|
def skip_localized_page?(file_path)
|
|
91
|
-
relative_path = file_path.sub(@dest,
|
|
91
|
+
relative_path = file_path.sub(@dest, '')
|
|
92
92
|
|
|
93
93
|
all_locales = @site.pages.map do |p|
|
|
94
|
-
p.data.dig(
|
|
94
|
+
p.data.dig('with_locales_data', 'locales') || []
|
|
95
95
|
end
|
|
96
96
|
all_locales.flatten!
|
|
97
97
|
all_locales.uniq!
|
|
@@ -106,8 +106,8 @@ module Jekyll
|
|
|
106
106
|
# @param config [Hash] Page front matter data
|
|
107
107
|
# @return [Array<String>] CSS selectors for excluded elements
|
|
108
108
|
def extract_exclude_selectors(config)
|
|
109
|
-
config.data.dig(
|
|
110
|
-
[
|
|
109
|
+
config.data.dig('with_locales_data', 'extraction', 'exclude_selectors') ||
|
|
110
|
+
['script', 'style', 'code.language-plaintext', 'pre code']
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
3
|
+
require_relative '../utils/xpath_reference_generator'
|
|
4
|
+
require_relative '../utils/text_validator'
|
|
5
5
|
|
|
6
6
|
module Jekyll
|
|
7
7
|
module L10n
|
|
@@ -24,7 +24,7 @@ module Jekyll
|
|
|
24
24
|
# ['title', 'alt', 'aria-label'])
|
|
25
25
|
# # Returns array of extraction entries for all valid attribute values
|
|
26
26
|
module DomAttributeExtractor
|
|
27
|
-
|
|
27
|
+
module_function
|
|
28
28
|
|
|
29
29
|
# Extract attribute values from an HTML element.
|
|
30
30
|
#
|
|
@@ -47,7 +47,7 @@ module Jekyll
|
|
|
47
47
|
attrs = extract_node_attributes(node, translatable_attrs)
|
|
48
48
|
attrs.map do |attr_text, attr_name|
|
|
49
49
|
reference = XPathReferenceGenerator.generate(node, file_path, dest, attr_name)
|
|
50
|
-
{ :
|
|
50
|
+
{ msgid: attr_text, msgstr: '', reference: reference }
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
3
|
+
require_relative '../utils/text_normalizer'
|
|
4
|
+
require_relative '../utils/xpath_reference_generator'
|
|
5
|
+
require_relative '../utils/html_text_utils'
|
|
6
|
+
require_relative '../utils/html_elements'
|
|
7
|
+
require_relative '../utils/text_validator'
|
|
8
8
|
|
|
9
9
|
module Jekyll
|
|
10
10
|
module L10n
|
|
@@ -48,7 +48,7 @@ module Jekyll
|
|
|
48
48
|
return nil if text.nil?
|
|
49
49
|
|
|
50
50
|
reference = XPathReferenceGenerator.generate(node, file_path, dest)
|
|
51
|
-
{ :
|
|
51
|
+
{ msgid: text, msgstr: '', reference: reference }
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def extractable?(node)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
3
|
+
require_relative 'config_loader'
|
|
4
|
+
require_relative 'result_saver'
|
|
5
|
+
require_relative 'logger'
|
|
6
|
+
require_relative 'html_string_extractor'
|
|
7
|
+
require_relative '../utils/file_operations'
|
|
8
|
+
require_relative '../utils/site_config_accessor'
|
|
9
|
+
require_relative '../utils/error_handler'
|
|
10
10
|
|
|
11
11
|
module Jekyll
|
|
12
12
|
module L10n
|
|
@@ -72,7 +72,7 @@ module Jekyll
|
|
|
72
72
|
# result = extractor.extract_site
|
|
73
73
|
# puts "Processed #{result[:files_processed]} files"
|
|
74
74
|
def extract_site
|
|
75
|
-
Jekyll.logger.info
|
|
75
|
+
Jekyll.logger.info 'Localization', 'Extracting translatable strings...'
|
|
76
76
|
start_time = Time.now
|
|
77
77
|
stats = process_all_html_files
|
|
78
78
|
translate_all_compendia
|
|
@@ -81,8 +81,8 @@ module Jekyll
|
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def process_all_html_files
|
|
84
|
-
stats = { :
|
|
85
|
-
html_files = Dir.glob(File.join(@dest,
|
|
84
|
+
stats = { files_processed: 0, strings_extracted: 0, po_files_created: 0 }
|
|
85
|
+
html_files = Dir.glob(File.join(@dest, '**', '*.html'))
|
|
86
86
|
|
|
87
87
|
html_files.each do |file_path|
|
|
88
88
|
next if @config_loader.skip_localized_page?(file_path)
|
|
@@ -100,7 +100,7 @@ module Jekyll
|
|
|
100
100
|
config = find_libretranslate_config
|
|
101
101
|
return unless config
|
|
102
102
|
|
|
103
|
-
ErrorHandler.handle_with_logging(
|
|
103
|
+
ErrorHandler.handle_with_logging('machine translation') do
|
|
104
104
|
@result_saver.translate_compendia(config)
|
|
105
105
|
end
|
|
106
106
|
end
|
|
@@ -120,7 +120,7 @@ module Jekyll
|
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
def default_stats
|
|
123
|
-
{ :
|
|
123
|
+
{ files_processed: 0, strings_extracted: 0, po_files_created: 0 }
|
|
124
124
|
end
|
|
125
125
|
|
|
126
126
|
def extract_strings_from_file(file_path, config)
|
|
@@ -137,9 +137,9 @@ module Jekyll
|
|
|
137
137
|
return nil unless @site.respond_to?(:pages)
|
|
138
138
|
|
|
139
139
|
@site.pages.each do |page|
|
|
140
|
-
next unless page.data[
|
|
140
|
+
next unless page.data['with_locales'] == true
|
|
141
141
|
|
|
142
|
-
config = @config_loader.load_page_config(page.destination(
|
|
142
|
+
config = @config_loader.load_page_config(page.destination(''))
|
|
143
143
|
return config if config.libretranslate_enabled?
|
|
144
144
|
end
|
|
145
145
|
|
|
@@ -149,7 +149,7 @@ module Jekyll
|
|
|
149
149
|
private
|
|
150
150
|
|
|
151
151
|
def construct_page_path(file_path)
|
|
152
|
-
file_path.sub("#{@dest}/",
|
|
152
|
+
file_path.sub("#{@dest}/", '')
|
|
153
153
|
end
|
|
154
154
|
end
|
|
155
155
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
3
|
+
require_relative 'dom_text_extractor'
|
|
4
|
+
require_relative 'dom_attribute_extractor'
|
|
5
|
+
require_relative 'logger'
|
|
6
6
|
|
|
7
7
|
module Jekyll
|
|
8
8
|
module L10n
|
|
@@ -92,10 +92,10 @@ module Jekyll
|
|
|
92
92
|
|
|
93
93
|
@exclude_selectors.any? { |selector| node.matches?(selector) }
|
|
94
94
|
rescue Nokogiri::CSS::SyntaxError => e
|
|
95
|
-
Jekyll.logger.warn
|
|
95
|
+
Jekyll.logger.warn 'Localization', "CSS selector syntax error: #{e.message}"
|
|
96
96
|
false
|
|
97
97
|
rescue StandardError => e
|
|
98
|
-
Jekyll.logger.warn
|
|
98
|
+
Jekyll.logger.warn 'Localization', "Selector matching error (continuing): #{e.message}"
|
|
99
99
|
false
|
|
100
100
|
end
|
|
101
101
|
end
|
|
@@ -22,7 +22,7 @@ module Jekyll
|
|
|
22
22
|
# @param error [StandardError] The error that occurred
|
|
23
23
|
# @return [void]
|
|
24
24
|
def self.log_error(file_path, error)
|
|
25
|
-
Jekyll.logger.error
|
|
25
|
+
Jekyll.logger.error 'Localization', "Error extracting from #{file_path}: #{error.message}"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# Log extraction completion summary.
|
|
@@ -37,11 +37,11 @@ module Jekyll
|
|
|
37
37
|
# @param elapsed [Float] Time elapsed in seconds
|
|
38
38
|
# @return [void]
|
|
39
39
|
def self.log_summary(stats, elapsed)
|
|
40
|
-
Jekyll.logger.info
|
|
41
|
-
Jekyll.logger.info
|
|
42
|
-
Jekyll.logger.info
|
|
43
|
-
Jekyll.logger.info
|
|
44
|
-
Jekyll.logger.info
|
|
40
|
+
Jekyll.logger.info 'Localization', 'Extraction complete:'
|
|
41
|
+
Jekyll.logger.info 'Localization', " Files processed: #{stats[:files_processed]}"
|
|
42
|
+
Jekyll.logger.info 'Localization', " Strings extracted: #{stats[:strings_extracted]}"
|
|
43
|
+
Jekyll.logger.info 'Localization', " PO files created/updated: #{stats[:po_files_created]}"
|
|
44
|
+
Jekyll.logger.info 'Localization', " Time: #{elapsed.round(2)}s"
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
3
|
+
require_relative '../po_file/manager'
|
|
4
|
+
require_relative '../utils/page_locales_config'
|
|
5
|
+
require_relative '../utils/site_config_accessor'
|
|
6
|
+
require_relative '../utils/logger_formatter'
|
|
7
|
+
require_relative 'compendium_translator'
|
|
8
|
+
require_relative 'compendium_merger'
|
|
9
9
|
|
|
10
10
|
module Jekyll
|
|
11
11
|
module L10n
|
|
@@ -34,7 +34,7 @@ module Jekyll
|
|
|
34
34
|
def initialize(site)
|
|
35
35
|
@site = site
|
|
36
36
|
with_locales_data = SiteConfigAccessor.extract_locales_data(@site)
|
|
37
|
-
@site_config = PageLocalesConfig.new({
|
|
37
|
+
@site_config = PageLocalesConfig.new({ 'with_locales_data' => with_locales_data })
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Save extraction results to PO files.
|
|
@@ -51,15 +51,15 @@ module Jekyll
|
|
|
51
51
|
# - :strings_extracted [Integer] Number of extracted strings
|
|
52
52
|
# - :po_files_created [Integer] Number of PO files created/updated
|
|
53
53
|
def save_results(config, entries, page_path)
|
|
54
|
-
LoggerFormatter.debug_if_enabled(
|
|
54
|
+
LoggerFormatter.debug_if_enabled('ExtractionResultSaver', "Processing page: #{page_path}")
|
|
55
55
|
|
|
56
56
|
po_manager = PoFileManager.new(@site, config.locales_dir)
|
|
57
57
|
po_files_created = save_po_files(po_manager, config, entries, page_path)
|
|
58
58
|
|
|
59
59
|
{
|
|
60
|
-
:
|
|
61
|
-
:
|
|
62
|
-
:
|
|
60
|
+
files_processed: 1,
|
|
61
|
+
strings_extracted: entries.length,
|
|
62
|
+
po_files_created: po_files_created
|
|
63
63
|
}
|
|
64
64
|
end
|
|
65
65
|
|
|
@@ -81,7 +81,7 @@ module Jekyll
|
|
|
81
81
|
po_files_created = 0
|
|
82
82
|
|
|
83
83
|
config.locales.each do |locale|
|
|
84
|
-
po_files_created += 1 if po_manager.save_po_file(locale, entries, :
|
|
84
|
+
po_files_created += 1 if po_manager.save_po_file(locale, entries, page_path: page_path)
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
CompendiumMerger.new(@site).merge_compendia(po_manager, config) if config.update_compendium?
|