jekyll-chatgpt-translate 0.0.18 → 0.0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/README.md +6 -0
- data/jekyll-chatgpt-translate.gemspec +1 -1
- data/lib/jekyll-chatgpt-translate/chatgpt.rb +17 -9
- data/lib/jekyll-chatgpt-translate/generator.rb +5 -4
- data/lib/jekyll-chatgpt-translate/ping.rb +8 -8
- data/lib/jekyll-chatgpt-translate/plain.rb +46 -25
- 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 +90 -16
- 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: 76da34820682d38fd53ca0c5c02bf8d9e23f5665af2a6f0553f11a62d6fce452
|
4
|
+
data.tar.gz: 413def3d7da352c1a6c2d7dbd67722329573732d53bfbae96a1bf86c39c9c16e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 715bdfed0bf33249c0091a66a0f338d89469aaa43db6fb6f80bf79a2e633d68ed0087997ce7b08b259bc24a47196061d3114d2c3f66ab8f1c7f76cc9758e0a2c
|
7
|
+
data.tar.gz: 6a0eeb27d20053284535b0a053ab3e0832eb6e20477bb3451ac095ce5ab48e967b7e5e607aa777269475ce846b784414382e1367ceb88daf5e24ad458440c745
|
data/.rubocop.yml
CHANGED
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)
|
@@ -69,6 +70,11 @@ Full list of options available to specify in `_config.yml`:
|
|
69
70
|
download them and place into the `_site` directory. Thus, your entire site
|
70
71
|
will have to be re-translated on every build (might be very ineffective if the site is big!)
|
71
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
|
+
|
72
78
|
* `layout` (optional) — is name of the file in `_layouts` directory, without the extension.
|
73
79
|
This layout will be specified for the pages generated by this plugin.
|
74
80
|
|
@@ -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.20'
|
32
32
|
s.license = 'MIT'
|
33
33
|
s.summary = 'Translate Jekyll Pages Through ChatGPT'
|
34
34
|
s.description = [
|
@@ -47,13 +47,17 @@ 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 par.length < min
|
54
|
+
Jekyll.logger.debug("Not translating this, b/c too short: #{par.inspect}")
|
54
55
|
par
|
55
|
-
elsif par
|
56
|
-
Jekyll.logger.debug("Not translating this
|
56
|
+
elsif par.start_with?('```') || par.end_with?('```')
|
57
|
+
Jekyll.logger.debug("Not translating this code block: #{par.inspect}")
|
58
|
+
par
|
59
|
+
elsif par =~ /^[^\p{Alnum}\*'"]/
|
60
|
+
Jekyll.logger.debug("Not translating this, b/c it's not a plain text: #{par.inspect}")
|
57
61
|
par
|
58
62
|
elsif @key.empty?
|
59
63
|
par
|
@@ -79,15 +83,19 @@ class GptTranslate::ChatGPT
|
|
79
83
|
}
|
80
84
|
)
|
81
85
|
answer = response.dig('choices', 0, 'message', 'content')
|
82
|
-
Jekyll.logger.debug("ChatGPT prompt:
|
86
|
+
Jekyll.logger.debug("ChatGPT prompt: #{prompt.inspect}, ChatGPT answer: #{answer.inspect}")
|
83
87
|
rescue StandardError => e
|
84
88
|
attempt += 1
|
85
|
-
|
89
|
+
if attempt < 4
|
90
|
+
Jekyll.logger.error("ChatGPT failed to answer to #{prompt.inspect} \
|
91
|
+
(attempt no.#{attempt}): #{e.message.inspect}")
|
92
|
+
retry
|
93
|
+
end
|
86
94
|
raise e
|
87
95
|
end
|
88
96
|
Jekyll.logger.info("Translated #{par.split.count} #{@source.upcase} words \
|
89
97
|
to #{answer.split.count} #{@target.upcase} words \
|
90
|
-
through #{@model} in #{(Time.now - start).round(2)}s")
|
98
|
+
through #{@model} in #{(Time.now - start).round(2)}s: #{"#{par[0..24]}...".inspect}")
|
91
99
|
answer
|
92
100
|
end
|
93
101
|
end
|
@@ -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
|
@@ -79,7 +80,7 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
79
80
|
config['source'] || 'en',
|
80
81
|
lang
|
81
82
|
)
|
82
|
-
foreign = gpt.translate(plain)
|
83
|
+
foreign = gpt.translate(plain, min: min_chars)
|
83
84
|
File.write(
|
84
85
|
path,
|
85
86
|
[
|
@@ -95,7 +96,7 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
95
96
|
'',
|
96
97
|
foreign,
|
97
98
|
'',
|
98
|
-
"#{marker} on #{Time.now.strftime('%d
|
99
|
+
"#{marker} on #{Time.now.strftime('%Y-%m-%d at %H:%M')}\n{: .jekyll-chatgpt-translate}"
|
99
100
|
].join("\n")
|
100
101
|
)
|
101
102
|
site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
|
@@ -121,10 +122,10 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
121
122
|
k
|
122
123
|
elsif File.exist?(file)
|
123
124
|
k = File.read(file).strip
|
124
|
-
Jekyll.logger.info("The OpenAI API key taken from the file:
|
125
|
+
Jekyll.logger.info("The OpenAI API key taken from the file: #{file.inspect} (#{k.length} chars)")
|
125
126
|
k
|
126
127
|
else
|
127
|
-
Jekyll.logger.info("The file with the OpenAI API key is not found:
|
128
|
+
Jekyll.logger.info("The file with the OpenAI API key is not found: #{file.inspect}")
|
128
129
|
nil
|
129
130
|
end
|
130
131
|
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}")
|
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,31 +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.
|
53
|
+
# Motivated by https://github.com/vmg/redcarpet/blob/master/lib/redcarpet/render_strip.rb
|
58
54
|
class Strip < Redcarpet::Render::Base
|
59
55
|
%i[
|
60
|
-
|
56
|
+
block_quote
|
61
57
|
block_html
|
62
|
-
autolink
|
63
|
-
|
64
|
-
triple_emphasis
|
58
|
+
autolink
|
59
|
+
underline
|
60
|
+
triple_emphasis
|
61
|
+
strikethrough
|
65
62
|
superscript highlight quote
|
66
63
|
footnotes footnote_def footnote_ref
|
67
64
|
entity normal_text
|
@@ -71,18 +68,38 @@ class GptTranslate::Plain
|
|
71
68
|
end
|
72
69
|
end
|
73
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
|
+
|
83
|
+
def header(text, level)
|
84
|
+
"#{'#' * level} #{text}\n\n"
|
85
|
+
end
|
86
|
+
|
74
87
|
def codespan(content)
|
75
88
|
if content.start_with?("\n")
|
76
89
|
"```#{content}```"
|
77
90
|
elsif content.end_with?("\n")
|
78
91
|
"```\n#{content.split("\n", 2)[1]}```"
|
79
92
|
else
|
80
|
-
content
|
93
|
+
"`#{content}`"
|
81
94
|
end
|
82
95
|
end
|
83
96
|
|
84
|
-
def
|
85
|
-
|
97
|
+
def image(link, title, alt)
|
98
|
+
"![#{alt}](#{link} \"#{title}\")"
|
99
|
+
end
|
100
|
+
|
101
|
+
def raw_html(html)
|
102
|
+
html
|
86
103
|
end
|
87
104
|
|
88
105
|
def list(content, _type)
|
@@ -90,15 +107,19 @@ class GptTranslate::Plain
|
|
90
107
|
end
|
91
108
|
|
92
109
|
def list_item(content, _type)
|
93
|
-
content
|
110
|
+
"#{content.strip}\n\n"
|
94
111
|
end
|
95
112
|
|
96
113
|
def paragraph(text)
|
97
|
-
text
|
114
|
+
unless text.start_with?('```')
|
115
|
+
text.gsub!(/\n+/, ' ')
|
116
|
+
text.gsub!(/\s{2,}/, ' ')
|
117
|
+
end
|
118
|
+
"#{text}\n\n"
|
98
119
|
end
|
99
120
|
|
100
|
-
def link(
|
101
|
-
content
|
121
|
+
def link(link, _title, content)
|
122
|
+
"[#{content}](#{link})"
|
102
123
|
end
|
103
124
|
end
|
104
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,8 +32,10 @@ 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,
|
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)
|
38
|
+
# assert_equal('Hello, Walter!', GptTranslate::Plain.new('Hello, ~Walter~!').to_s)
|
36
39
|
assert_equal("Hi\n\nBye", GptTranslate::Plain.new(" Hi\n\nBye\n\n\n").to_s)
|
37
40
|
assert_equal('Hi, dude!', GptTranslate::Plain.new(" Hi,\ndude!\n").to_s)
|
38
41
|
end
|
@@ -64,34 +67,27 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
64
67
|
|
65
68
|
def test_links
|
66
69
|
assert_equal(
|
67
|
-
'Hello, dude!',
|
68
|
-
GptTranslate::Plain.new('Hello, [dude](
|
70
|
+
'Hello, [dude](/a.html)!',
|
71
|
+
GptTranslate::Plain.new('Hello, [dude](/a.html)!').to_s
|
69
72
|
)
|
70
73
|
end
|
71
74
|
|
72
75
|
def test_code
|
73
76
|
assert_equal(
|
74
|
-
'Hello, Java
|
77
|
+
'Hello, `Java`!',
|
75
78
|
GptTranslate::Plain.new('Hello, `Java`!').to_s
|
76
79
|
)
|
77
80
|
end
|
78
81
|
|
79
82
|
def test_code_block
|
80
83
|
assert_equal(
|
81
|
-
"
|
82
|
-
GptTranslate::Plain.new("
|
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
|
83
86
|
)
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_html
|
87
87
|
assert_equal(
|
88
|
-
|
89
|
-
GptTranslate::Plain.new(
|
88
|
+
"Hello:\n\n```\nJava\n```",
|
89
|
+
GptTranslate::Plain.new("Hello:\n\n```\nJava\n```\n").to_s
|
90
90
|
)
|
91
|
-
assert_equal('<img src="a"/>', GptTranslate::Plain.new('<img src="a"/>').to_s)
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_big_code
|
95
91
|
assert_equal(
|
96
92
|
"```\nHello\n```",
|
97
93
|
GptTranslate::Plain.new("```\nHello\n```").to_s
|
@@ -102,6 +98,24 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
102
98
|
)
|
103
99
|
end
|
104
100
|
|
101
|
+
def test_titles
|
102
|
+
assert_equal('# Hello', GptTranslate::Plain.new('# Hello').to_s)
|
103
|
+
assert_equal('## Hello', GptTranslate::Plain.new('## Hello').to_s)
|
104
|
+
assert_equal('### Hello', GptTranslate::Plain.new('### Hello').to_s)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_image
|
108
|
+
assert_equal('![alt](a.png "hello")', GptTranslate::Plain.new('![alt](a.png "hello")').to_s)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_html
|
112
|
+
assert_equal(
|
113
|
+
'This is picture: <img src="a"/>!',
|
114
|
+
GptTranslate::Plain.new('This is picture: <img src="a"/>!').to_s
|
115
|
+
)
|
116
|
+
assert_equal('<img src="a"/>', GptTranslate::Plain.new('<img src="a"/>').to_s)
|
117
|
+
end
|
118
|
+
|
105
119
|
def test_liquid_tags
|
106
120
|
assert_equal(
|
107
121
|
'Hello, !',
|
@@ -131,4 +145,64 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
131
145
|
GptTranslate::Plain.new("Hello, <!-- \nJava\n -->!").to_s
|
132
146
|
)
|
133
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
|
134
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.20
|
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
|