jekyll-chatgpt-translate 0.0.17 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f48ffb6334ada2deb878ede0622065326b23ed765946070aff20c9ce5888715d
4
- data.tar.gz: df98890a24fb215b1ba1efc2794a6e4bf1cb0b9949efb94648b267c343052562
3
+ metadata.gz: d7cc9cfc295b4eeb123b972094f4fa1c648a88f3df384a78b489b9b0bafbd0c1
4
+ data.tar.gz: 06cd12eabf0fbf6e77a64f52384609bcdc33edb8c6324aa4555de4f7fb275c99
5
5
  SHA512:
6
- metadata.gz: 158df2fdeb7459cace117be39d3e94f9830c852034719ae049777b863bbbc61dc869c362534cc651f53e21af1fa37203865ec7b295254768274921a406cf858f
7
- data.tar.gz: f8e34b0bd3432d598b9e7b2f5582ede75231f0c8c9e3dd71db348a5711ddf56106f7685adbf28c02a84f8ef84c7589f4a4909c650afb08d9a110751a317b8bbd
6
+ metadata.gz: d0b55a94c132688afe28b9edbc4115570e6fd449b001bc606bf33c9d30712f2c1639fa8e0334652c0e8aa36b79e356f40845162e810e5b980f8b2dbcd7641746
7
+ data.tar.gz: e058ea19c7ffb630ab48bac0b433c8fde5f5b76d6087833cb2f7a70c04eaaca32f7273cacd881caf7b3b9355b5cb6a15f539060ff14bd3184baf5a6214b79914
data/.rubocop.yml CHANGED
@@ -33,3 +33,5 @@ Layout/ElseAlignment:
33
33
  Enabled: false
34
34
  Layout/EndAlignment:
35
35
  Enabled: false
36
+ Metrics/ClassLength:
37
+ Max: 200
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Gem Version](https://badge.fury.io/rb/glogin.svg)](http://badge.fury.io/rb/glogin)
1
2
  <img src="logo.png" style="width:256px;"/>
2
3
 
3
4
  [![rake](https://github.com/yegor256/jekyll-chatgpt-translate/actions/workflows/rake.yml/badge.svg)](https://github.com/yegor256/jekyll-chatgpt-translate/actions/workflows/rake.yml)
@@ -50,6 +51,8 @@ to get the URL of the page that was translated.
50
51
 
51
52
  You can also use `{{ page.chatgpt-model }}`
52
53
  inside both the original page and the translated one, to refer to the model of ChatGPT.
54
+ The presence of this attribute in the `{{ page }}` means that the
55
+ page was translated or the translated HTML was downloaded and placed into the `_site` directory.
53
56
 
54
57
  ## Options
55
58
 
@@ -62,6 +65,16 @@ Full list of options available to specify in `_config.yml`:
62
65
 
63
66
  * `source` (optional) — is the ISO-839-1 code of the source language.
64
67
 
68
+ * `no_download` (optional) — if this attribute is present, the plugin won't try
69
+ to find HTML versions of translated pages in the Internet and won't try to
70
+ download them and place into the `_site` directory. Thus, your entire site
71
+ will have to be re-translated on every build (might be very ineffective if the site is big!)
72
+
73
+ * `min_chars` (optional) — minimum number of chars that must be present in
74
+ a paragraph in order for it to be feasible to go to ChatGPT. The robot
75
+ doesn't translate short paragraphs pretty enough. It's better to keep this
76
+ number big enough, to avoid silly translations. The default is 128.
77
+
65
78
  * `layout` (optional) — is name of the file in `_layouts` directory, without the extension.
66
79
  This layout will be specified for the pages generated by this plugin.
67
80
 
@@ -40,7 +40,7 @@ Given(/^I have a "([^"]*)" file with content:$/) do |file, text|
40
40
  File.write(file, text.gsub('\\xFF', 0xFF.chr))
41
41
  end
42
42
 
43
- When(/^I build Jekyll site$/) do
43
+ When('I build Jekyll site') do
44
44
  @stdout = `jekyll build`
45
45
  @exitstatus = $CHILD_STATUS.exitstatus
46
46
  end
@@ -59,20 +59,16 @@ Then('File {string} contains {string}') do |string, string2|
59
59
  raise "The file \"#{string}\" doesn't contain \"#{string2}\":\n#{content}" unless content.include?(string2)
60
60
  end
61
61
 
62
- Then(/^Stdout is empty$/) do
63
- raise "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
64
- end
65
-
66
- Then(/^Exit code is zero$/) do
62
+ Then('Exit code is zero') do
67
63
  raise "Non-zero exit #{@exitstatus}:\n#{@stdout}" unless @exitstatus.zero?
68
64
  end
69
65
 
70
- Then(/^Exit code is not zero$/) do
66
+ Then('Exit code is not zero') do
71
67
  raise 'Zero exit code' if @exitstatus.zero?
72
68
  end
73
69
 
74
- When(/^I run bash with "([^"]*)"$/) do |text|
75
- @stdout = `#{text}`
70
+ When('I run bash with {string}') do |string|
71
+ @stdout = `#{string}`
76
72
  @exitstatus = $CHILD_STATUS.exitstatus
77
73
  end
78
74
 
@@ -81,7 +77,7 @@ When(/^I run bash with:$/) do |text|
81
77
  @exitstatus = $CHILD_STATUS.exitstatus
82
78
  end
83
79
 
84
- When(/^I copy this gem into temp dir$/) do
80
+ When('I copy this gem into temp dir') do
85
81
  FileUtils.copy_entry(@cwd, File.join(@dir, 'jekyll-chatgpt-translate'))
86
82
  end
87
83
 
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
29
29
  s.required_ruby_version = '>= 2.6'
30
30
  s.name = 'jekyll-chatgpt-translate'
31
- s.version = '0.0.17'
31
+ s.version = '0.0.19'
32
32
  s.license = 'MIT'
33
33
  s.summary = 'Translate Jekyll Pages Through ChatGPT'
34
34
  s.description = [
@@ -47,12 +47,12 @@ class GptTranslate::ChatGPT
47
47
  @target = target
48
48
  end
49
49
 
50
- def translate(text)
50
+ def translate(text, min: 32)
51
51
  text.split("\n\n").compact.map do |par|
52
- if par.length <= 32
52
+ if par.length < min
53
53
  Jekyll.logger.debug("Not translating this, b/c too short: \"#{par}\"")
54
54
  par
55
- elsif par !~ /^[[:alpha:]]/
55
+ elsif par !~ /^[[[:alpha:]]'"]/
56
56
  Jekyll.logger.debug("Not translating this, b/c it's not a plain text: \"#{par}\"")
57
57
  par
58
58
  elsif @key.empty?
@@ -53,6 +53,7 @@ class GptTranslate::Generator < Jekyll::Generator
53
53
  layout = config['layout'] || 'translated'
54
54
  version = config['version'] || GptTranslate::VERSION
55
55
  threshold = config['threshold'] || 1024
56
+ min_chars = config['min_chars'] || 128
56
57
  start = Time.now
57
58
  translated = 0
58
59
  copied = 0
@@ -68,41 +69,42 @@ class GptTranslate::Generator < Jekyll::Generator
68
69
  FileUtils.mkdir_p(File.dirname(path))
69
70
  File.write(path, '') # in order to surpress warnings in Page ctor
70
71
  dest = Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path)).destination(site.dest)
71
- doc.data["translated-#{lang}-url"] = link
72
- doc.data['chatgpt-model'] = model
73
- if GptTranslate::Ping.new(site, link).found?(dest, version)
72
+ if config['no_download'].nil? && GptTranslate::Ping.new(site, link).found?(dest, version)
74
73
  copied += 1
74
+ elsif translated >= threshold
75
75
  next
76
+ else
77
+ gpt = GptTranslate::ChatGPT.new(
78
+ key,
79
+ model,
80
+ config['source'] || 'en',
81
+ lang
82
+ )
83
+ foreign = gpt.translate(plain, min: min_chars)
84
+ File.write(
85
+ path,
86
+ [
87
+ '---',
88
+ "layout: #{target['layout'] || layout}",
89
+ "title: #{doc['title'].to_json}",
90
+ "description: #{doc['description'].to_json}",
91
+ "permalink: #{link.to_json}",
92
+ "translated-original-url: #{doc.url.to_json}",
93
+ "translated-language: #{lang.to_json}",
94
+ "chatgpt-model: #{model.to_json}",
95
+ '---',
96
+ '',
97
+ foreign,
98
+ '',
99
+ "#{marker} on #{Time.now.strftime('%Y-%m-%d at %H:%M')}\n{: .jekyll-chatgpt-translate}"
100
+ ].join("\n")
101
+ )
102
+ site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
103
+ translated += 1
104
+ Jekyll.logger.info("Translated via ChatGPT: #{path} (#{File.size(path)} bytes)")
76
105
  end
77
- next if translated >= threshold
78
- gpt = GptTranslate::ChatGPT.new(
79
- key,
80
- model,
81
- config['source'] || 'en',
82
- lang
83
- )
84
- foreign = gpt.translate(plain)
85
- File.write(
86
- path,
87
- [
88
- '---',
89
- "layout: #{target['layout'] || layout}",
90
- "title: #{doc['title'].to_json}",
91
- "description: #{doc['description'].to_json}",
92
- "permalink: #{link.to_json}",
93
- "translated-original-url: #{doc.url.to_json}",
94
- "translated-language: #{lang.to_json}",
95
- "chatgpt-model: #{model.to_json}",
96
- '---',
97
- '',
98
- foreign,
99
- '',
100
- "#{marker} on #{Time.now.strftime('%d/%m/%Y %H:%M')}\n{: .jekyll-chatgpt-translate}"
101
- ].join("\n")
102
- )
103
- site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
104
- translated += 1
105
- Jekyll.logger.info("Translated via ChatGPT: #{path} (#{File.size(path)} bytes)")
106
+ doc.data["translated-#{lang}-url"] = link
107
+ doc.data['chatgpt-model'] = model
106
108
  end
107
109
  end
108
110
  Jekyll.logger.info("#{translated} pages translated and #{copied} pages copied in #{(Time.now - start).round(2)}s")
@@ -39,7 +39,7 @@ class GptTranslate::Plain
39
39
 
40
40
  def to_s
41
41
  # To turn compact lists into proper lists
42
- @markdown.gsub(/([^\n])\n(\s*\*)/, "\\1\n\n\\2").split(/\n{2,}/).compact.map do |par|
42
+ @markdown.gsub(/([^\n])\n(\s*\* )/, "\\1\n\n\\2").split(/\n{2,}/).compact.map do |par|
43
43
  par.strip!
44
44
  # Liquid tags are removed, but this implementation is primitive
45
45
  # Seehttps://stackoverflow.com/questions/
@@ -55,6 +55,7 @@ class GptTranslate::Plain
55
55
  end
56
56
 
57
57
  # Markdown to pain text.
58
+ # Motivated by https://github.com/vmg/redcarpet/blob/master/lib/redcarpet/render_strip.rb
58
59
  class Strip < Redcarpet::Render::Base
59
60
  %i[
60
61
  block_code block_quote
@@ -71,6 +72,10 @@ class GptTranslate::Plain
71
72
  end
72
73
  end
73
74
 
75
+ def header(text, level)
76
+ "#{'#' * level} #{text}"
77
+ end
78
+
74
79
  def codespan(content)
75
80
  if content.start_with?("\n")
76
81
  "```#{content}```"
@@ -81,6 +86,10 @@ class GptTranslate::Plain
81
86
  end
82
87
  end
83
88
 
89
+ def image(link, title, alt)
90
+ "![#{alt}](#{link} \"#{title}\")"
91
+ end
92
+
84
93
  def raw_html(content)
85
94
  content
86
95
  end
@@ -23,5 +23,5 @@
23
23
  # SOFTWARE.
24
24
 
25
25
  module GptTranslate
26
- VERSION = '0.0.17'
26
+ VERSION = '0.0.19'
27
27
  end
@@ -75,28 +75,23 @@ class GptTranslate::GeneratorTest < Minitest::Test
75
75
  end
76
76
 
77
77
  class FakeDocument
78
+ attr_reader :data
79
+
78
80
  def initialize(path)
79
81
  @path = path
82
+ @data = { 'date' => Time.now, 'title' => 'Hello!' }
80
83
  end
81
84
 
82
85
  def content
83
86
  'Hello, world!'
84
87
  end
85
88
 
86
- def data
87
- {}
89
+ def []=(key, value)
90
+ @data[key] = value
88
91
  end
89
92
 
90
- def []=(key, value); end
91
-
92
93
  def [](key)
93
- if key == 'date'
94
- Time.now
95
- elsif key == 'title'
96
- 'Hello!'
97
- else
98
- ''
99
- end
94
+ @data[key] || ''
100
95
  end
101
96
 
102
97
  def relative_path
data/test/test_plain.rb CHANGED
@@ -31,8 +31,10 @@ require_relative '../lib/jekyll-chatgpt-translate/plain'
31
31
  # License:: MIT
32
32
  class GptTranslate::PlainTest < Minitest::Test
33
33
  def test_simple_map
34
- assert_equal('Hello, world!', GptTranslate::Plain.new('Hello, **world**!').to_s)
34
+ assert_equal('Hello, world!', GptTranslate::Plain.new("Hello,\n**world**!").to_s)
35
+ assert_equal('Hello, world!', GptTranslate::Plain.new("Hello,\n[world](/x.html)!").to_s)
35
36
  assert_equal('Hello, Jeff!', GptTranslate::Plain.new('Hello, _Jeff_!').to_s)
37
+ # assert_equal('Hello, Walter!', GptTranslate::Plain.new('Hello, ~Walter~!').to_s)
36
38
  assert_equal("Hi\n\nBye", GptTranslate::Plain.new(" Hi\n\nBye\n\n\n").to_s)
37
39
  assert_equal('Hi, dude!', GptTranslate::Plain.new(" Hi,\ndude!\n").to_s)
38
40
  end
@@ -83,6 +85,16 @@ class GptTranslate::PlainTest < Minitest::Test
83
85
  )
84
86
  end
85
87
 
88
+ def test_titles
89
+ assert_equal('# Hello', GptTranslate::Plain.new('# Hello').to_s)
90
+ assert_equal('## Hello', GptTranslate::Plain.new('## Hello').to_s)
91
+ assert_equal('### Hello', GptTranslate::Plain.new('### Hello').to_s)
92
+ end
93
+
94
+ def test_image
95
+ assert_equal('![alt](a.png "hello")', GptTranslate::Plain.new('![alt](a.png "hello")').to_s)
96
+ end
97
+
86
98
  def test_html
87
99
  assert_equal(
88
100
  'This is picture: <img src="a"/>!',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-chatgpt-translate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.17
4
+ version: 0.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko