embeddable_content 0.3.2 → 0.4.0.beta7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +2 -1
- data/app/assets/javascripts/geogebra/support.js +1 -0
- data/app/services/embeddable_content/doc_processor.rb +10 -3
- data/app/services/embeddable_content/embedder.rb +1 -1
- data/app/services/embeddable_content/has_moveable_nodes.rb +69 -0
- data/app/services/embeddable_content/images/doc_processor.rb +6 -28
- data/app/services/embeddable_content/presentation_tags/node_processor.rb +29 -1
- data/app/services/embeddable_content/tex/base_renderer.rb +31 -89
- data/app/services/embeddable_content/tex/canvas_renderer.rb +36 -4
- data/app/services/embeddable_content/tex/doc_processor.rb +11 -34
- data/app/services/embeddable_content/tex/mathjax_renderer.rb +8 -2
- data/app/services/embeddable_content/tex/mml_renderer.rb +17 -4
- data/app/services/embeddable_content/tex/svg_renderer.rb +12 -4
- data/app/services/embeddable_content/tex/uri_encode_component.rb +175 -0
- data/app/services/embeddable_content/video_links/doc_processor.rb +13 -1
- data/app/views/embeddable_content/replacements/images/_modal_content.html.slim +2 -2
- data/app/views/embeddable_content/replacements/video_links/_video_embed.html.slim +1 -1
- data/lib/embeddable_content/version.rb +1 -1
- metadata +9 -9
- data/app/services/embeddable_content/tex/schoology_string_renderer.rb +0 -15
- data/app/services/mathjax/api/client.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f519e66cbe92ede8252b5e6c02c619c7f7db67ca24d989c5f3aac51a863ea7d3
|
4
|
+
data.tar.gz: de2e69dd5b55b60946677e5ac5f0615926f90da9ef1f675f11e88ea52c90155d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 992589b5decacdf64748ca60472ff1037199c61742457de76816c1888301df318f01e03fe2d43fb067b5d893f5c83125d4ca1a4160062e5abe4a442ed6c607e7
|
7
|
+
data.tar.gz: a5c40a06797b30da08365563ba43ce7ef98058954290cd8b843f3571f3c01542e379125bf38666742c9a66c59c1ffd3d3895ba1cf62b49a97375ec2dec7a4ba1
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -70,5 +70,6 @@ $ gem push embeddable_content-0.2.0.gem
|
|
70
70
|
|
71
71
|
| Version | Changes |
|
72
72
|
| --- | --- |
|
73
|
+
| 0.4.0 | Adapt gem to make full use of TexExpression model.
|
73
74
|
| 0.3.1 | Meaningless change as I (EDC) experiment with gem host. |
|
74
|
-
| 0.2.0 | NIMAS export now using embedder for TeX. However, the embedder is not yet using the full TexExprssions
|
75
|
+
| 0.2.0 | NIMAS export now using embedder for TeX. However, the embedder is not yet using the full TexExprssions model. |
|
@@ -9,5 +9,6 @@ function loadGeogebraApplet(elmt) {
|
|
9
9
|
dataNode = elmt.getElementsByClassName('ggb-base-64-data')[0],
|
10
10
|
parameters = JSON.parse(dataNode.dataset['parameters']),
|
11
11
|
applet = new GGBApplet(parameters, '5.0');
|
12
|
+
applet.setHTML5Codebase('/GeoGebra/HTML5/5.0/web3d/');
|
12
13
|
applet.inject(container.id);
|
13
14
|
};
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module EmbeddableContent
|
2
2
|
class DocProcessor < EmbedderBase
|
3
|
-
|
3
|
+
include HasMoveableNodes
|
4
4
|
|
5
|
+
PROCESS_NODES_BY_DEFAULT = true
|
5
6
|
attr_reader :embedder
|
6
7
|
|
7
8
|
delegate :document, :html, :rebuild_document, to: :embedder
|
@@ -28,10 +29,16 @@ module EmbeddableContent
|
|
28
29
|
private
|
29
30
|
|
30
31
|
def refresh_html
|
31
|
-
html.replace document.
|
32
|
+
html.replace document.to_html
|
32
33
|
end
|
33
34
|
|
34
|
-
def pre_process
|
35
|
+
def pre_process
|
36
|
+
update_moveable_nodes if update_moveable_nodes?
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_moveable_nodes?
|
40
|
+
false
|
41
|
+
end
|
35
42
|
|
36
43
|
def process_matching_nodes
|
37
44
|
matching_nodes.each.with_index(1) { |node, idx| process_node(node, idx) }
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EmbeddableContent
|
4
|
+
module HasMoveableNodes
|
5
|
+
CSS_CLASS_MOVEABLE_NODE_RELOCATED = 'node-relocated-by-embedder'
|
6
|
+
CSS_CLASS_MOVEABLE_NODES_RELOCATED = 'nodes-relocated-by-embedder'
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def update_moveable_nodes?
|
11
|
+
false
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_moveable_nodes
|
15
|
+
moveable_nodes.each { |node| update_moveable_node node }
|
16
|
+
remove_affected_empty_nodes
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_affected_empty_nodes
|
20
|
+
relocated_moveable_nodes.each { |node| node.remove if node.content.blank? }
|
21
|
+
end
|
22
|
+
|
23
|
+
def update_moveable_node(moveable_node)
|
24
|
+
moveable_node.parent.tap do |parent_node|
|
25
|
+
moveable_node.add_class CSS_CLASS_MOVEABLE_NODE_RELOCATED
|
26
|
+
parent_node.add_class CSS_CLASS_MOVEABLE_NODES_RELOCATED
|
27
|
+
relocate_moveable_node moveable_node
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def relocate_moveable_node(_moveable_node)
|
32
|
+
raise 'define this method in including class'
|
33
|
+
end
|
34
|
+
|
35
|
+
def place_moveable_node_before_parent(moveable_node)
|
36
|
+
moveable_node.parent.tap do |parent_node|
|
37
|
+
parent_node.add_previous_sibling moveable_node
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def place_moveable_node_after_parent(moveable_node)
|
42
|
+
moveable_node.parent.tap do |parent_node|
|
43
|
+
parent_node.add_next_sibling moveable_node
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def moveable_nodes
|
48
|
+
@moveable_nodes ||= document.css moveable_node_selector
|
49
|
+
end
|
50
|
+
|
51
|
+
def relocated_moveable_nodes
|
52
|
+
@relocated_moveable_nodes ||= document.css(relocated_moveable_node_selector)
|
53
|
+
end
|
54
|
+
|
55
|
+
def relocated_moveable_node_selector
|
56
|
+
@relocated_moveable_node_selector ||=
|
57
|
+
"#{parent_node_selector}.#{CSS_CLASS_MOVEABLE_NODES_RELOCATED}"
|
58
|
+
end
|
59
|
+
|
60
|
+
DEFAULT_PARENT_NODE_SELECTOR = 'p'
|
61
|
+
def parent_node_selector
|
62
|
+
DEFAULT_PARENT_NODE_SELECTOR
|
63
|
+
end
|
64
|
+
|
65
|
+
def moveable_node_selector
|
66
|
+
@moveable_node_selector ||= "#{parent_node_selector} > #{node_selector}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -5,12 +5,14 @@ module EmbeddableContent
|
|
5
5
|
class DocProcessor < EmbeddableContent::DocProcessor
|
6
6
|
delegate :image_catalog, to: :embedder
|
7
7
|
|
8
|
-
CLASS_IMG_TAG_RELOCATED = 'img-tag-relocated-by-embedder'
|
9
|
-
|
10
8
|
private
|
11
9
|
|
12
|
-
def
|
13
|
-
|
10
|
+
def update_moveable_nodes?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def relocate_moveable_node(moveable_node)
|
15
|
+
place_moveable_node_before_parent moveable_node
|
14
16
|
end
|
15
17
|
|
16
18
|
def post_process
|
@@ -25,30 +27,6 @@ module EmbeddableContent
|
|
25
27
|
def node_selector
|
26
28
|
'img'
|
27
29
|
end
|
28
|
-
|
29
|
-
def move_img_tags_out_from_p_tags
|
30
|
-
img_tags_inside_p_tags.each do |img_tag|
|
31
|
-
move_img_tag_out_from_p_tag img_tag
|
32
|
-
end
|
33
|
-
remove_affected_empty_p_tags
|
34
|
-
end
|
35
|
-
|
36
|
-
def remove_affected_empty_p_tags
|
37
|
-
document.css("p.#{CLASS_IMG_TAG_RELOCATED}").each do |p_tag|
|
38
|
-
remove_if_empty p_tag
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def move_img_tag_out_from_p_tag(img_tag)
|
43
|
-
img_tag.parent.tap do |p_tag|
|
44
|
-
p_tag.add_previous_sibling img_tag
|
45
|
-
p_tag.add_class CLASS_IMG_TAG_RELOCATED
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def img_tags_inside_p_tags
|
50
|
-
@img_tags_inside_p_tags ||= document.css 'p > img'
|
51
|
-
end
|
52
30
|
end
|
53
31
|
end
|
54
32
|
end
|
@@ -15,7 +15,35 @@ module EmbeddableContent
|
|
15
15
|
delegate :template_based?, to: :presentation_tag
|
16
16
|
|
17
17
|
def replace_node
|
18
|
-
template_based? ?
|
18
|
+
template_based? ? place_node : modify_parent
|
19
|
+
end
|
20
|
+
|
21
|
+
def place_node
|
22
|
+
if node_in_p_tag?
|
23
|
+
add_empty_p_tag_for_pre_mjpage_compatibility
|
24
|
+
place_node_after_parent_node
|
25
|
+
else
|
26
|
+
place_node_within_parent_node
|
27
|
+
end
|
28
|
+
remove_node
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def place_node_after_parent_node
|
33
|
+
parent_node.add_next_sibling replacement_node
|
34
|
+
end
|
35
|
+
|
36
|
+
def place_node_within_parent_node
|
37
|
+
parent_node << replacement_node
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_empty_p_tag_for_pre_mjpage_compatibility
|
41
|
+
parent_node
|
42
|
+
.add_next_sibling '<p class="empty-p-tag-added-for-pre-mjpage-compatability"></p>'
|
43
|
+
end
|
44
|
+
|
45
|
+
def node_in_p_tag?
|
46
|
+
parent_node&.name == 'p'
|
19
47
|
end
|
20
48
|
|
21
49
|
def modify_parent
|
@@ -1,124 +1,66 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
1
|
module EmbeddableContent
|
4
2
|
module Tex
|
5
|
-
class RenderError < StandardError
|
6
|
-
attr_reader :script, :stderr, :status
|
7
|
-
|
8
|
-
def initialize(script, stderr, status, api_errors)
|
9
|
-
@script = script
|
10
|
-
@stderr = stderr
|
11
|
-
@status = status
|
12
|
-
super "Unable to resolve error raised calling #{script}: #{status}\n#{stderr}\n#{api_errors}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
3
|
class BaseRenderer
|
17
|
-
|
4
|
+
attr_reader :document, :math_span
|
18
5
|
|
19
|
-
|
6
|
+
delegate :displaystyle?, :mathjax, :mml, :svg, :tex_string, :unadorned_tex_string,
|
7
|
+
to: :tex_expression
|
20
8
|
|
21
|
-
def initialize(
|
22
|
-
@
|
9
|
+
def initialize(math_span, document)
|
10
|
+
@math_span = math_span
|
11
|
+
@document = document
|
23
12
|
end
|
24
13
|
|
25
14
|
def render
|
26
|
-
|
27
|
-
|
28
|
-
run_script
|
15
|
+
rendered_node
|
29
16
|
end
|
30
17
|
|
31
18
|
private
|
32
19
|
|
33
|
-
def
|
34
|
-
|
20
|
+
def rendered_node
|
21
|
+
@rendered_node ||= math_span.replace replacement
|
35
22
|
end
|
36
23
|
|
37
|
-
def
|
38
|
-
|
24
|
+
def replacement
|
25
|
+
@replacement ||= base_replacement_span.then { |node| node << math_node }
|
39
26
|
end
|
40
27
|
|
41
|
-
def
|
42
|
-
|
28
|
+
def math_node
|
29
|
+
@math_node ||= math_content_node
|
43
30
|
end
|
44
31
|
|
45
|
-
def
|
46
|
-
|
32
|
+
def math_content_node
|
33
|
+
@math_content_node ||= Nokogiri::HTML.fragment(math_content).children.first
|
47
34
|
end
|
48
35
|
|
49
|
-
def
|
50
|
-
@
|
51
|
-
|
52
|
-
|
53
|
-
def run_script
|
54
|
-
@run_script ||= Open3.capture3(script, stdin_data: html).tap do |stdout, stderr, status|
|
55
|
-
@stdout = stdout
|
56
|
-
@stderr = stderr
|
57
|
-
@status = status
|
36
|
+
def base_replacement_span
|
37
|
+
@base_replacement_span ||= blank_span.then do |span|
|
38
|
+
span['class'] = replacement_css_classes if replacement_css_classes.present?
|
39
|
+
span
|
58
40
|
end
|
59
|
-
render_failed? ? try_api_client : html.replace(stdout)
|
60
|
-
end
|
61
|
-
|
62
|
-
def script
|
63
|
-
@script ||= [RENDER_TEX_JS_PATH, '--output', target_format].join(' ')
|
64
|
-
end
|
65
|
-
|
66
|
-
REGEX_TEX_STRING = /Formula\s+(?<texstring>.*)\s+contains the following errors:/.freeze
|
67
|
-
def offending_tex_string
|
68
|
-
@offending_tex_string ||= REGEX_TEX_STRING.match(stderr)[:texstring].strip if
|
69
|
-
stderr.present?
|
70
41
|
end
|
71
42
|
|
72
|
-
def
|
73
|
-
|
43
|
+
def blank_span
|
44
|
+
Nokogiri::XML::Node.new('span', document)
|
74
45
|
end
|
75
46
|
|
76
|
-
def
|
77
|
-
|
47
|
+
def replacement_css_classes
|
48
|
+
''
|
78
49
|
end
|
79
50
|
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
def try_api_client
|
85
|
-
raise render_error if offending_node.blank?
|
86
|
-
raise render_error unless api_client.success?
|
87
|
-
|
88
|
-
offending_node.content = ''
|
89
|
-
offending_node.add_child repaired_content
|
90
|
-
renderer_for_repaired_document.render
|
91
|
-
end
|
92
|
-
|
93
|
-
def renderer_for_repaired_document
|
94
|
-
@renderer_for_repaired_document ||=
|
95
|
-
self.class.new html.replace(document.to_html)
|
96
|
-
end
|
97
|
-
|
98
|
-
def repaired_span
|
99
|
-
@repaired_span = %w[<span class="mathjax-api"></span>].tap do |span|
|
100
|
-
span << repaired_content
|
51
|
+
def emptied_math_span
|
52
|
+
@emptied_math_span ||= math_span.dup.then do |empty_span|
|
53
|
+
empty_span.content = ''
|
54
|
+
math_span.replace empty_span
|
101
55
|
end
|
102
56
|
end
|
103
57
|
|
104
|
-
def
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
def api_client
|
109
|
-
@api_client ||= Mathjax::Api::Client.new offending_tex_string
|
58
|
+
def first_build_math_node
|
59
|
+
math_node
|
110
60
|
end
|
111
61
|
|
112
|
-
def
|
113
|
-
@
|
114
|
-
all_spans.detect { |node| offending_tex_appears_in?(node) }
|
115
|
-
end
|
116
|
-
|
117
|
-
REGEX_NODE_TEX_CONTENT = /\\\(\s*(?<tex_string>.*)\s*\\\)/m.freeze
|
118
|
-
def offending_tex_appears_in?(node)
|
119
|
-
node.content.match(REGEX_NODE_TEX_CONTENT).then do |md|
|
120
|
-
md.present? && md[:tex_string]&.strip.eql?(offending_tex_string)
|
121
|
-
end
|
62
|
+
def tex_expression
|
63
|
+
@tex_expression ||= TexExpression.for_math_span math_span
|
122
64
|
end
|
123
65
|
end
|
124
66
|
end
|
@@ -1,14 +1,46 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
1
|
module EmbeddableContent
|
4
2
|
module Tex
|
5
3
|
class CanvasRenderer < BaseRenderer
|
4
|
+
require 'embeddable_content/tex/uri_encode_component'
|
5
|
+
|
6
6
|
def target_format
|
7
7
|
:canvas
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
#################################################
|
11
|
+
# EDC: this is the way Canvas likes things done #
|
12
|
+
#################################################
|
13
|
+
def math_node
|
14
|
+
@math_node ||= Nokogiri::XML::Node.new('img', document).tap do |node|
|
15
|
+
node['class'] = 'equation_image'
|
16
|
+
node['title'] = unadorned_tex_string
|
17
|
+
node['src'] = expression_uri
|
18
|
+
node['alt'] = alt_expression
|
19
|
+
node['data-equation-content'] = unadorned_tex_string
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def rendered_node
|
24
|
+
@rendered_node ||= emptied_math_span.then { |span| span << math_node }
|
25
|
+
end
|
26
|
+
|
27
|
+
def base_replacement_span
|
28
|
+
@base_replacement_span ||= blank_span.tap do |span|
|
29
|
+
span['class'] = 'math'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def alt_expression
|
34
|
+
@alt_expression ||= "LaTeX: #{unadorned_tex_string}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def expression_uri
|
38
|
+
@expression_uri ||= "/equation_images/#{doubly_encoded_expression}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def doubly_encoded_expression
|
42
|
+
@doubly_encoded_expression ||=
|
43
|
+
encodeURIComponent encodeURIComponent unadorned_tex_string
|
12
44
|
end
|
13
45
|
end
|
14
46
|
end
|
@@ -1,54 +1,31 @@
|
|
1
1
|
module EmbeddableContent
|
2
2
|
module Tex
|
3
3
|
class DocProcessor < EmbeddableContent::DocProcessor
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
delegate :remove_repaired_math_spans?, to: :embedder
|
4
|
+
delegate :remove_repaired_math_spans?, :tex_output_format,
|
5
|
+
to: :embedder
|
8
6
|
|
9
7
|
private
|
10
8
|
|
11
|
-
def process_nodes?
|
12
|
-
remove_repaired_math_spans?
|
13
|
-
end
|
14
|
-
|
15
9
|
def process_node(node, _node_index)
|
16
|
-
|
10
|
+
tex_renderer_for_node(node).render
|
17
11
|
end
|
18
12
|
|
13
|
+
# TODO: resolve this --- still needed?
|
19
14
|
def remove_repaired_math_span(node)
|
20
|
-
node.replace node.content
|
21
|
-
end
|
22
|
-
|
23
|
-
def post_process
|
24
|
-
refresh_html
|
25
|
-
render_tex
|
26
|
-
fix_mml_fragments if fix_mml_fragments?
|
27
|
-
rebuild_document
|
15
|
+
# node.replace node.content
|
28
16
|
end
|
29
17
|
|
30
18
|
def node_selector
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
def repaired_math_nodes
|
35
|
-
@repaired_math_nodes ||= document.css(REPAIRED_MATH_CSS_SELECTOR)
|
36
|
-
end
|
37
|
-
|
38
|
-
def render_tex
|
39
|
-
tex_renderer.new(html).render
|
40
|
-
end
|
41
|
-
|
42
|
-
def fix_mml_fragments?
|
43
|
-
embedder.fragment? && embedder.xml?
|
19
|
+
Mathjax::Config::MATH_SPAN_SELECTOR
|
44
20
|
end
|
45
21
|
|
46
|
-
def
|
47
|
-
|
22
|
+
def tex_renderer_for_node(node)
|
23
|
+
tex_renderer_class.new node, document
|
48
24
|
end
|
49
25
|
|
50
|
-
def
|
51
|
-
|
26
|
+
def tex_renderer_class
|
27
|
+
@tex_renderer_class ||=
|
28
|
+
"#{module_name}::#{tex_output_format.classify}Renderer".constantize
|
52
29
|
end
|
53
30
|
end
|
54
31
|
end
|
@@ -1,10 +1,23 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
1
|
module EmbeddableContent
|
4
2
|
module Tex
|
5
3
|
class MmlRenderer < BaseRenderer
|
6
|
-
|
7
|
-
|
4
|
+
private
|
5
|
+
|
6
|
+
# TODO: update this once embedder specs working
|
7
|
+
def replacement_css_classes
|
8
|
+
@replacement_css_classes ||=
|
9
|
+
displaystyle? ? 'mjpage mjpage__block' : 'mjpage'
|
10
|
+
end
|
11
|
+
|
12
|
+
def math_content
|
13
|
+
mml
|
14
|
+
end
|
15
|
+
|
16
|
+
def math_node
|
17
|
+
super.tap do |node|
|
18
|
+
node['display'] = 'block' if displaystyle?
|
19
|
+
node['alttext'] = unadorned_tex_string
|
20
|
+
end
|
8
21
|
end
|
9
22
|
end
|
10
23
|
end
|
@@ -1,10 +1,18 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
1
|
module EmbeddableContent
|
4
2
|
module Tex
|
5
3
|
class SvgRenderer < BaseRenderer
|
6
|
-
|
7
|
-
|
4
|
+
private
|
5
|
+
|
6
|
+
def rendered_node
|
7
|
+
@rendered_node ||= emptied_math_span.then { |span| span << math_node }
|
8
|
+
end
|
9
|
+
|
10
|
+
def math_content
|
11
|
+
svg
|
12
|
+
end
|
13
|
+
|
14
|
+
def base_replacement_span
|
15
|
+
emptied_math_span
|
8
16
|
end
|
9
17
|
end
|
10
18
|
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# edc: see
|
2
|
+
# https://github.com/bootstraponline/encodeURIComponent_ruby/blob/master/uri_encode_component.rb
|
3
|
+
|
4
|
+
=begin
|
5
|
+
Copyright 2006-2008 the V8 project authors. All rights reserved.
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are
|
8
|
+
met:
|
9
|
+
|
10
|
+
* Redistributions of source code must retain the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer.
|
12
|
+
* Redistributions in binary form must reproduce the above
|
13
|
+
copyright notice, this list of conditions and the following
|
14
|
+
disclaimer in the documentation and/or other materials provided
|
15
|
+
with the distribution.
|
16
|
+
* Neither the name of Google Inc. nor the names of its
|
17
|
+
contributors may be used to endorse or promote products derived
|
18
|
+
from this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
24
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
25
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
26
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
28
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
29
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
=end
|
32
|
+
|
33
|
+
# This file provides the following methods:
|
34
|
+
# encodeURIComponent(componentString)
|
35
|
+
# string.charCodeAt(k)
|
36
|
+
|
37
|
+
# component must be String
|
38
|
+
def encodeURIComponent(componentString)
|
39
|
+
URI::URIEncodeComponent(componentString)
|
40
|
+
end
|
41
|
+
|
42
|
+
# define charCodeAt on String
|
43
|
+
class String
|
44
|
+
def charCodeAt(k)
|
45
|
+
return self[k].ord
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
module URI; class << self
|
50
|
+
# Does the char code correspond to an alpha-numeric char.
|
51
|
+
# isAlphaNumeric('a'.ord) => true
|
52
|
+
# isAlphaNumeric(''.ord) => false
|
53
|
+
def isAlphaNumeric(cc)
|
54
|
+
# a - z
|
55
|
+
if (97 <= cc && cc <= 122); return true end
|
56
|
+
# A - Z
|
57
|
+
if (65 <= cc && cc <= 90); return true end
|
58
|
+
# 0 - 9
|
59
|
+
if (48 <= cc && cc <= 57); return true end
|
60
|
+
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
|
64
|
+
def unescapePredicate(cc)
|
65
|
+
if (isAlphaNumeric(cc)); return true end
|
66
|
+
# !
|
67
|
+
if (cc == 33); return true end
|
68
|
+
# '()*
|
69
|
+
if (39 <= cc && cc <= 42); return true end
|
70
|
+
# -.
|
71
|
+
if (45 <= cc && cc <= 46); return true end
|
72
|
+
# _
|
73
|
+
if (cc == 95); return true end
|
74
|
+
# ~
|
75
|
+
if (cc == 126); return true end
|
76
|
+
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
|
80
|
+
def URIEncodeSingle(cc, result, index)
|
81
|
+
x = (cc >> 12) & 0xF;
|
82
|
+
y = (cc >> 6) & 63;
|
83
|
+
z = cc & 63;
|
84
|
+
octets = Array.new(3);
|
85
|
+
if (cc <= 0x007F)
|
86
|
+
octets[0] = cc;
|
87
|
+
elsif (cc <= 0x07FF)
|
88
|
+
octets[0] = y + 192;
|
89
|
+
octets[1] = z + 128;
|
90
|
+
else
|
91
|
+
octets[0] = x + 224;
|
92
|
+
octets[1] = y + 128;
|
93
|
+
octets[2] = z + 128;
|
94
|
+
end
|
95
|
+
return URIEncodeOctets(octets, result, index);
|
96
|
+
end
|
97
|
+
|
98
|
+
# Lazily initialized.
|
99
|
+
@@hexCharCodeArray = 0;
|
100
|
+
|
101
|
+
def URIAddEncodedOctetToBuffer(octet, result, index)
|
102
|
+
result[index] = 37; # Char code of '%'.
|
103
|
+
index += 1
|
104
|
+
result[index] = @@hexCharCodeArray[octet >> 4];
|
105
|
+
index += 1
|
106
|
+
result[index] = @@hexCharCodeArray[octet & 0x0F];
|
107
|
+
index += 1
|
108
|
+
return index;
|
109
|
+
end
|
110
|
+
|
111
|
+
def URIEncodeOctets(octets, result, index)
|
112
|
+
if (@@hexCharCodeArray == 0)
|
113
|
+
@@hexCharCodeArray = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
114
|
+
65, 66, 67, 68, 69, 70];
|
115
|
+
end
|
116
|
+
index = URIAddEncodedOctetToBuffer(octets[0], result, index);
|
117
|
+
if (octets[1]); index = URIAddEncodedOctetToBuffer(octets[1], result, index) end
|
118
|
+
if (octets[2]); index = URIAddEncodedOctetToBuffer(octets[2], result, index) end
|
119
|
+
if (octets[3]); index = URIAddEncodedOctetToBuffer(octets[3], result, index) end
|
120
|
+
return index;
|
121
|
+
end
|
122
|
+
|
123
|
+
def URIEncodePair(cc1 , cc2, result, index)
|
124
|
+
u = ((cc1 >> 6) & 0xF) + 1;
|
125
|
+
w = (cc1 >> 2) & 0xF;
|
126
|
+
x = cc1 & 3;
|
127
|
+
y = (cc2 >> 6) & 0xF;
|
128
|
+
z = cc2 & 63;
|
129
|
+
octets = Array.new(4);
|
130
|
+
octets[0] = (u >> 2) + 240;
|
131
|
+
octets[1] = (((u & 3) << 4) | w) + 128;
|
132
|
+
octets[2] = ((x << 4) | y) + 128;
|
133
|
+
octets[3] = z + 128;
|
134
|
+
return URIEncodeOctets(octets, result, index);
|
135
|
+
end
|
136
|
+
|
137
|
+
# component must be String
|
138
|
+
def URIEncodeComponent(componentString)
|
139
|
+
Encode(componentString, :unescapePredicate);
|
140
|
+
end
|
141
|
+
|
142
|
+
# ECMA-262, section 15.1.3
|
143
|
+
def Encode(uri, unescape)
|
144
|
+
uriLength = uri.length;
|
145
|
+
# We are going to pass result to %StringFromCharCodeArray
|
146
|
+
# which does not expect any getters/setters installed
|
147
|
+
# on the incoming array.
|
148
|
+
result = Array.new(uriLength);
|
149
|
+
index = 0;
|
150
|
+
k = -1;
|
151
|
+
while ((k+=1) < uriLength) do
|
152
|
+
cc1 = uri.charCodeAt(k);
|
153
|
+
if (self.send(unescape, cc1))
|
154
|
+
result[index] = cc1;
|
155
|
+
index += 1
|
156
|
+
else
|
157
|
+
if (cc1 >= 0xDC00 && cc1 <= 0xDFFF); throw("URI malformed") end
|
158
|
+
if (cc1 < 0xD800 || cc1 > 0xDBFF)
|
159
|
+
index = URIEncodeSingle(cc1, result, index);
|
160
|
+
else
|
161
|
+
k+=1;
|
162
|
+
if (k == uriLength); throw("URI malformed") end
|
163
|
+
cc2 = uri.charCodeAt(k);
|
164
|
+
if (cc2 < 0xDC00 || cc2 > 0xDFFF); throw("URI malformed") end
|
165
|
+
index = URIEncodePair(cc1, cc2, result, index);
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
# return %StringFromCharCodeArray(result);
|
170
|
+
# 'c' = 8 bit signed char
|
171
|
+
# http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-pack
|
172
|
+
return result.pack 'c*'
|
173
|
+
end
|
174
|
+
end # class << self
|
175
|
+
end # module
|
@@ -1,5 +1,17 @@
|
|
1
1
|
module EmbeddableContent
|
2
2
|
module VideoLinks
|
3
|
-
class DocProcessor < EmbeddableContent::DocProcessor
|
3
|
+
class DocProcessor < EmbeddableContent::DocProcessor
|
4
|
+
TARGETS_FOR_WHICH_NODES_ARE_UNMOVEABLE = %i[cms exported kiddom web].freeze
|
5
|
+
|
6
|
+
def update_moveable_nodes?
|
7
|
+
TARGETS_FOR_WHICH_NODES_ARE_UNMOVEABLE.exclude? target
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def relocate_moveable_node(moveable_node)
|
13
|
+
place_moveable_node_after_parent moveable_node
|
14
|
+
end
|
15
|
+
end
|
4
16
|
end
|
5
17
|
end
|
@@ -15,7 +15,7 @@ div.im-c-modal__content.im-c-content
|
|
15
15
|
- if description.present?
|
16
16
|
p
|
17
17
|
strong> Description:
|
18
|
-
|
18
|
+
== description
|
19
19
|
img *img_tag_attrs
|
20
20
|
- if caption.present?
|
21
21
|
p id = caption_id
|
@@ -24,7 +24,7 @@ div.im-c-modal__content.im-c-content
|
|
24
24
|
- if attribution.present?
|
25
25
|
p id = attribution_id
|
26
26
|
strong> Attribution:
|
27
|
-
|
27
|
+
==> modal_dialog.attribution_display_text
|
28
28
|
a href = attribution.original_url
|
29
29
|
| Source
|
30
30
|
| .
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embeddable_content
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0.beta7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Connally
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -175,6 +175,7 @@ files:
|
|
175
175
|
- app/services/embeddable_content/fragment_embedder.rb
|
176
176
|
- app/services/embeddable_content/geogebra_files/doc_processor.rb
|
177
177
|
- app/services/embeddable_content/geogebra_files/node_processor.rb
|
178
|
+
- app/services/embeddable_content/has_moveable_nodes.rb
|
178
179
|
- app/services/embeddable_content/html_tags/doc_processor.rb
|
179
180
|
- app/services/embeddable_content/html_tags/node_processor.rb
|
180
181
|
- app/services/embeddable_content/images/attributions_processor.rb
|
@@ -198,8 +199,8 @@ files:
|
|
198
199
|
- app/services/embeddable_content/tex/doc_processor.rb
|
199
200
|
- app/services/embeddable_content/tex/mathjax_renderer.rb
|
200
201
|
- app/services/embeddable_content/tex/mml_renderer.rb
|
201
|
-
- app/services/embeddable_content/tex/schoology_string_renderer.rb
|
202
202
|
- app/services/embeddable_content/tex/svg_renderer.rb
|
203
|
+
- app/services/embeddable_content/tex/uri_encode_component.rb
|
203
204
|
- app/services/embeddable_content/token_replacement_map.rb
|
204
205
|
- app/services/embeddable_content/tree_based_node_processor.rb
|
205
206
|
- app/services/embeddable_content/video_links/doc_processor.rb
|
@@ -208,7 +209,6 @@ files:
|
|
208
209
|
- app/services/embeddable_content/visual_element_node_processor.rb
|
209
210
|
- app/services/embeddable_content/widget_files/doc_processor.rb
|
210
211
|
- app/services/embeddable_content/widget_files/node_processor.rb
|
211
|
-
- app/services/mathjax/api/client.rb
|
212
212
|
- app/views/.keep
|
213
213
|
- app/views/embeddable_content/replacements/desmos_files/_applet.html.slim
|
214
214
|
- app/views/embeddable_content/replacements/desmos_files/_description.html.slim
|
@@ -286,7 +286,7 @@ files:
|
|
286
286
|
homepage: https://github.com/illustrativemathematics/embedded_content
|
287
287
|
licenses: []
|
288
288
|
metadata: {}
|
289
|
-
post_install_message:
|
289
|
+
post_install_message:
|
290
290
|
rdoc_options: []
|
291
291
|
require_paths:
|
292
292
|
- lib
|
@@ -298,12 +298,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
298
298
|
version: '0'
|
299
299
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
300
300
|
requirements:
|
301
|
-
- - "
|
301
|
+
- - ">"
|
302
302
|
- !ruby/object:Gem::Version
|
303
|
-
version:
|
303
|
+
version: 1.3.1
|
304
304
|
requirements: []
|
305
305
|
rubygems_version: 3.0.3
|
306
|
-
signing_key:
|
306
|
+
signing_key:
|
307
307
|
specification_version: 4
|
308
308
|
summary: Embeddable Content functionality extracted from cms-im app.
|
309
309
|
test_files: []
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'open3'
|
2
|
-
|
3
|
-
module EmbeddableContent
|
4
|
-
module Tex
|
5
|
-
class SchoologyStringRenderer < BaseRenderer
|
6
|
-
def target_format
|
7
|
-
:schoology_string
|
8
|
-
end
|
9
|
-
|
10
|
-
def render_format(_format)
|
11
|
-
Mathjax::SchoologyStringRenderer.new(html).render
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|