jekyll-chatgpt-translate 0.1.0 → 0.3.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.0pdd.yml +1 -1
  3. data/.github/workflows/actionlint.yml +2 -2
  4. data/.github/workflows/copyrights.yml +2 -2
  5. data/.github/workflows/markdown-lint.yml +3 -3
  6. data/.github/workflows/pdd.yml +2 -2
  7. data/.github/workflows/rake.yml +2 -2
  8. data/.github/workflows/reuse.yml +2 -2
  9. data/.github/workflows/typos.yml +19 -0
  10. data/.github/workflows/xcop.yml +2 -2
  11. data/.github/workflows/yamllint.yml +2 -2
  12. data/.gitignore +4 -4
  13. data/.rubocop.yml +2 -1
  14. data/.rultor.yml +1 -1
  15. data/Gemfile +7 -6
  16. data/LICENSE.txt +1 -1
  17. data/LICENSES/MIT.txt +1 -1
  18. data/README.md +25 -25
  19. data/REUSE.toml +7 -7
  20. data/Rakefile +1 -1
  21. data/features/cli.feature +1 -1
  22. data/features/gem_package.feature +1 -1
  23. data/features/step_definitions/steps.rb +1 -1
  24. data/features/support/env.rb +1 -1
  25. data/jekyll-chatgpt-translate.gemspec +12 -10
  26. data/lib/jekyll-chatgpt-translate/chatgpt.rb +33 -33
  27. data/lib/jekyll-chatgpt-translate/generator.rb +90 -88
  28. data/lib/jekyll-chatgpt-translate/pars.rb +2 -2
  29. data/lib/jekyll-chatgpt-translate/permalink.rb +2 -2
  30. data/lib/jekyll-chatgpt-translate/ping.rb +2 -2
  31. data/lib/jekyll-chatgpt-translate/plain.rb +2 -2
  32. data/lib/jekyll-chatgpt-translate/prompt.rb +2 -2
  33. data/lib/jekyll-chatgpt-translate/version.rb +2 -2
  34. data/lib/jekyll-chatgpt-translate.rb +1 -1
  35. data/test/test__helper.rb +5 -4
  36. data/test/test_chatgpt.rb +2 -2
  37. data/test/test_generator.rb +2 -2
  38. data/test/test_pars.rb +2 -2
  39. data/test/test_permalink.rb +2 -2
  40. data/test/test_ping.rb +2 -2
  41. data/test/test_plain.rb +2 -2
  42. data/test/test_prompt.rb +2 -2
  43. metadata +67 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1af86cfed83e4dc57c410b6cab0826e2025b9ad3dee77ef6aa6469322ee9c09a
4
- data.tar.gz: 2d8c75e9d8c4a4951dd2804e729cee5f64758772849953f05d1a0e83ff487e51
3
+ metadata.gz: a33656cc2e5c82d51feb6cb2900c339cce6f210bbe9615dd19756f457ace47c7
4
+ data.tar.gz: 2867d144dfa9e867a6bbecce340a1d77eb908a54c9790fbef9f7985223861250
5
5
  SHA512:
6
- metadata.gz: c0bb602c3b3c6d3132f0b6261996f295dad4acec631ccd89c4a19f69115a1639ae9944ce19bd2f257265cdd301786da74bb57c25f5fdcb62c13383108c750ebd
7
- data.tar.gz: 28ccf65532f29f122c162033623b6bd56be44e9f44e3f088220bcb0f65603de5af1a7701955a309cf12622d23de492ff3381676d172212e26329dae64bf87c9c
6
+ metadata.gz: 370cf4f063e237ab00af98e0212b738211d33f868e24c89547a4b378f867389ff46c6dfce39ac90553e25e448751490b8c465382d5a6ffdefb6aa8bca59b6826
7
+ data.tar.gz: beafec1d47ac6b1f731d9557de276c7ce4d9b9223a6a19e3791e7b9555cf2d3950501e99d77bc92c54501a0c8b8d4ba21710cb35102ad4a932430330c32b6795
data/.0pdd.yml CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  errors:
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -15,7 +15,7 @@ jobs:
15
15
  timeout-minutes: 15
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v6
19
19
  - name: Download actionlint
20
20
  id: get_actionlint
21
21
  run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -15,5 +15,5 @@ jobs:
15
15
  timeout-minutes: 15
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v6
19
19
  - uses: yegor256/copyrights-action@0.0.8
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -19,5 +19,5 @@ jobs:
19
19
  timeout-minutes: 15
20
20
  runs-on: ubuntu-24.04
21
21
  steps:
22
- - uses: actions/checkout@v4
23
- - uses: articulate/actions-markdownlint@v1
22
+ - uses: actions/checkout@v6
23
+ - uses: DavidAnson/markdownlint-cli2-action@v20.0.0
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -15,5 +15,5 @@ jobs:
15
15
  timeout-minutes: 15
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v6
19
19
  - uses: volodya-lombrozo/pdd-action@master
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -18,7 +18,7 @@ jobs:
18
18
  ruby: [3.3]
19
19
  runs-on: ${{ matrix.os }}
20
20
  steps:
21
- - uses: actions/checkout@v4
21
+ - uses: actions/checkout@v6
22
22
  - uses: ruby/setup-ruby@v1
23
23
  with:
24
24
  ruby-version: ${{ matrix.ruby }}
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -15,5 +15,5 @@ jobs:
15
15
  timeout-minutes: 15
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v6
19
19
  - uses: fsfe/reuse-action@v5
@@ -0,0 +1,19 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
+ # SPDX-License-Identifier: MIT
3
+ ---
4
+ # yamllint disable rule:line-length
5
+ name: typos
6
+ 'on':
7
+ push:
8
+ branches:
9
+ - master
10
+ pull_request:
11
+ branches:
12
+ - master
13
+ jobs:
14
+ typos:
15
+ timeout-minutes: 15
16
+ runs-on: ubuntu-24.04
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+ - uses: crate-ci/typos@v1.32.0
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -15,5 +15,5 @@ jobs:
15
15
  timeout-minutes: 15
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v6
19
19
  - uses: g4s8/xcop-action@master
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
@@ -15,5 +15,5 @@ jobs:
15
15
  timeout-minutes: 15
16
16
  runs-on: ubuntu-24.04
17
17
  steps:
18
- - uses: actions/checkout@v4
18
+ - uses: actions/checkout@v6
19
19
  - uses: ibiqlik/action-yamllint@v3
data/.gitignore CHANGED
@@ -1,12 +1,12 @@
1
- *.gem
2
- .DS_Store
1
+ _chatgpt-translate/
3
2
  .bundle/
3
+ .DS_Store
4
4
  .idea/
5
5
  .yardoc/
6
- Gemfile.lock
7
- _chatgpt-translate/
6
+ *.gem
8
7
  coverage/
9
8
  doc/
9
+ Gemfile.lock
10
10
  node_modules/
11
11
  rdoc/
12
12
  vendor/
data/.rubocop.yml CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  AllCops:
@@ -48,3 +48,4 @@ Metrics/ClassLength:
48
48
  Max: 200
49
49
  Style/ClassVars:
50
50
  Enabled: false
51
+ require: []
data/.rultor.yml CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  ---
4
4
  # yamllint disable rule:line-length
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  source 'https://rubygems.org'
@@ -8,13 +8,14 @@ gemspec
8
8
 
9
9
  gem 'cucumber', '~>9.2', require: false
10
10
  gem 'kramdown-parser-gfm', '~>1.1', require: false
11
- gem 'minitest', '~>5.25', require: false
11
+ gem 'minitest', '~>6.0', require: false
12
12
  gem 'minitest-reporters', '~>1.7', require: false
13
13
  gem 'rake', '~>13.2', require: false
14
+ gem 'rdoc', '~>7.0', require: false
14
15
  gem 'rubocop', '~>1.64', require: false
15
- gem 'rubocop-minitest', '>0', require: false
16
- gem 'rubocop-performance', '>0', require: false
17
- gem 'rubocop-rake', '>0', require: false
16
+ gem 'rubocop-minitest', '~>0.38', require: false
17
+ gem 'rubocop-performance', '>1.26', require: false
18
+ gem 'rubocop-rake', '~>0.7', require: false
18
19
  gem 'simplecov', '~>0.22', require: false
19
- gem 'simplecov-cobertura', '~>2.1', require: false
20
+ gem 'simplecov-cobertura', '~>3.1', require: false
20
21
  gem 'webmock', '~>3.24', require: false
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2023-2025 Yegor Bugayenko
3
+ Copyright (c) 2023-2026 Yegor Bugayenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the 'Software'), to deal
data/LICENSES/MIT.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2023-2025 Yegor Bugayenko
3
+ Copyright (c) 2023-2026 Yegor Bugayenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the 'Software'), to deal
data/README.md CHANGED
@@ -6,17 +6,18 @@
6
6
  [![Gem Version](https://badge.fury.io/rb/jekyll-chatgpt-translate.svg)](https://badge.fury.io/rb/jekyll-chatgpt-translate)
7
7
 
8
8
  If you have a [Jekyll](https://jekyllrb.com/) static site,
9
- this plugin may help you automatically
10
- translate its pages to another language, through
11
- [ChatGPT](https://chat.openai.com/). See how it
12
- works for [my blog](https://github.com/yegor256/ru.yegor256.com),
13
- for example [this page](https://ru.yegor256.com/2023-08-13-dictators.html)
14
- is translated to
15
- [English](https://www.yegor256.com/en/2023/08/13/dictators.html).
16
-
17
- Install it first (you need
18
- [Ruby 3+](https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/)
19
- and [Jekyll 3+](https://jekyllrb.com/)):
9
+ this plugin may help you automatically
10
+ translate its pages to another language, through
11
+ [ChatGPT](https://chat.openai.com/).
12
+ See how it works for [my blog](https://github.com/yegor256/ru.yegor256.com),
13
+ for example [this page](https://ru.yegor256.com/2023-08-13-dictators.html)
14
+ is translated to
15
+ [English](https://www.yegor256.com/en/2023/08/13/dictators.html).
16
+
17
+ Install it first
18
+ (you need
19
+ [Ruby 3+](https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/)
20
+ and [Jekyll 3+](https://jekyllrb.com/)):
20
21
 
21
22
  ```bash
22
23
  gem install jekyll-chatgpt-translate
@@ -49,29 +50,28 @@ where the layout for Chinese is `_layout/chinese-translated.html` and for
49
50
  French is `_layout/translated.html` (you must have these files).
50
51
 
51
52
  OpenAI API KEY must be set in the `OPENAI_API_KEY` environment variable,
52
- otherwise
53
- the plugin will not do any translation and won't generate translated pages.
54
- You can get your key
55
- [here][open-ai].
53
+ otherwise the plugin will not do any translation
54
+ and won't generate translated pages.
55
+ You can get your key go to [OpenAI][open-ai].
56
56
 
57
57
  OpenAI API base URL can be customized by the `OPENAI_API_BASE`
58
- environment variable.
58
+ environment variable.
59
59
  If this variable is not set, the default value is `https://api.openai.com/`.
60
60
 
61
61
  Inside the original page you can use `{{ page.chatgpt-translate.urls[XX] }}`
62
- in order to render the URL
63
- of the translated page, where `XX` is the [ISO-639-1][iso-639]
64
- code of the target language.
62
+ in order to render the URL
63
+ of the translated page, where `XX` is the [ISO-639-1][iso-639]
64
+ code of the target language.
65
65
  Inside the translated page you can use
66
- `{{ page.chatgpt-translate.original-url }}` in order
67
- to get the URL of the page that was translated.
66
+ `{{ page.chatgpt-translate.original-url }}` in order
67
+ to get the URL of the page that was translated.
68
68
 
69
69
  You can also use `{{ page.chatgpt-translate.model }}`
70
- inside both the original page and the translated one,
71
- to refer to the model of ChatGPT.
70
+ inside both the original page and the translated one,
71
+ to refer to the model of ChatGPT.
72
72
  The presence of `{{ page.chatgpt-translate }}` means that the
73
- page was translated or the translated HTML was downloaded
74
- and placed into the `_site` directory.
73
+ page was translated or the translated HTML was downloaded
74
+ and placed into the `_site` directory.
75
75
 
76
76
  ## Options
77
77
 
data/REUSE.toml CHANGED
@@ -4,10 +4,17 @@
4
4
  version = 1
5
5
  [[annotations]]
6
6
  path = [
7
+ ".DS_Store",
8
+ ".gitattributes",
9
+ ".gitignore",
10
+ ".pdd",
7
11
  "**.json",
8
12
  "**.md",
9
13
  "**.png",
10
14
  "**.txt",
15
+ "**/.DS_Store",
16
+ "**/.gitignore",
17
+ "**/.pdd",
11
18
  "**/*.csv",
12
19
  "**/*.jpg",
13
20
  "**/*.json",
@@ -17,15 +24,8 @@ path = [
17
24
  "**/*.svg",
18
25
  "**/*.txt",
19
26
  "**/*.vm",
20
- "**/.DS_Store",
21
- "**/.gitignore",
22
- "**/.pdd",
23
27
  "**/CNAME",
24
28
  "**/Gemfile.lock",
25
- ".DS_Store",
26
- ".gitattributes",
27
- ".gitignore",
28
- ".pdd",
29
29
  "Gemfile.lock",
30
30
  "README.md",
31
31
  "renovate.json",
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'rubygems'
data/features/cli.feature CHANGED
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  Feature: Simple site building
4
4
  I want to be able to build a site
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
1
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  Feature: Gem Package
4
4
  As a source code writer I want to be able to
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'tmpdir'
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'simplecov'
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'English'
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
10
10
  s.required_ruby_version = '>= 3.0'
11
11
  s.name = 'jekyll-chatgpt-translate'
12
- s.version = '0.1.0'
12
+ s.version = '0.3.0'
13
13
  s.license = 'MIT'
14
14
  s.summary = 'Translate Jekyll Pages Through ChatGPT'
15
15
  s.description = [
@@ -23,13 +23,15 @@ Gem::Specification.new do |s|
23
23
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
24
  s.rdoc_options = ['--charset=UTF-8']
25
25
  s.extra_rdoc_files = %w[README.md LICENSE.txt]
26
- s.add_dependency 'humanize', '>= 2'
27
- s.add_dependency 'iri', '>= 0'
28
- s.add_dependency 'iso-639', '>= 0'
29
- s.add_dependency 'jekyll', '>= 3'
30
- s.add_dependency 'json', '>= 2'
31
- s.add_dependency 'redcarpet', '>= 3'
32
- s.add_dependency 'ruby-openai', '>= 5'
33
- s.add_dependency 'tiktoken_ruby', '>= 0.0.6'
26
+ s.add_dependency 'base64', '~>0.3'
27
+ s.add_dependency 'elapsed', '~>0.2'
28
+ s.add_dependency 'humanize', '~>3.1'
29
+ s.add_dependency 'iri', '~>0.11'
30
+ s.add_dependency 'iso-639', '~>0.3'
31
+ s.add_dependency 'jekyll', '>= 3.0', '< 5.0'
32
+ s.add_dependency 'json', '~>2.18'
33
+ s.add_dependency 'redcarpet', '~>3.6'
34
+ s.add_dependency 'ruby-openai', '~>8.3'
35
+ s.add_dependency 'tiktoken_ruby', '~>0.0'
34
36
  s.metadata['rubygems_mfa_required'] = 'true'
35
37
  end
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
+ require 'elapsed'
7
+ require 'iso-639'
6
8
  require 'jekyll'
7
9
  require 'json'
8
10
  require 'openai'
9
- require 'iso-639'
10
11
  require 'tiktoken_ruby'
11
12
  require_relative 'pars'
12
13
  require_relative 'prompt'
@@ -16,7 +17,7 @@ module GptTranslate; end
16
17
 
17
18
  # Abstraction of ChatGPT.
18
19
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
19
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
20
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
20
21
  # License:: MIT
21
22
  class GptTranslate::ChatGPT
22
23
  # Is TRUE if we already shown to the user the available models.
@@ -72,7 +73,7 @@ class GptTranslate::ChatGPT
72
73
  ready[i] = "* #{translate_par(par[2..])}"
73
74
  elsif /^[0-9]+\. /.match?(par)
74
75
  ready[i] = "1. #{translate_par(par.split('.', 2)[1])}"
75
- elsif /^[^\p{Alnum}\*'"\[]/.match?(par)
76
+ elsif /^[^\p{Alnum}*'"\[]/.match?(par)
76
77
  Jekyll.logger.debug("Not translating this, b/c it's not a plain text: #{par.inspect}")
77
78
  ready[i] = par
78
79
  else
@@ -115,40 +116,39 @@ class GptTranslate::ChatGPT
115
116
  @@models_printed = true
116
117
  end
117
118
  prompt = GptTranslate::Prompt.new(par, @source, @target).to_s
118
- start = Time.now
119
119
  answer = nil
120
120
  attempt = 0
121
- begin
122
- response = @client.chat(
123
- parameters: {
124
- model: @model,
125
- messages: [{ role: 'user', content: prompt }],
126
- temperature: 0.7
127
- }
128
- )
129
- json = response.is_a?(Hash) ? response : JSON.parse(response)
130
- answer = json.dig('choices', 0, 'message', 'content')
131
- if answer.nil?
132
- Jekyll.logger.error("No content returned by ChatGPT: #{response}")
133
- raise 'No content returned by ChatGPT'
134
- end
135
- Jekyll.logger.debug("ChatGPT prompt: #{prompt.inspect}, ChatGPT answer: #{answer.inspect}")
136
- rescue StandardError => e
137
- attempt += 1
138
- if attempt < 4
139
- Jekyll.logger.error(
140
- "ChatGPT failed to answer to #{prompt.inspect}" \
141
- "(attempt no.#{attempt}): #{e.message.inspect}"
121
+ elapsed(Jekyll.logger) do
122
+ begin
123
+ response = @client.chat(
124
+ parameters: {
125
+ model: @model,
126
+ messages: [{ role: 'user', content: prompt }],
127
+ temperature: 0.7
128
+ }
142
129
  )
143
- retry
130
+ json = response.is_a?(Hash) ? response : JSON.parse(response)
131
+ answer = json.dig('choices', 0, 'message', 'content')
132
+ if answer.nil?
133
+ Jekyll.logger.error("No content returned by ChatGPT: #{response}")
134
+ raise 'No content returned by ChatGPT'
135
+ end
136
+ Jekyll.logger.debug("ChatGPT prompt: #{prompt.inspect}, ChatGPT answer: #{answer.inspect}")
137
+ rescue StandardError => e
138
+ attempt += 1
139
+ if attempt < 4
140
+ Jekyll.logger.error(
141
+ "ChatGPT failed to answer to #{prompt.inspect}" \
142
+ "(attempt no.#{attempt}): #{e.message.inspect}"
143
+ )
144
+ retry
145
+ end
146
+ raise e
144
147
  end
145
- raise e
148
+ throw :"Translated #{par.split.count} #{@source.upcase} words \
149
+ to #{answer.split.count} #{@target.upcase} words \
150
+ through #{@model}: #{"#{par[0..24]}...".inspect}"
146
151
  end
147
- Jekyll.logger.info(
148
- "Translated #{par.split.count} #{@source.upcase} words " \
149
- "to #{answer.split.count} #{@target.upcase} words " \
150
- "through #{@model} in #{(Time.now - start).round(2)}s: #{"#{par[0..24]}...".inspect}"
151
- )
152
152
  answer
153
153
  end
154
154
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
- require 'jekyll'
6
+ require 'elapsed'
7
7
  require 'fileutils'
8
+ require 'jekyll'
8
9
  require 'json'
9
10
  require_relative 'chatgpt'
10
11
  require_relative 'permalink'
@@ -17,7 +18,7 @@ module GptTranslate; end
17
18
 
18
19
  # Pages generator.
19
20
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
20
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
21
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
21
22
  # License:: MIT
22
23
  class GptTranslate::Generator < Jekyll::Generator
23
24
  safe true
@@ -29,7 +30,7 @@ class GptTranslate::Generator < Jekyll::Generator
29
30
  Jekyll.logger.info("jekyll-chatgpt-translate #{GptTranslate::VERSION} skipped, due to the --offline option")
30
31
  return
31
32
  end
32
- Jekyll.logger.info("jekyll-chatgpt-translate #{GptTranslate::VERSION} starting...")
33
+ Jekyll.logger.info("jekyll-chatgpt-translate #{GptTranslate::VERSION} starts (no --offline option)...")
33
34
  config ||= site.config['chatgpt-translate'] || {}
34
35
  home = config['tmpdir'] || '_chatgpt-translate'
35
36
  key = api_key(config)
@@ -41,101 +42,100 @@ class GptTranslate::Generator < Jekyll::Generator
41
42
  version = config['version'] || GptTranslate::VERSION
42
43
  threshold = config['threshold'] || 1024
43
44
  min_chars = config['min_chars'] || 128
44
- start = Time.now
45
45
  translated = 0
46
46
  copied = 0
47
47
  model = config['model'] || 'gpt-3.5-turbo'
48
- marker = "Translated by ChatGPT #{model}#{version.empty? ? '' : "/#{version}"}"
49
- site.posts.docs.shuffle.each_with_index do |doc, pos|
50
- plain = GptTranslate::Plain.new(doc.content).to_s
51
- layout = doc['layout']
52
- config['targets'].each do |target|
53
- pstart = Time.now
54
- link = GptTranslate::Permalink.new(doc, target['permalink']).to_path
55
- lang = target['language']
56
- raise 'Language must be defined for each target' if target.nil?
57
- only = target['only']
58
- if !only.nil? && layout != only
59
- Jekyll.logger.debug("Not translating #{link.inspect}, b/c 'only' set to '#{only}'")
60
- next
61
- end
62
- path = File.join(home, lang, doc.basename.gsub(/\.md$/, "-#{lang}.md"))
63
- FileUtils.mkdir_p(File.dirname(path))
64
- File.write(
65
- path,
66
- [
67
- '---',
68
- "layout: #{target['layout'] || layout}",
69
- "title: #{doc['title'].to_json}",
70
- "description: #{doc['description'].to_json}",
71
- "permalink: #{link.to_json}",
72
- 'chatgpt-translate:',
73
- " original-url: #{doc.url.to_json}",
74
- " language: #{lang.to_json}",
75
- " model: #{model.to_json}",
76
- '---'
77
- ].join("\n")
78
- )
79
- html = config['no_download'].nil? ? GptTranslate::Ping.new(site, link).download : nil
80
- needed = false
81
- added = false
82
- if html.nil?
83
- Jekyll.logger.info("The page is absent, need to translate #{link.inspect}")
84
- needed = true
85
- else
86
- copied += 1
87
- site.static_files << DownloadedFile.new(site, link, html)
88
- added = true
89
- if version.empty?
90
- Jekyll.logger.info("Re-translation not required, since version is empty: #{link.inspect}")
91
- elsif html.include?(marker)
92
- Jekyll.logger.info("No need to translate, the page exists at \
93
- #{link.inspect} (#{html.split.count} words)")
94
- else
95
- Jekyll.logger.info("Re-translation required for #{link.inspect}")
96
- needed = true
48
+ marker = "Translated by ChatGPT #{model}#{"/#{version}" unless version.empty?}"
49
+ elapsed(Jekyll.logger) do
50
+ site.posts.docs.shuffle.each_with_index do |doc, pos|
51
+ plain = GptTranslate::Plain.new(doc.content).to_s
52
+ layout = doc['layout']
53
+ config['targets'].each do |target|
54
+ link = GptTranslate::Permalink.new(doc, target['permalink']).to_path
55
+ lang = target['language']
56
+ raise 'Language must be defined for each target' if target.nil?
57
+ only = target['only']
58
+ if !only.nil? && layout != only
59
+ Jekyll.logger.debug("Not translating #{link.inspect}, b/c 'only' set to '#{only}'")
60
+ next
97
61
  end
98
- end
99
- if translated >= threshold
100
- Jekyll.logger.info("Page ##{pos} is ignored, we are over the threshold of #{threshold}: #{link}")
101
- elsif needed
102
- gpt = GptTranslate::ChatGPT.new(
103
- key,
104
- model,
105
- target['source'] || config['source'] || 'en',
106
- lang
107
- )
108
- foreign = gpt.translate(
109
- plain,
110
- min: min_chars,
111
- window_length: (config['window_length'] || '2048').to_i
112
- )
62
+ path = File.join(home, lang, doc.basename.gsub(/\.md$/, "-#{lang}.md"))
63
+ FileUtils.mkdir_p(File.dirname(path))
113
64
  File.write(
114
65
  path,
115
66
  [
116
- '',
117
- foreign,
118
- '',
119
- "#{marker} on #{Time.now.strftime('%Y-%m-%d at %H:%M')}\n{: .jekyll-chatgpt-translate}"
120
- ].join("\n"),
121
- mode: 'a+'
67
+ '---',
68
+ "layout: #{target['layout'] || layout}",
69
+ "title: #{doc['title'].to_json}",
70
+ "description: #{doc['description'].to_json}",
71
+ "permalink: #{link.to_json}",
72
+ 'chatgpt-translate:',
73
+ " original-url: #{doc.url.to_json}",
74
+ " language: #{lang.to_json}",
75
+ " model: #{model.to_json}",
76
+ '---'
77
+ ].join("\n")
122
78
  )
123
- site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
124
- site.static_files.delete_if { |f| f.is_a?(DownloadedFile) && f.link == link }
125
- added = true
126
- translated += 1
127
- Jekyll.logger.info("Translated via ChatGPT \
128
- in #{(Time.now - pstart).round(2)}s: #{path} (#{File.size(path)} bytes)")
79
+ html = config['no_download'].nil? ? GptTranslate::Ping.new(site, link).download : nil
80
+ needed = false
81
+ added = false
82
+ if html.nil?
83
+ Jekyll.logger.info("The page is absent, need to translate #{link.inspect}")
84
+ needed = true
85
+ else
86
+ copied += 1
87
+ site.static_files << DownloadedFile.new(site, link, html)
88
+ added = true
89
+ if version.empty?
90
+ Jekyll.logger.info("Re-translation not required, since version is empty: #{link.inspect}")
91
+ elsif html.include?(marker)
92
+ Jekyll.logger.info("The page exists at #{link.inspect} (#{html.split.count} words)")
93
+ else
94
+ Jekyll.logger.info("Re-translation required for #{link.inspect}")
95
+ needed = true
96
+ end
97
+ end
98
+ if translated >= threshold
99
+ Jekyll.logger.info("Page ##{pos} is ignored, we are over the threshold of #{threshold}: #{link}")
100
+ elsif needed
101
+ elapsed(Jekyll.logger) do
102
+ gpt = GptTranslate::ChatGPT.new(
103
+ key,
104
+ model,
105
+ target['source'] || config['source'] || 'en',
106
+ lang
107
+ )
108
+ foreign = gpt.translate(
109
+ plain,
110
+ min: min_chars,
111
+ window_length: (config['window_length'] || '2048').to_i
112
+ )
113
+ File.write(
114
+ path,
115
+ [
116
+ '',
117
+ foreign,
118
+ '',
119
+ "#{marker} on #{Time.now.strftime('%Y-%m-%d at %H:%M')}\n{: .jekyll-chatgpt-translate}"
120
+ ].join("\n"),
121
+ mode: 'a+'
122
+ )
123
+ site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
124
+ site.static_files.delete_if { |f| f.is_a?(DownloadedFile) && f.link == link }
125
+ added = true
126
+ translated += 1
127
+ throw :"Translated via ChatGPT #{path} (#{File.size(path)} bytes)"
128
+ end
129
+ end
130
+ next unless added
131
+ doc.data['chatgpt-translate'] ||= {}
132
+ doc.data['chatgpt-translate']['model'] ||= model
133
+ doc.data['chatgpt-translate']['urls'] ||= {}
134
+ doc.data['chatgpt-translate']['urls'][lang] = link
129
135
  end
130
- next unless added
131
- doc.data['chatgpt-translate'] ||= {}
132
- doc.data['chatgpt-translate']['model'] ||= model
133
- doc.data['chatgpt-translate']['urls'] ||= {}
134
- doc.data['chatgpt-translate']['urls'][lang] = link
135
136
  end
137
+ throw :"#{translated} page(s) translated and #{copied} page(s) copied"
136
138
  end
137
- Jekyll.logger.info("jekyll-chatgpt-translate #{GptTranslate::VERSION}: \
138
- #{translated} pages translated and #{copied} pages copied in #{(Time.now - start).round(2)}s")
139
139
  end
140
140
 
141
141
  # The file we just downloaded.
@@ -148,12 +148,14 @@ in #{(Time.now - pstart).round(2)}s: #{path} (#{File.size(path)} bytes)")
148
148
  @link = link
149
149
  end
150
150
 
151
+ # rubocop:disable Naming/PredicateMethod
151
152
  def write(_dest)
152
153
  FileUtils.mkdir_p(File.dirname(path))
153
154
  File.write(path, @html)
154
155
  Jekyll.logger.info("Saved #{@html.split.count} words to #{path.inspect}")
155
156
  true
156
157
  end
158
+ # rubocop:enable Naming/PredicateMethod
157
159
  end
158
160
 
159
161
  private
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  # The module we are in.
@@ -8,7 +8,7 @@ module GptTranslate; end
8
8
 
9
9
  # Markdown broken down ito pars.
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
11
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
12
12
  # License:: MIT
13
13
  class GptTranslate::Pars
14
14
  # Ctor.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'cgi'
@@ -10,7 +10,7 @@ module GptTranslate; end
10
10
 
11
11
  # Permalink.
12
12
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
13
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
14
14
  # License:: MIT
15
15
  class GptTranslate::Permalink
16
16
  def initialize(doc, template)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'iri'
@@ -17,7 +17,7 @@ module GptTranslate; end
17
17
 
18
18
  # Ping one page of a site.
19
19
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
20
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
20
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
21
21
  # License:: MIT
22
22
  class GptTranslate::Ping
23
23
  # Ctor.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'redcarpet'
@@ -10,7 +10,7 @@ module GptTranslate; end
10
10
 
11
11
  # Markdown to plain text.
12
12
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
13
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
14
14
  # License:: MIT
15
15
  class GptTranslate::Plain
16
16
  # Ctor.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'iso-639'
@@ -11,7 +11,7 @@ module GptTranslate; end
11
11
 
12
12
  # Prompt for ChatGPT.
13
13
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
14
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
14
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
15
15
  # License:: MIT
16
16
  class GptTranslate::Prompt
17
17
  # Ctor.
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  module GptTranslate
7
- VERSION = '0.1.0'
7
+ VERSION = '0.3.0'
8
8
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'jekyll-chatgpt-translate/generator'
data/test/test__helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  $stdout.sync = true
@@ -28,6 +28,7 @@ end
28
28
 
29
29
  require 'minitest/reporters'
30
30
  Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
31
+ Minitest.load :minitest_reporter
31
32
 
32
33
  require 'minitest/autorun'
33
34
 
@@ -39,7 +40,7 @@ module GptTranslate; end
39
40
 
40
41
  # Fake.
41
42
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
42
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
43
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
43
44
  # License:: MIT
44
45
  class GptTranslate::FakeSite
45
46
  attr_reader :config, :pages, :static_files
@@ -87,7 +88,7 @@ end
87
88
 
88
89
  # Fake.
89
90
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
90
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
91
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
91
92
  # License:: MIT
92
93
  class GptTranslate::FakeDocument
93
94
  attr_reader :data
@@ -124,7 +125,7 @@ end
124
125
 
125
126
  # Fake.
126
127
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
127
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
128
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
128
129
  # License:: MIT
129
130
  class GptTranslate::FakePosts
130
131
  attr_reader :config
data/test/test_chatgpt.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'webmock/minitest'
@@ -9,7 +9,7 @@ require_relative '../lib/jekyll-chatgpt-translate/chatgpt'
9
9
 
10
10
  # ChatGPT test.
11
11
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
12
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
12
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
13
13
  # License:: MIT
14
14
  class GptTranslate::ChatGPTTest < Minitest::Test
15
15
  def test_short_text
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'tmpdir'
@@ -10,7 +10,7 @@ require_relative '../lib/jekyll-chatgpt-translate/generator'
10
10
 
11
11
  # Generator test.
12
12
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
13
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
14
14
  # License:: MIT
15
15
  class GptTranslate::GeneratorTest < Minitest::Test
16
16
  def test_simple_scenario
data/test/test_pars.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require_relative 'test__helper'
@@ -8,7 +8,7 @@ require_relative '../lib/jekyll-chatgpt-translate/pars'
8
8
 
9
9
  # Test for Pars.
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
11
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
12
12
  # License:: MIT
13
13
  class GptTranslate::ParsTest < Minitest::Test
14
14
  def test_simple_cases
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require_relative 'test__helper'
@@ -8,7 +8,7 @@ require_relative '../lib/jekyll-chatgpt-translate/permalink'
8
8
 
9
9
  # Permalink test.
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
11
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
12
12
  # License:: MIT
13
13
  class GptTranslate::PermalinkTest < Minitest::Test
14
14
  def test_simple_link
data/test/test_ping.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require 'webmock/minitest'
@@ -11,7 +11,7 @@ require_relative '../lib/jekyll-chatgpt-translate/ping'
11
11
 
12
12
  # Ping test.
13
13
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
14
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
14
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
15
15
  # License:: MIT
16
16
  class GptTranslate::PingTest < Minitest::Test
17
17
  def test_when_exists
data/test/test_plain.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require_relative 'test__helper'
@@ -8,7 +8,7 @@ require_relative '../lib/jekyll-chatgpt-translate/plain'
8
8
 
9
9
  # Plain test.
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
11
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
12
12
  # License:: MIT
13
13
  class GptTranslate::PlainTest < Minitest::Test
14
14
  def test_simple_map
data/test/test_prompt.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # SPDX-FileCopyrightText: Copyright (c) 2023-2025 Yegor Bugayenko
3
+ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
6
  require_relative 'test__helper'
@@ -8,7 +8,7 @@ require_relative '../lib/jekyll-chatgpt-translate/prompt'
8
8
 
9
9
  # Prompt test.
10
10
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2023-2025 Yegor Bugayenko
11
+ # Copyright:: Copyright (c) 2023-2026 Yegor Bugayenko
12
12
  # License:: MIT
13
13
  class GptTranslate::PromptTest < Minitest::Test
14
14
  def head(source, target)
metadata CHANGED
@@ -1,127 +1,161 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-chatgpt-translate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-20 00:00:00.000000000 Z
11
+ date: 2026-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: elapsed
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: humanize
15
43
  requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
- - - ">="
45
+ - - "~>"
18
46
  - !ruby/object:Gem::Version
19
- version: '2'
47
+ version: '3.1'
20
48
  type: :runtime
21
49
  prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
- - - ">="
52
+ - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: '2'
54
+ version: '3.1'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: iri
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
- - - ">="
59
+ - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: '0'
61
+ version: '0.11'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
- - - ">="
66
+ - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '0'
68
+ version: '0.11'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: iso-639
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
- - - ">="
73
+ - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '0'
75
+ version: '0.3'
48
76
  type: :runtime
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
- - - ">="
80
+ - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '0'
82
+ version: '0.3'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: jekyll
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - ">="
60
88
  - !ruby/object:Gem::Version
61
- version: '3'
89
+ version: '3.0'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '5.0'
62
93
  type: :runtime
63
94
  prerelease: false
64
95
  version_requirements: !ruby/object:Gem::Requirement
65
96
  requirements:
66
97
  - - ">="
67
98
  - !ruby/object:Gem::Version
68
- version: '3'
99
+ version: '3.0'
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '5.0'
69
103
  - !ruby/object:Gem::Dependency
70
104
  name: json
71
105
  requirement: !ruby/object:Gem::Requirement
72
106
  requirements:
73
- - - ">="
107
+ - - "~>"
74
108
  - !ruby/object:Gem::Version
75
- version: '2'
109
+ version: '2.18'
76
110
  type: :runtime
77
111
  prerelease: false
78
112
  version_requirements: !ruby/object:Gem::Requirement
79
113
  requirements:
80
- - - ">="
114
+ - - "~>"
81
115
  - !ruby/object:Gem::Version
82
- version: '2'
116
+ version: '2.18'
83
117
  - !ruby/object:Gem::Dependency
84
118
  name: redcarpet
85
119
  requirement: !ruby/object:Gem::Requirement
86
120
  requirements:
87
- - - ">="
121
+ - - "~>"
88
122
  - !ruby/object:Gem::Version
89
- version: '3'
123
+ version: '3.6'
90
124
  type: :runtime
91
125
  prerelease: false
92
126
  version_requirements: !ruby/object:Gem::Requirement
93
127
  requirements:
94
- - - ">="
128
+ - - "~>"
95
129
  - !ruby/object:Gem::Version
96
- version: '3'
130
+ version: '3.6'
97
131
  - !ruby/object:Gem::Dependency
98
132
  name: ruby-openai
99
133
  requirement: !ruby/object:Gem::Requirement
100
134
  requirements:
101
- - - ">="
135
+ - - "~>"
102
136
  - !ruby/object:Gem::Version
103
- version: '5'
137
+ version: '8.3'
104
138
  type: :runtime
105
139
  prerelease: false
106
140
  version_requirements: !ruby/object:Gem::Requirement
107
141
  requirements:
108
- - - ">="
142
+ - - "~>"
109
143
  - !ruby/object:Gem::Version
110
- version: '5'
144
+ version: '8.3'
111
145
  - !ruby/object:Gem::Dependency
112
146
  name: tiktoken_ruby
113
147
  requirement: !ruby/object:Gem::Requirement
114
148
  requirements:
115
- - - ">="
149
+ - - "~>"
116
150
  - !ruby/object:Gem::Version
117
- version: 0.0.6
151
+ version: '0.0'
118
152
  type: :runtime
119
153
  prerelease: false
120
154
  version_requirements: !ruby/object:Gem::Requirement
121
155
  requirements:
122
- - - ">="
156
+ - - "~>"
123
157
  - !ruby/object:Gem::Version
124
- version: 0.0.6
158
+ version: '0.0'
125
159
  description: Add this plugin to your Jekyll site and all posts will be automatically
126
160
  translated to the languages of your choice through ChatGPT
127
161
  email: yegor256@gmail.com
@@ -138,6 +172,7 @@ files:
138
172
  - ".github/workflows/pdd.yml"
139
173
  - ".github/workflows/rake.yml"
140
174
  - ".github/workflows/reuse.yml"
175
+ - ".github/workflows/typos.yml"
141
176
  - ".github/workflows/xcop.yml"
142
177
  - ".github/workflows/yamllint.yml"
143
178
  - ".gitignore"