jekyll-chatgpt-translate 0.0.19 → 0.0.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/README.md +0 -1
- data/features/cli.feature +1 -1
- data/jekyll-chatgpt-translate.gemspec +1 -1
- data/lib/jekyll-chatgpt-translate/chatgpt.rb +20 -9
- data/lib/jekyll-chatgpt-translate/generator.rb +22 -16
- data/lib/jekyll-chatgpt-translate/ping.rb +8 -8
- data/lib/jekyll-chatgpt-translate/plain.rb +38 -26
- data/lib/jekyll-chatgpt-translate/prompt.rb +4 -4
- data/lib/jekyll-chatgpt-translate/version.rb +1 -1
- data/test/test__helper.rb +3 -0
- data/test/test_chatgpt.rb +30 -4
- data/test/test_generator.rb +1 -0
- data/test/test_permalink.rb +1 -0
- data/test/test_ping.rb +1 -0
- data/test/test_plain.rb +79 -17
- data/test/test_prompt.rb +6 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bae88d4bb6c95da76a68c64321f5d308611a19981158f69cd2aa8763d0f4f8f0
|
4
|
+
data.tar.gz: b820a3d53adafd3ea91f365e95851bf848e05890281d1cc7d85bc6a19692af3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 554c9a981763d2957c83b396098fec3b75c23fd98f73a180b33528db97a43406cc2b6595893b1e848a59829e614ec4eb4c70f50d63301d6b93047caf12a81e19
|
7
|
+
data.tar.gz: 695cbae5292d6e81ad69d81657e5ded96f69f2c970bfa2d0ad4b8da23c8c8f412cd77e3944ec09e064417114b0c2ae3518b61b80c3af3a2d4d376e0d0dd8c6b0
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
[![Gem Version](https://badge.fury.io/rb/glogin.svg)](http://badge.fury.io/rb/glogin)
|
2
1
|
<img src="logo.png" style="width:256px;"/>
|
3
2
|
|
4
3
|
[![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)
|
data/features/cli.feature
CHANGED
@@ -40,6 +40,7 @@ Feature: Simple site building
|
|
40
40
|
Hello, world!
|
41
41
|
"""
|
42
42
|
Then I build Jekyll site
|
43
|
+
And Exit code is zero
|
43
44
|
And File "_chatgpt-translated/zh/2023-01-01-hello-zh.md" exists
|
44
45
|
And File "_chatgpt-translated/zh/2023-01-01-hello-zh.md" contains "/2023-01-01-hello-chinese.html"
|
45
46
|
And File "_chatgpt-translated/zh/2023-01-01-hello-zh.md" contains "translated-language: \"zh\""
|
@@ -48,5 +49,4 @@ Feature: Simple site building
|
|
48
49
|
And File "_site/2023-01-01-hello-chinese.html" exists
|
49
50
|
And File "_site/2023-01-01-hello-chinese.html" contains "The original: /2023/01/01/hello.html"
|
50
51
|
And File "_site/2023/hello-french.html" exists
|
51
|
-
And Exit code is zero
|
52
52
|
|
@@ -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.
|
31
|
+
s.version = '0.0.21'
|
32
32
|
s.license = 'MIT'
|
33
33
|
s.summary = 'Translate Jekyll Pages Through ChatGPT'
|
34
34
|
s.description = [
|
@@ -47,13 +47,20 @@ class GptTranslate::ChatGPT
|
|
47
47
|
@target = target
|
48
48
|
end
|
49
49
|
|
50
|
-
def translate(
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
def translate(markdown, min: 32)
|
51
|
+
markdown.split(/\n{2,}/).compact.map do |par|
|
52
|
+
par.strip!
|
53
|
+
if @source == @target
|
54
|
+
Jekyll.logger.debug("No need to translate from #{@source.inspect} to #{@target.inspect}: #{par.inspect}")
|
54
55
|
par
|
55
|
-
elsif par
|
56
|
-
Jekyll.logger.debug("Not translating this, b/c
|
56
|
+
elsif par.length < min
|
57
|
+
Jekyll.logger.debug("Not translating this, b/c too short: #{par.inspect}")
|
58
|
+
par
|
59
|
+
elsif par.start_with?('```') || par.end_with?('```')
|
60
|
+
Jekyll.logger.debug("Not translating this code block: #{par.inspect}")
|
61
|
+
par
|
62
|
+
elsif par =~ /^[^\p{Alnum}\*'"]/
|
63
|
+
Jekyll.logger.debug("Not translating this, b/c it's not a plain text: #{par.inspect}")
|
57
64
|
par
|
58
65
|
elsif @key.empty?
|
59
66
|
par
|
@@ -79,15 +86,19 @@ class GptTranslate::ChatGPT
|
|
79
86
|
}
|
80
87
|
)
|
81
88
|
answer = response.dig('choices', 0, 'message', 'content')
|
82
|
-
Jekyll.logger.debug("ChatGPT prompt:
|
89
|
+
Jekyll.logger.debug("ChatGPT prompt: #{prompt.inspect}, ChatGPT answer: #{answer.inspect}")
|
83
90
|
rescue StandardError => e
|
84
91
|
attempt += 1
|
85
|
-
|
92
|
+
if attempt < 4
|
93
|
+
Jekyll.logger.error("ChatGPT failed to answer to #{prompt.inspect} \
|
94
|
+
(attempt no.#{attempt}): #{e.message.inspect}")
|
95
|
+
retry
|
96
|
+
end
|
86
97
|
raise e
|
87
98
|
end
|
88
99
|
Jekyll.logger.info("Translated #{par.split.count} #{@source.upcase} words \
|
89
100
|
to #{answer.split.count} #{@target.upcase} words \
|
90
|
-
through #{@model} in #{(Time.now - start).round(2)}s")
|
101
|
+
through #{@model} in #{(Time.now - start).round(2)}s: #{"#{par[0..24]}...".inspect}")
|
91
102
|
answer
|
92
103
|
end
|
93
104
|
end
|
@@ -58,7 +58,7 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
58
58
|
translated = 0
|
59
59
|
copied = 0
|
60
60
|
model = config['model'] || 'gpt-3.5-turbo'
|
61
|
-
marker = "Translated by ChatGPT #{model}/#{version}"
|
61
|
+
marker = "Translated by ChatGPT #{model}#{version.empty? ? '' : "/#{version}"}"
|
62
62
|
site.posts.docs.shuffle.each do |doc|
|
63
63
|
plain = GptTranslate::Plain.new(doc.content).to_s
|
64
64
|
config['targets'].each do |target|
|
@@ -67,9 +67,23 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
67
67
|
raise 'Language must be defined for each target' if target.nil?
|
68
68
|
path = File.join(home, lang, doc.basename.gsub(/\.md$/, "-#{lang}.md"))
|
69
69
|
FileUtils.mkdir_p(File.dirname(path))
|
70
|
-
File.write(
|
71
|
-
|
72
|
-
|
70
|
+
File.write(
|
71
|
+
path,
|
72
|
+
[
|
73
|
+
'---',
|
74
|
+
"layout: #{target['layout'] || layout}",
|
75
|
+
"title: #{doc['title'].to_json}",
|
76
|
+
"description: #{doc['description'].to_json}",
|
77
|
+
"permalink: #{link.to_json}",
|
78
|
+
"translated-original-url: #{doc.url.to_json}",
|
79
|
+
"translated-language: #{lang.to_json}",
|
80
|
+
"chatgpt-model: #{model.to_json}",
|
81
|
+
'---'
|
82
|
+
].join("\n")
|
83
|
+
)
|
84
|
+
url = Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path)).url
|
85
|
+
ping = GptTranslate::Ping.new(site, link)
|
86
|
+
if config['no_download'].nil? && ping.found?(File.join(site.dest, url), version.empty? ? '' : marker)
|
73
87
|
copied += 1
|
74
88
|
elsif translated >= threshold
|
75
89
|
next
|
@@ -84,20 +98,12 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
84
98
|
File.write(
|
85
99
|
path,
|
86
100
|
[
|
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
101
|
'',
|
97
102
|
foreign,
|
98
103
|
'',
|
99
104
|
"#{marker} on #{Time.now.strftime('%Y-%m-%d at %H:%M')}\n{: .jekyll-chatgpt-translate}"
|
100
|
-
].join("\n")
|
105
|
+
].join("\n"),
|
106
|
+
mode: 'a+'
|
101
107
|
)
|
102
108
|
site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
|
103
109
|
translated += 1
|
@@ -122,10 +128,10 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
122
128
|
k
|
123
129
|
elsif File.exist?(file)
|
124
130
|
k = File.read(file).strip
|
125
|
-
Jekyll.logger.info("The OpenAI API key taken from the file:
|
131
|
+
Jekyll.logger.info("The OpenAI API key taken from the file: #{file.inspect} (#{k.length} chars)")
|
126
132
|
k
|
127
133
|
else
|
128
|
-
Jekyll.logger.info("The file with the OpenAI API key is not found:
|
134
|
+
Jekyll.logger.info("The file with the OpenAI API key is not found: #{file.inspect}")
|
129
135
|
nil
|
130
136
|
end
|
131
137
|
if key.nil? && Jekyll.env == 'development'
|
@@ -50,26 +50,26 @@ class GptTranslate::Ping
|
|
50
50
|
def found?(file, marker)
|
51
51
|
home = @site.config['url']
|
52
52
|
return false if home.nil?
|
53
|
-
uri = Iri.new(home).path(@path)
|
53
|
+
uri = Iri.new(home).path(@path).to_s
|
54
54
|
begin
|
55
|
-
before = Net::HTTP.get_response(URI(uri
|
55
|
+
before = Net::HTTP.get_response(URI(uri))
|
56
56
|
if before.is_a?(Net::HTTPSuccess)
|
57
57
|
html = before.body
|
58
58
|
if html.include?(marker)
|
59
59
|
Jekyll.logger.info("No need to translate, the page exists at \
|
60
|
-
|
60
|
+
#{uri.inspect} (#{html.split.count} words), saved to #{file.inspect}")
|
61
61
|
FileUtils.mkdir_p(File.dirname(file))
|
62
62
|
File.write(file, html)
|
63
63
|
return true
|
64
64
|
end
|
65
|
-
Jekyll.logger.info("Re-translation required for
|
65
|
+
Jekyll.logger.info("Re-translation required for #{uri.inspect}")
|
66
66
|
else
|
67
|
-
Jekyll.logger.info("The page is absent, will translate
|
67
|
+
Jekyll.logger.info("The page is absent, will translate #{uri.inspect} (#{before.code})")
|
68
68
|
end
|
69
|
-
Jekyll.logger.debug("GET
|
69
|
+
Jekyll.logger.debug("GET #{uri.inspect}: #{before.code}")
|
70
70
|
rescue StandardError => e
|
71
|
-
Jekyll.logger.debug("Failed to ping
|
72
|
-
Jekyll.logger.info("The page is absent:
|
71
|
+
Jekyll.logger.debug("Failed to ping #{uri.inspect}: #{e.message}")
|
72
|
+
Jekyll.logger.info("The page is absent (#{e.class.name}): #{uri.inspect}")
|
73
73
|
end
|
74
74
|
false
|
75
75
|
end
|
@@ -37,32 +37,28 @@ class GptTranslate::Plain
|
|
37
37
|
@markdown = markdown
|
38
38
|
end
|
39
39
|
|
40
|
+
# Liquid tags are removed, but this implementation is primitive
|
41
|
+
# Seehttps://stackoverflow.com/questions/
|
40
42
|
def to_s
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
par.gsub!(/<!--.+?-->/m, '')
|
49
|
-
par = Redcarpet::Markdown.new(Strip).render(par)
|
50
|
-
par.gsub!("\t", ' ')
|
51
|
-
par.gsub!(/\n+/, ' ') unless par.start_with?('```')
|
52
|
-
par.gsub!(/ {2,}/, ' ') unless par.start_with?('```')
|
53
|
-
par.strip
|
54
|
-
end.join("\n\n").gsub(/\n{2,}/, "\n\n").strip
|
43
|
+
Redcarpet::Markdown.new(Strip).render(
|
44
|
+
@markdown
|
45
|
+
.gsub(/([^\n])\n(\s*\* )/, "\\1\n\n\\2")
|
46
|
+
.gsub(/<!--.+?-->/m, '')
|
47
|
+
.gsub(/{{[^}]+}}/, '')
|
48
|
+
.gsub(/{%.+?%}/, '')
|
49
|
+
).strip
|
55
50
|
end
|
56
51
|
|
57
52
|
# Markdown to pain text.
|
58
53
|
# Motivated by https://github.com/vmg/redcarpet/blob/master/lib/redcarpet/render_strip.rb
|
59
54
|
class Strip < Redcarpet::Render::Base
|
60
55
|
%i[
|
61
|
-
|
56
|
+
block_quote
|
62
57
|
block_html
|
63
|
-
autolink
|
64
|
-
|
65
|
-
triple_emphasis
|
58
|
+
autolink
|
59
|
+
underline
|
60
|
+
triple_emphasis
|
61
|
+
strikethrough
|
66
62
|
superscript highlight quote
|
67
63
|
footnotes footnote_def footnote_ref
|
68
64
|
entity normal_text
|
@@ -72,8 +68,20 @@ class GptTranslate::Plain
|
|
72
68
|
end
|
73
69
|
end
|
74
70
|
|
71
|
+
def double_emphasis(txt)
|
72
|
+
"**#{txt}**"
|
73
|
+
end
|
74
|
+
|
75
|
+
def block_code(code, _lang)
|
76
|
+
code
|
77
|
+
end
|
78
|
+
|
79
|
+
def emphasis(txt)
|
80
|
+
"*#{txt}*"
|
81
|
+
end
|
82
|
+
|
75
83
|
def header(text, level)
|
76
|
-
"#{'#' * level} #{text}"
|
84
|
+
"#{'#' * level} #{text}\n\n"
|
77
85
|
end
|
78
86
|
|
79
87
|
def codespan(content)
|
@@ -82,7 +90,7 @@ class GptTranslate::Plain
|
|
82
90
|
elsif content.end_with?("\n")
|
83
91
|
"```\n#{content.split("\n", 2)[1]}```"
|
84
92
|
else
|
85
|
-
content
|
93
|
+
"`#{content}`"
|
86
94
|
end
|
87
95
|
end
|
88
96
|
|
@@ -90,8 +98,8 @@ class GptTranslate::Plain
|
|
90
98
|
"![#{alt}](#{link} \"#{title}\")"
|
91
99
|
end
|
92
100
|
|
93
|
-
def raw_html(
|
94
|
-
|
101
|
+
def raw_html(html)
|
102
|
+
html
|
95
103
|
end
|
96
104
|
|
97
105
|
def list(content, _type)
|
@@ -99,15 +107,19 @@ class GptTranslate::Plain
|
|
99
107
|
end
|
100
108
|
|
101
109
|
def list_item(content, _type)
|
102
|
-
content
|
110
|
+
"#{content.strip}\n\n"
|
103
111
|
end
|
104
112
|
|
105
113
|
def paragraph(text)
|
106
|
-
text
|
114
|
+
unless text.start_with?('```')
|
115
|
+
text.gsub!(/\n+/, ' ')
|
116
|
+
text.gsub!(/\s{2,}/, ' ')
|
117
|
+
end
|
118
|
+
"#{text}\n\n"
|
107
119
|
end
|
108
120
|
|
109
|
-
def link(
|
110
|
-
content
|
121
|
+
def link(link, _title, content)
|
122
|
+
"[#{content}](#{link})"
|
111
123
|
end
|
112
124
|
end
|
113
125
|
end
|
@@ -44,15 +44,15 @@ class GptTranslate::Prompt
|
|
44
44
|
|
45
45
|
def to_s
|
46
46
|
from = ISO_639.find_by_code(@source)
|
47
|
-
raise "Unknown source language ISO-639 code:
|
47
|
+
raise "Unknown source language ISO-639 code: #{@source.inspect}" if from.nil?
|
48
48
|
to = ISO_639.find_by_code(@target)
|
49
|
-
raise "Unknown source language ISO-639 code:
|
49
|
+
raise "Unknown source language ISO-639 code: #{@target.inspect}" if to.nil?
|
50
50
|
head = [
|
51
|
-
'Please, translate the following paragraph from ',
|
51
|
+
'Please, translate the following Markdown paragraph from ',
|
52
52
|
from[3],
|
53
53
|
' to ',
|
54
54
|
to[3],
|
55
|
-
', don\'t
|
55
|
+
', don\'t translate technical terms and proper nouns'
|
56
56
|
].join
|
57
57
|
"#{head}:\n\n#{@par}"
|
58
58
|
end
|
data/test/test__helper.rb
CHANGED
data/test/test_chatgpt.rb
CHANGED
@@ -24,6 +24,7 @@
|
|
24
24
|
|
25
25
|
require 'minitest/autorun'
|
26
26
|
require 'webmock/minitest'
|
27
|
+
require_relative 'test__helper'
|
27
28
|
require_relative '../lib/jekyll-chatgpt-translate/chatgpt'
|
28
29
|
|
29
30
|
# ChatGPT test.
|
@@ -32,20 +33,45 @@ require_relative '../lib/jekyll-chatgpt-translate/chatgpt'
|
|
32
33
|
# License:: MIT
|
33
34
|
class GptTranslate::ChatGPTTest < Minitest::Test
|
34
35
|
def test_short_text
|
35
|
-
chat = GptTranslate::ChatGPT.new('fake-key', '
|
36
|
+
chat = GptTranslate::ChatGPT.new('fake-key', 'foo', 'xx', 'xx')
|
36
37
|
assert_equal('Hello, world!', chat.translate('Hello, world!'))
|
37
38
|
end
|
38
39
|
|
39
40
|
def test_dry_mode
|
40
|
-
chat = GptTranslate::ChatGPT.new('', '
|
41
|
-
assert_equal(38, chat.translate('This text should not be sent to OpenAI').length)
|
41
|
+
chat = GptTranslate::ChatGPT.new('', 'foo', 'xx', 'xx')
|
42
|
+
assert_equal(38, chat.translate('This text should not be sent to OpenAI', min: 100).length)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_no_translation
|
46
|
+
chat = GptTranslate::ChatGPT.new('', 'foo', 'xx', 'xx')
|
47
|
+
chat.translate(
|
48
|
+
"
|
49
|
+
How are you, my friend?
|
50
|
+
|
51
|
+
Read this Java code:
|
52
|
+
|
53
|
+
```
|
54
|
+
System.out.println(\"Hello, dude!\");
|
55
|
+
System.out.println(\"Good bye!\");
|
56
|
+
System.out.println(\"Done!\");
|
57
|
+
```
|
58
|
+
|
59
|
+
This is it.
|
60
|
+
",
|
61
|
+
min: 40
|
62
|
+
)
|
42
63
|
end
|
43
64
|
|
44
65
|
def test_markup
|
45
|
-
chat = GptTranslate::ChatGPT.new('fake-key', 'gpt-3.5-turbo', '
|
66
|
+
chat = GptTranslate::ChatGPT.new('fake-key', 'gpt-3.5-turbo', 'xx', 'xx')
|
46
67
|
assert_equal('<img src="a"/>', chat.translate('<img src="a"/>'))
|
47
68
|
end
|
48
69
|
|
70
|
+
def test_code_block
|
71
|
+
chat = GptTranslate::ChatGPT.new('fake-key', '', 'xx', 'xx')
|
72
|
+
chat.translate("```\ntest\n```", min: 0)
|
73
|
+
end
|
74
|
+
|
49
75
|
def test_through_webmock
|
50
76
|
stub_request(:any, 'https://api.openai.com/v1/chat/completions')
|
51
77
|
.to_return(body: '{"choices":[{"message":{"content": "boom!"}}]}')
|
data/test/test_generator.rb
CHANGED
data/test/test_permalink.rb
CHANGED
data/test/test_ping.rb
CHANGED
data/test/test_plain.rb
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
# SOFTWARE.
|
24
24
|
|
25
25
|
require 'minitest/autorun'
|
26
|
+
require_relative 'test__helper'
|
26
27
|
require_relative '../lib/jekyll-chatgpt-translate/plain'
|
27
28
|
|
28
29
|
# Plain test.
|
@@ -31,9 +32,9 @@ require_relative '../lib/jekyll-chatgpt-translate/plain'
|
|
31
32
|
# License:: MIT
|
32
33
|
class GptTranslate::PlainTest < Minitest::Test
|
33
34
|
def test_simple_map
|
34
|
-
assert_equal('Hello, world
|
35
|
-
assert_equal('Hello, world!', GptTranslate::Plain.new("Hello,\n[world](/x.html)!").to_s)
|
36
|
-
assert_equal('Hello, Jeff
|
35
|
+
assert_equal('Hello, **world**!', GptTranslate::Plain.new("Hello,\n**world**!").to_s)
|
36
|
+
assert_equal('Hello, [world](/x.html)!', GptTranslate::Plain.new("Hello,\n[world](/x.html)!").to_s)
|
37
|
+
assert_equal('Hello, *Jeff*!', GptTranslate::Plain.new('Hello, _Jeff_!').to_s)
|
37
38
|
# assert_equal('Hello, Walter!', GptTranslate::Plain.new('Hello, ~Walter~!').to_s)
|
38
39
|
assert_equal("Hi\n\nBye", GptTranslate::Plain.new(" Hi\n\nBye\n\n\n").to_s)
|
39
40
|
assert_equal('Hi, dude!', GptTranslate::Plain.new(" Hi,\ndude!\n").to_s)
|
@@ -66,23 +67,35 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
66
67
|
|
67
68
|
def test_links
|
68
69
|
assert_equal(
|
69
|
-
'Hello, dude!',
|
70
|
-
GptTranslate::Plain.new('Hello, [dude](
|
70
|
+
'Hello, [dude](/a.html)!',
|
71
|
+
GptTranslate::Plain.new('Hello, [dude](/a.html)!').to_s
|
71
72
|
)
|
72
73
|
end
|
73
74
|
|
74
75
|
def test_code
|
75
76
|
assert_equal(
|
76
|
-
'Hello, Java
|
77
|
+
'Hello, `Java`!',
|
77
78
|
GptTranslate::Plain.new('Hello, `Java`!').to_s
|
78
79
|
)
|
79
80
|
end
|
80
81
|
|
81
82
|
def test_code_block
|
83
|
+
assert_equal(
|
84
|
+
"```\na\na\na\na\na\na\na\n\n```",
|
85
|
+
GptTranslate::Plain.new("```\na\na\na\na\na\na\na\n\n```").to_s
|
86
|
+
)
|
82
87
|
assert_equal(
|
83
88
|
"Hello:\n\n```\nJava\n```",
|
84
89
|
GptTranslate::Plain.new("Hello:\n\n```\nJava\n```\n").to_s
|
85
90
|
)
|
91
|
+
assert_equal(
|
92
|
+
"```\nHello\n```",
|
93
|
+
GptTranslate::Plain.new("```\nHello\n```").to_s
|
94
|
+
)
|
95
|
+
assert_equal(
|
96
|
+
"```\nprint('hi!')\n```",
|
97
|
+
GptTranslate::Plain.new("```java\nprint('hi!')\n```").to_s
|
98
|
+
)
|
86
99
|
end
|
87
100
|
|
88
101
|
def test_titles
|
@@ -103,17 +116,6 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
103
116
|
assert_equal('<img src="a"/>', GptTranslate::Plain.new('<img src="a"/>').to_s)
|
104
117
|
end
|
105
118
|
|
106
|
-
def test_big_code
|
107
|
-
assert_equal(
|
108
|
-
"```\nHello\n```",
|
109
|
-
GptTranslate::Plain.new("```\nHello\n```").to_s
|
110
|
-
)
|
111
|
-
assert_equal(
|
112
|
-
"```\nprint('hi!')\n```",
|
113
|
-
GptTranslate::Plain.new("```java\nprint('hi!')\n```").to_s
|
114
|
-
)
|
115
|
-
end
|
116
|
-
|
117
119
|
def test_liquid_tags
|
118
120
|
assert_equal(
|
119
121
|
'Hello, !',
|
@@ -143,4 +145,64 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
143
145
|
GptTranslate::Plain.new("Hello, <!-- \nJava\n -->!").to_s
|
144
146
|
)
|
145
147
|
end
|
148
|
+
|
149
|
+
def test_big_text
|
150
|
+
expected = "Hi, dear **friend**!
|
151
|
+
|
152
|
+
In this *lovely* letter I will explain how objects work in C++:
|
153
|
+
|
154
|
+
Declare a class
|
155
|
+
|
156
|
+
Make an instance of it
|
157
|
+
|
158
|
+
Delete the instance
|
159
|
+
|
160
|
+
## More details
|
161
|
+
|
162
|
+
Something like this:
|
163
|
+
|
164
|
+
```
|
165
|
+
class Foo {};
|
166
|
+
Foo f = Foo();
|
167
|
+
```
|
168
|
+
|
169
|
+
And then use `new` and `delete` like this:
|
170
|
+
|
171
|
+
```
|
172
|
+
Foo* f = new Foo();
|
173
|
+
delete f;
|
174
|
+
```
|
175
|
+
|
176
|
+
Should work!"
|
177
|
+
input = "
|
178
|
+
Hi, dear **friend**!
|
179
|
+
|
180
|
+
In this _lovely_ letter I will
|
181
|
+
explain how objects
|
182
|
+
work in C++:
|
183
|
+
|
184
|
+
* \tDeclare a class
|
185
|
+
* \tMake an instance of it
|
186
|
+
* \tDelete the instance
|
187
|
+
|
188
|
+
## More details
|
189
|
+
|
190
|
+
Something like this:
|
191
|
+
|
192
|
+
```
|
193
|
+
class Foo {};
|
194
|
+
Foo f = Foo();
|
195
|
+
```
|
196
|
+
|
197
|
+
And then use `new` and `delete` like this:
|
198
|
+
|
199
|
+
```cpp
|
200
|
+
Foo* f = new Foo();
|
201
|
+
delete f;
|
202
|
+
```
|
203
|
+
|
204
|
+
Should work!
|
205
|
+
"
|
206
|
+
assert_equal(expected, GptTranslate::Plain.new(input).to_s)
|
207
|
+
end
|
146
208
|
end
|
data/test/test_prompt.rb
CHANGED
@@ -23,6 +23,7 @@
|
|
23
23
|
# SOFTWARE.
|
24
24
|
|
25
25
|
require 'minitest/autorun'
|
26
|
+
require_relative 'test__helper'
|
26
27
|
require_relative '../lib/jekyll-chatgpt-translate/prompt'
|
27
28
|
|
28
29
|
# Prompt test.
|
@@ -31,7 +32,11 @@ require_relative '../lib/jekyll-chatgpt-translate/prompt'
|
|
31
32
|
# License:: MIT
|
32
33
|
class GptTranslate::PromptTest < Minitest::Test
|
33
34
|
def par(body, source, target)
|
34
|
-
|
35
|
+
[
|
36
|
+
'Please, translate the following Markdown paragraph',
|
37
|
+
" from #{source} to #{target},",
|
38
|
+
" don't translate technical terms and proper nouns:\n\n#{body}"
|
39
|
+
].join
|
35
40
|
end
|
36
41
|
|
37
42
|
def test_english_to_russian
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-chatgpt-translate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: iri
|