jekyll-chatgpt-translate 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|
+
[](http://badge.fury.io/rb/glogin)
|
1
2
|
<img src="logo.png" style="width:256px;"/>
|
2
3
|
|
3
4
|
[](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
|
+
""
|
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('', GptTranslate::Plain.new('').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
|