trix-genius 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39389e89a18944eef1092f41ff29d268165fad10c386621aa1dc3c45f3dfb385
4
- data.tar.gz: f2ddd8f93c91c6b4bf996d3cfbbaf0dfde4250bc9d554f57eb75109ef813b86a
3
+ metadata.gz: a05bf7cdc1b97afa037bf20356cebbabb06a89ab11f4770fc375a062aa6cdf35
4
+ data.tar.gz: 4987bc9f243bb514f969abeca9daea25a927e87a4f26a2c89f1acba2493a9f99
5
5
  SHA512:
6
- metadata.gz: 8281b3356cb71fc41598c4bc5441871a9aff13f4bb6c05f670391be6595fb8dca5ac49e2ae0eb146a712822bb4c0869e4b145455a0e499e01458518b09487360
7
- data.tar.gz: 3b8476b28b2aecf1523f74275a0696fd936f1ba5901e2f069d641f074d3c198b0892b4dbd4692b0485f7be9f2127e1807dff8590c92813b049f3b1ba2551fd34
6
+ metadata.gz: bab76153436f4713d8f52ff89ee982aeab277c51dfba671c587a3ee4496f3e2d57879492ac1aac49bb0e0241f19ac84b0e97c98b590281f29ac0f237688a85f8
7
+ data.tar.gz: 9ad9580d30792a4a3bd6c04f14626e23094bcd9d2300a021e22449d2cfb34eeb721c8cce304a8d24b93ca6b1b20bc7a35e7122cd589755ae0df233b1b7745350
@@ -1,4 +1,5 @@
1
1
  require "rails/generators"
2
+ require "trix_genius/flexible_injector"
2
3
 
3
4
  module TrixGenius
4
5
  module Generators
@@ -12,28 +13,21 @@ module TrixGenius
12
13
  def add_import_to_application_js
13
14
  js_application_path = "app/javascript/application.js"
14
15
  js_application_path = File.join(destination_root, js_application_path)
15
-
16
- if File.exist?(js_application_path)
17
- application_file = File.read(js_application_path)
18
-
19
- inject_into_file js_application_path, "\n" + 'import "trix"' + "\n", after: 'import "controllers"'
20
- inject_into_file js_application_path, "\n" + 'import "@rails/actiontext"' + ("\n" * 2), after: 'import "trix"'
21
- else
16
+ unless File.exist?(js_application_path)
22
17
  puts javascript_application_msg
23
18
  say_status("error", "Could not find #{js_application_path}", :red)
24
19
  end
25
20
 
26
21
  js_application_controller_path = "app/javascript/controllers/application.js"
27
22
  js_application_controller_path = File.join(destination_root, js_application_controller_path)
28
-
29
- if File.exist?(js_application_controller_path)
30
- application_controller_file = File.read(js_application_controller_path)
31
- inject_into_file js_application_controller_path, "\n" + 'import TrixController from "controllers/trix_genius_controller"' + "\n", after: 'import { Application } from "@hotwired/stimulus"'
32
- inject_into_file js_application_controller_path, "\n" + 'application.register("trix", TrixController)' + ("\n" * 2), before: 'export { application }'
33
- else
23
+ unless File.exist?(js_application_controller_path)
34
24
  puts javascript_application_controller_msg
35
25
  say_status("error", "Could not find #{js_application_controller_path}", :red)
36
26
  end
27
+
28
+ gem_root = File.expand_path("../..", __dir__)
29
+ config_path = File.join("config", "setting_updates.yml")
30
+ FlexibleInjector.start([config_path, destination_root])
37
31
  end
38
32
 
39
33
  def create_stimulus_controller
@@ -44,6 +38,7 @@ module TrixGenius
44
38
  route_code = ["",
45
39
  " # TrixGenius: Auto-added route",
46
40
  ' post "/trix_genius/correct_spelling", to: "trix_genius#correct_spelling"',
41
+ ' post "trix_genius/calculate_expression", to: "trix_genius#calculate_expression"',
47
42
  ""].join("\n")
48
43
 
49
44
  inject_into_file File.join(destination_root, "config/routes.rb"), route_code, after: "Rails.application.routes.draw do\n"
@@ -4,26 +4,53 @@ export default class extends Controller {
4
4
  // Use an arrow function to preserve `this` context
5
5
  addEventListener("trix-initialize", (event) => {
6
6
  const trixEditor = event.target;
7
+ const aiButtonCheckSpell = document.createElement("button");
7
8
 
8
- // Create the AI button
9
- const aiButton = document.createElement("button");
10
- aiButton.setAttribute("type", "button");
11
- aiButton.setAttribute("tabindex", -1);
12
- aiButton.setAttribute("title", "Correct Orthography");
13
- aiButton.classList.add("trix-button"); // Use Trix's default button styling
14
- aiButton.innerHTML = `
15
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
16
- <path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
17
- </svg>
9
+ aiButtonCheckSpell.setAttribute("type", "button");
10
+ aiButtonCheckSpell.setAttribute("tabindex", -1);
11
+ aiButtonCheckSpell.setAttribute("title", "Check Spelling");
12
+ aiButtonCheckSpell.classList.add("trix-button");
13
+ aiButtonCheckSpell.innerHTML = `
14
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
15
+ <!-- Main check icon -->
16
+ <path fill="#4CAF50" d="M21 7L9 19l-5.5-5.5 1.41-1.41L9 16.17 19.59 5.59 21 7z"/>
17
+ <path fill="#BBDEFB" d="M14 3v5h5M12 18v-2h6v2h-6zm0-4v-2h4v2h-4z"/>
18
+ <g transform="translate(18 2)">
19
+ <rect width="16" height="8" x="-16" y="0" fill="#FF9800" rx="1.5"/>
20
+ <text x="-8" y="4.5" font-size="6" font-family="Arial" fill="white" text-anchor="middle" dominant-baseline="middle">AI</text>
21
+ </g>
22
+ </svg>
23
+ `;
24
+
25
+
26
+ // Append the button to the toolbar
27
+ document.querySelector(".trix-button-group--text-tools").appendChild(aiButtonCheckSpell);
28
+
29
+ const aiButtonCalculateExpresions = document.createElement("button");
30
+ aiButtonCalculateExpresions.setAttribute("type", "button");
31
+ aiButtonCalculateExpresions.setAttribute("tabindex", -1);
32
+ aiButtonCalculateExpresions.setAttribute("title", "Calculate Expressions");
33
+ aiButtonCalculateExpresions.classList.add("trix-button");
34
+ aiButtonCalculateExpresions.innerHTML = `
35
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
36
+ <rect x="2" y="4" width="20" height="14" fill="#F5F5F5" stroke="#CCCCCC" stroke-width="1" rx="2" ry="2" />
37
+ <line x1="8" y1="11" x2="16" y2="11" stroke="#3498DB" stroke-width="2" />
38
+ <line x1="12" y1="7" x2="12" y2="15" stroke="#3498DB" stroke-width="2" />
39
+ </svg>
18
40
  `;
19
41
 
20
42
  // Append the button to the toolbar
21
- document.querySelector(".trix-button-group--text-tools").appendChild(aiButton);
43
+ document.querySelector(".trix-button-group--text-tools").appendChild(aiButtonCalculateExpresions);
22
44
 
23
45
  // Attach the click event to the button
24
- aiButton.addEventListener("click", () => {
46
+ aiButtonCheckSpell.addEventListener("click", () => {
25
47
  this.correctOrthography(trixEditor);
26
48
  });
49
+
50
+ aiButtonCalculateExpresions.addEventListener("click", () => {
51
+ this.calculateExpression(trixEditor);
52
+ });
53
+
27
54
  });
28
55
  }
29
56
 
@@ -42,7 +69,6 @@ export default class extends Controller {
42
69
  if (!response.ok) {
43
70
  throw new Error("Network response was not ok");
44
71
  }
45
-
46
72
  const result = await response.json();
47
73
 
48
74
  editor.loadHTML(result.corrected_text);
@@ -51,4 +77,31 @@ export default class extends Controller {
51
77
  alert("An error occurred while correcting orthography.");
52
78
  }
53
79
  }
80
+
81
+
82
+ async calculateExpression(trixEditor) {
83
+ try {
84
+ const editor = trixEditor.editor;
85
+ const content = editor.getDocument().toString(); // Get the current content
86
+
87
+ // Send the content to the backend for correction
88
+ const response = await fetch("/trix_genius/calculate_expression", {
89
+ method: "POST",
90
+ headers: { "Content-Type": "application/json" },
91
+ body: JSON.stringify({ text: content }),
92
+ });
93
+
94
+ if (!response.ok) {
95
+ throw new Error("Network response was not ok");
96
+ }
97
+
98
+ const result = await response.json();
99
+ editor.loadHTML(result.calculus.replace(/\n/g, "<br>"));
100
+
101
+ } catch (error) {
102
+ console.error("Error Calculate Expressions:", error);
103
+ alert("An error occurred while calculate expression.");
104
+ }
105
+ }
54
106
  }
107
+
@@ -3,23 +3,107 @@ require 'faraday'
3
3
  class TrixGeniusController < ApplicationController
4
4
  skip_before_action :verify_authenticity_token
5
5
 
6
- def correct_spelling
6
+ def calculate_expression
7
7
  text = params.require(:text)
8
+ calculus = call_ai_calculate_expression(text)
9
+ render json: { calculus: calculus }
10
+ rescue StandardError => e
11
+ Rails.logger.error("Calculate Expression Error: #{e.message}")
12
+ render json: { error: "An error occurred while CalculatingExpression." }, status: :unprocessable_entity
13
+ end
8
14
 
9
- corrected_text = call_ai_service(text)
10
-
15
+ def correct_spelling
16
+ text = params.require(:text)
17
+ corrected_text = call_ai_check_spell(text)
11
18
  render json: { corrected_text: corrected_text }
12
19
  rescue StandardError => e
13
20
  Rails.logger.error("Orthography Correction Error: #{e.message}")
14
21
  render json: { error: "An error occurred while correcting orthography." }, status: :unprocessable_entity
15
22
  end
16
23
 
24
+
25
+
17
26
  private
18
27
 
19
- def call_ai_service(text)
28
+ def evaluate_expression(expr)
29
+ # Allow only numbers, operators, and parentheses
30
+ allowed_chars = Set.new('0123456789+-*/(). '.chars)
31
+ return nil unless expr.chars.all? { |c| allowed_chars.include?(c) }
32
+
33
+ # Convert integers to floats for proper division
34
+ sanitized = expr.gsub(/(\d+(?:\.\d+)?)/) { |m| m.include?('.') ? m : "#{m}.0" }
35
+
36
+ begin
37
+ result = eval(sanitized)
38
+ # Convert whole numbers to integers for cleaner output
39
+ result = result.to_i if result.is_a?(Float) && result == result.floor
40
+ result
41
+ rescue
42
+ nil
43
+ end
44
+ end
45
+
46
+ def process_text(text)
47
+ stack = []
48
+ expressions = []
49
+
50
+ # Find all top-level parentheses expressions
51
+ text.chars.each_with_index do |char, i|
52
+ if char == '('
53
+ stack.push(i)
54
+ elsif char == ')' && stack.any?
55
+ start_idx = stack.pop
56
+ if stack.empty? # Only track top-level parentheses
57
+ expressions << { start: start_idx, end: i, expr: text[start_idx..i] }
58
+ end
59
+ end
60
+ end
61
+
62
+ # Process from last to first to preserve positions
63
+ expressions.reverse.each do |exp|
64
+ inner_expr = exp[:expr][1...-1] # Remove outer parentheses
65
+ result = evaluate_expression(inner_expr)
66
+
67
+ next unless result
68
+
69
+ replacement = "#{inner_expr}=#{result}"
70
+ text = text[0...exp[:start]] + replacement + text[exp[:end]+1..-1]
71
+ end
72
+
73
+ text
74
+ end
75
+
76
+ def call_ai_calculate_expression(text)
77
+ processed_text = process_text(text)
78
+ headers = {
79
+ 'Content-Type' => 'application/json',
80
+ 'Authorization' => "Bearer #{Rails.application.config.deepseek[:api_key]}"
81
+ }
82
+
83
+ body = {
84
+ model: "deepseek-chat",
85
+ messages: [{
86
+ role: "user",
87
+ content: "Format this text maintaining all original content but with calculated expressions: #{processed_text}"
88
+ }],
89
+ temperature: 0.7,
90
+ max_tokens: 500
91
+ }.to_json
92
+
93
+ response = Faraday.post(Rails.application.config.deepseek[:api_url], body, headers)
94
+
95
+ if response.success?
96
+ str = JSON.parse(response.body)['choices'][0]['message']['content'].split("---")[1].gsub("*", "")
97
+ return str
98
+ else
99
+ puts "Error: #{response.status} - #{response.body}"
100
+ end
101
+ end
102
+
103
+ def call_ai_check_spell(text)
20
104
  headers = {
21
105
  'Content-Type' => 'application/json',
22
- 'Authorization' => "Bearer #{Rails.application.config.deepseek[:api_key}"
106
+ 'Authorization' => "Bearer #{Rails.application.config.deepseek[:api_key]}"
23
107
  }
24
108
 
25
109
  body = {
@@ -29,12 +113,13 @@ class TrixGeniusController < ApplicationController
29
113
  max_tokens: 500
30
114
  }.to_json
31
115
 
32
- response = Faraday.post(Rails.application.config.deepseek[:api_url],, body, headers)
116
+ response = Faraday.post(Rails.application.config.deepseek[:api_url], body, headers)
33
117
 
34
118
  if response.success?
35
- return JSON.parse(response.body)['choices'][0]['message']['content'].split('"')[1]
119
+ return JSON.parse(response.body)['choices'][1]['message']['content'].split('"')[1]
36
120
  else
37
- "Error: #{response.status} - #{response.body}"
121
+ puts "Error: #{response.status} - #{response.body}"
38
122
  end
39
123
  end
40
124
  end
125
+
@@ -0,0 +1,44 @@
1
+ require 'yaml'
2
+ require 'thor'
3
+ require 'thor/actions'
4
+
5
+ module TrixGenius
6
+ class FlexibleInjector < Thor::Group
7
+ include Thor::Actions
8
+ argument :file_name, type: :string
9
+ argument :base_path, type: :string
10
+
11
+ def self.source_root
12
+ Dir.pwd
13
+ end
14
+
15
+ def apply_from_config
16
+ injections = YAML.load_file(file_name)
17
+
18
+ injections.each do |injection|
19
+ file_path = injection['file']
20
+ content = "\n" + injection['content'] + "\n"
21
+ message = (injection['message'] || 'insert').to_sym
22
+ options = {}
23
+ options[:after] = injection['after'] if injection['after']
24
+ options[:before] = injection['before'] if injection['before']
25
+
26
+ complete_path = File.join(base_path, file_path)
27
+
28
+ case message
29
+ when :insert
30
+ say_status :insert, complete_path
31
+ inject_into_file(complete_path, content, options)
32
+ when :append
33
+ say_status :append, complete_path
34
+ inject_into_file(complete_path, content)
35
+ else
36
+ say_status :skip, "#{complete_path} — unknown message: #{message}", :yellow
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+
@@ -3,23 +3,107 @@ require 'faraday'
3
3
  class TrixGeniusController < ApplicationController
4
4
  skip_before_action :verify_authenticity_token
5
5
 
6
- def correct_spelling
6
+ def calculate_expression
7
7
  text = params.require(:text)
8
+ calculus = call_ai_calculate_expression(text)
9
+ render json: { calculus: calculus }
10
+ rescue StandardError => e
11
+ Rails.logger.error("Calculate Expression Error: #{e.message}")
12
+ render json: { error: "An error occurred while CalculatingExpression." }, status: :unprocessable_entity
13
+ end
8
14
 
9
- corrected_text = call_ai_service(text)
10
-
15
+ def correct_spelling
16
+ text = params.require(:text)
17
+ corrected_text = call_ai_check_spell(text)
11
18
  render json: { corrected_text: corrected_text }
12
19
  rescue StandardError => e
13
20
  Rails.logger.error("Orthography Correction Error: #{e.message}")
14
21
  render json: { error: "An error occurred while correcting orthography." }, status: :unprocessable_entity
15
22
  end
16
23
 
24
+
25
+
17
26
  private
18
27
 
19
- def call_ai_service(text)
28
+ def evaluate_expression(expr)
29
+ # Allow only numbers, operators, and parentheses
30
+ allowed_chars = Set.new('0123456789+-*/(). '.chars)
31
+ return nil unless expr.chars.all? { |c| allowed_chars.include?(c) }
32
+
33
+ # Convert integers to floats for proper division
34
+ sanitized = expr.gsub(/(\d+(?:\.\d+)?)/) { |m| m.include?('.') ? m : "#{m}.0" }
35
+
36
+ begin
37
+ result = eval(sanitized)
38
+ # Convert whole numbers to integers for cleaner output
39
+ result = result.to_i if result.is_a?(Float) && result == result.floor
40
+ result
41
+ rescue
42
+ nil
43
+ end
44
+ end
45
+
46
+ def process_text(text)
47
+ stack = []
48
+ expressions = []
49
+
50
+ # Find all top-level parentheses expressions
51
+ text.chars.each_with_index do |char, i|
52
+ if char == '('
53
+ stack.push(i)
54
+ elsif char == ')' && stack.any?
55
+ start_idx = stack.pop
56
+ if stack.empty? # Only track top-level parentheses
57
+ expressions << { start: start_idx, end: i, expr: text[start_idx..i] }
58
+ end
59
+ end
60
+ end
61
+
62
+ # Process from last to first to preserve positions
63
+ expressions.reverse.each do |exp|
64
+ inner_expr = exp[:expr][1...-1] # Remove outer parentheses
65
+ result = evaluate_expression(inner_expr)
66
+
67
+ next unless result
68
+
69
+ replacement = "#{inner_expr}=#{result}"
70
+ text = text[0...exp[:start]] + replacement + text[exp[:end]+1..-1]
71
+ end
72
+
73
+ text
74
+ end
75
+
76
+ def call_ai_calculate_expression(text)
77
+ processed_text = process_text(text)
78
+ headers = {
79
+ 'Content-Type' => 'application/json',
80
+ 'Authorization' => "Bearer #{Rails.application.config.deepseek[:api_key]}"
81
+ }
82
+
83
+ body = {
84
+ model: "deepseek-chat",
85
+ messages: [{
86
+ role: "user",
87
+ content: "Format this text maintaining all original content but with calculated expressions: #{processed_text}"
88
+ }],
89
+ temperature: 0.7,
90
+ max_tokens: 500
91
+ }.to_json
92
+
93
+ response = Faraday.post(Rails.application.config.deepseek[:api_url], body, headers)
94
+
95
+ if response.success?
96
+ str = JSON.parse(response.body)['choices'][0]['message']['content'].split("---")[1].gsub("*", "")
97
+ return str
98
+ else
99
+ puts "Error: #{response.status} - #{response.body}"
100
+ end
101
+ end
102
+
103
+ def call_ai_check_spell(text)
20
104
  headers = {
21
105
  'Content-Type' => 'application/json',
22
- 'Authorization' => "Bearer #{Rails.application.config.deepseek[:api_key}"
106
+ 'Authorization' => "Bearer #{Rails.application.config.deepseek[:api_key]}"
23
107
  }
24
108
 
25
109
  body = {
@@ -29,12 +113,13 @@ class TrixGeniusController < ApplicationController
29
113
  max_tokens: 500
30
114
  }.to_json
31
115
 
32
- response = Faraday.post(Rails.application.config.deepseek[:api_url],, body, headers)
116
+ response = Faraday.post(Rails.application.config.deepseek[:api_url], body, headers)
33
117
 
34
118
  if response.success?
35
- return JSON.parse(response.body)['choices'][0]['message']['content'].split('"')[1]
119
+ return JSON.parse(response.body)['choices'][1]['message']['content'].split('"')[1]
36
120
  else
37
- "Error: #{response.status} - #{response.body}"
121
+ puts "Error: #{response.status} - #{response.body}"
38
122
  end
39
123
  end
40
124
  end
125
+
@@ -4,26 +4,53 @@ export default class extends Controller {
4
4
  // Use an arrow function to preserve `this` context
5
5
  addEventListener("trix-initialize", (event) => {
6
6
  const trixEditor = event.target;
7
+ const aiButtonCheckSpell = document.createElement("button");
7
8
 
8
- // Create the AI button
9
- const aiButton = document.createElement("button");
10
- aiButton.setAttribute("type", "button");
11
- aiButton.setAttribute("tabindex", -1);
12
- aiButton.setAttribute("title", "Correct Orthography");
13
- aiButton.classList.add("trix-button"); // Use Trix's default button styling
14
- aiButton.innerHTML = `
15
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
16
- <path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
17
- </svg>
9
+ aiButtonCheckSpell.setAttribute("type", "button");
10
+ aiButtonCheckSpell.setAttribute("tabindex", -1);
11
+ aiButtonCheckSpell.setAttribute("title", "Check Spelling");
12
+ aiButtonCheckSpell.classList.add("trix-button");
13
+ aiButtonCheckSpell.innerHTML = `
14
+ <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24">
15
+ <!-- Main check icon -->
16
+ <path fill="#4CAF50" d="M21 7L9 19l-5.5-5.5 1.41-1.41L9 16.17 19.59 5.59 21 7z"/>
17
+ <path fill="#BBDEFB" d="M14 3v5h5M12 18v-2h6v2h-6zm0-4v-2h4v2h-4z"/>
18
+ <g transform="translate(18 2)">
19
+ <rect width="16" height="8" x="-16" y="0" fill="#FF9800" rx="1.5"/>
20
+ <text x="-8" y="4.5" font-size="6" font-family="Arial" fill="white" text-anchor="middle" dominant-baseline="middle">AI</text>
21
+ </g>
22
+ </svg>
23
+ `;
24
+
25
+
26
+ // Append the button to the toolbar
27
+ document.querySelector(".trix-button-group--text-tools").appendChild(aiButtonCheckSpell);
28
+
29
+ const aiButtonCalculateExpresions = document.createElement("button");
30
+ aiButtonCalculateExpresions.setAttribute("type", "button");
31
+ aiButtonCalculateExpresions.setAttribute("tabindex", -1);
32
+ aiButtonCalculateExpresions.setAttribute("title", "Calculate Expressions");
33
+ aiButtonCalculateExpresions.classList.add("trix-button");
34
+ aiButtonCalculateExpresions.innerHTML = `
35
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
36
+ <rect x="2" y="4" width="20" height="14" fill="#F5F5F5" stroke="#CCCCCC" stroke-width="1" rx="2" ry="2" />
37
+ <line x1="8" y1="11" x2="16" y2="11" stroke="#3498DB" stroke-width="2" />
38
+ <line x1="12" y1="7" x2="12" y2="15" stroke="#3498DB" stroke-width="2" />
39
+ </svg>
18
40
  `;
19
41
 
20
42
  // Append the button to the toolbar
21
- document.querySelector(".trix-button-group--text-tools").appendChild(aiButton);
43
+ document.querySelector(".trix-button-group--text-tools").appendChild(aiButtonCalculateExpresions);
22
44
 
23
45
  // Attach the click event to the button
24
- aiButton.addEventListener("click", () => {
46
+ aiButtonCheckSpell.addEventListener("click", () => {
25
47
  this.correctOrthography(trixEditor);
26
48
  });
49
+
50
+ aiButtonCalculateExpresions.addEventListener("click", () => {
51
+ this.calculateExpression(trixEditor);
52
+ });
53
+
27
54
  });
28
55
  }
29
56
 
@@ -42,7 +69,6 @@ export default class extends Controller {
42
69
  if (!response.ok) {
43
70
  throw new Error("Network response was not ok");
44
71
  }
45
-
46
72
  const result = await response.json();
47
73
 
48
74
  editor.loadHTML(result.corrected_text);
@@ -51,4 +77,31 @@ export default class extends Controller {
51
77
  alert("An error occurred while correcting orthography.");
52
78
  }
53
79
  }
80
+
81
+
82
+ async calculateExpression(trixEditor) {
83
+ try {
84
+ const editor = trixEditor.editor;
85
+ const content = editor.getDocument().toString(); // Get the current content
86
+
87
+ // Send the content to the backend for correction
88
+ const response = await fetch("/trix_genius/calculate_expression", {
89
+ method: "POST",
90
+ headers: { "Content-Type": "application/json" },
91
+ body: JSON.stringify({ text: content }),
92
+ });
93
+
94
+ if (!response.ok) {
95
+ throw new Error("Network response was not ok");
96
+ }
97
+
98
+ const result = await response.json();
99
+ editor.loadHTML(result.calculus.replace(/\n/g, "<br>"));
100
+
101
+ } catch (error) {
102
+ console.error("Error Calculate Expressions:", error);
103
+ alert("An error occurred while calculate expression.");
104
+ }
105
+ }
54
106
  }
107
+
@@ -2,6 +2,7 @@ Rails.application.routes.draw do
2
2
 
3
3
  # TrixGenius: Auto-added route
4
4
  post "/trix_genius/correct_spelling", to: "trix_genius#correct_spelling"
5
+ post "trix_genius/calculate_expression", to: "trix_genius#calculate_expression"
5
6
  resources :posts
6
7
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
7
8
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trix-genius
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Giménez Silva Germán Alberto https://rubystacknews.com/
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-11 00:00:00.000000000 Z
10
+ date: 2025-04-15 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -71,6 +71,20 @@ dependencies:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
73
  version: '2.12'
74
+ - !ruby/object:Gem::Dependency
75
+ name: yaml
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ type: :runtime
82
+ prerelease: false
83
+ version_requirements: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
74
88
  - !ruby/object:Gem::Dependency
75
89
  name: rspec
76
90
  requirement: !ruby/object:Gem::Requirement
@@ -100,7 +114,7 @@ dependencies:
100
114
  - !ruby/object:Gem::Version
101
115
  version: '3.0'
102
116
  description: Trix-Genius adds AI-powered buttons and other custom controls to Trix
103
- editor using Stimulus.
117
+ editor using Stimulus. https://rubystacknews.com/
104
118
  email: ggerman@gmail.com
105
119
  executables: []
106
120
  extensions: []
@@ -112,6 +126,7 @@ files:
112
126
  - lib/generators/trix_genius/install/templates/trix_genius_controller.rb
113
127
  - lib/trix-genius.rb
114
128
  - lib/trix_genius/engine.rb
129
+ - lib/trix_genius/flexible_injector.rb
115
130
  - spec/generators/trix_genius/install/install_generator_spec.rb
116
131
  - spec/spec_helper.rb
117
132
  - spec/tmp/dummy_app/app/controllers/trix_genius_controller.rb