openstax_kitchen 1.0.0
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 +7 -0
- data/.devcontainer/devcontainer.json +19 -0
- data/.github/workflows/tests.yml +36 -0
- data/.gitignore +20 -0
- data/.rspec +3 -0
- data/.solargraph.yml +15 -0
- data/CHANGELOG.md +11 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Dockerfile +19 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +674 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/normalize +79 -0
- data/bin/setup +8 -0
- data/books/chemistry2e/bake.rb +133 -0
- data/codecov.yaml +27 -0
- data/docker-compose.yml +12 -0
- data/docker/bash +1 -0
- data/docker/entrypoint +9 -0
- data/lib/kitchen.rb +57 -0
- data/lib/kitchen/ancestor.rb +30 -0
- data/lib/kitchen/book_document.rb +18 -0
- data/lib/kitchen/book_element.rb +24 -0
- data/lib/kitchen/book_element_enumerator.rb +5 -0
- data/lib/kitchen/book_recipe.rb +25 -0
- data/lib/kitchen/chapter_element.rb +35 -0
- data/lib/kitchen/chapter_element_enumerator.rb +13 -0
- data/lib/kitchen/clipboard.rb +37 -0
- data/lib/kitchen/composite_chapter_element.rb +23 -0
- data/lib/kitchen/composite_page_element.rb +27 -0
- data/lib/kitchen/composite_page_element_enumerator.rb +13 -0
- data/lib/kitchen/config.rb +20 -0
- data/lib/kitchen/counter.rb +34 -0
- data/lib/kitchen/debug/print_recipe_error.rb +80 -0
- data/lib/kitchen/directions/bake_appendix.rb +26 -0
- data/lib/kitchen/directions/bake_chapter_glossary.rb +34 -0
- data/lib/kitchen/directions/bake_chapter_introductions.rb +58 -0
- data/lib/kitchen/directions/bake_chapter_key_equations.rb +30 -0
- data/lib/kitchen/directions/bake_chapter_summary.rb +52 -0
- data/lib/kitchen/directions/bake_composite_pages.rb +13 -0
- data/lib/kitchen/directions/bake_example.rb +31 -0
- data/lib/kitchen/directions/bake_exercises.rb +164 -0
- data/lib/kitchen/directions/bake_figure.rb +25 -0
- data/lib/kitchen/directions/bake_footnotes/main.rb +11 -0
- data/lib/kitchen/directions/bake_footnotes/v1.rb +38 -0
- data/lib/kitchen/directions/bake_index/main.rb +11 -0
- data/lib/kitchen/directions/bake_index/v1.rb +138 -0
- data/lib/kitchen/directions/bake_index/v1.xhtml.erb +28 -0
- data/lib/kitchen/directions/bake_math_in_paragraph.rb +13 -0
- data/lib/kitchen/directions/bake_notes.rb +58 -0
- data/lib/kitchen/directions/bake_numbered_table/main.rb +11 -0
- data/lib/kitchen/directions/bake_numbered_table/v1.rb +47 -0
- data/lib/kitchen/directions/bake_stepwise.rb +27 -0
- data/lib/kitchen/directions/bake_toc.rb +103 -0
- data/lib/kitchen/directions/bake_unnumbered_tables.rb +14 -0
- data/lib/kitchen/directions/move_title_text_into_span.rb +15 -0
- data/lib/kitchen/document.rb +142 -0
- data/lib/kitchen/element.rb +15 -0
- data/lib/kitchen/element_base.rb +444 -0
- data/lib/kitchen/element_enumerator.rb +12 -0
- data/lib/kitchen/element_enumerator_base.rb +101 -0
- data/lib/kitchen/element_enumerator_factory.rb +111 -0
- data/lib/kitchen/element_factory.rb +32 -0
- data/lib/kitchen/errors.rb +4 -0
- data/lib/kitchen/example_element.rb +20 -0
- data/lib/kitchen/example_element_enumerator.rb +13 -0
- data/lib/kitchen/figure_element.rb +20 -0
- data/lib/kitchen/figure_element_enumerator.rb +13 -0
- data/lib/kitchen/mixins/block_error_if.rb +19 -0
- data/lib/kitchen/note_element.rb +43 -0
- data/lib/kitchen/note_element_enumerator.rb +13 -0
- data/lib/kitchen/oven.rb +61 -0
- data/lib/kitchen/page_element.rb +51 -0
- data/lib/kitchen/page_element_enumerator.rb +13 -0
- data/lib/kitchen/pantry.rb +35 -0
- data/lib/kitchen/patches/nokogiri.rb +31 -0
- data/lib/kitchen/patches/renderable.rb +31 -0
- data/lib/kitchen/patches/string.rb +5 -0
- data/lib/kitchen/recipe.rb +78 -0
- data/lib/kitchen/search_history.rb +33 -0
- data/lib/kitchen/selectors/base.rb +8 -0
- data/lib/kitchen/selectors/standard_1.rb +12 -0
- data/lib/kitchen/table_element.rb +36 -0
- data/lib/kitchen/table_element_enumerator.rb +13 -0
- data/lib/kitchen/term_element.rb +16 -0
- data/lib/kitchen/term_element_enumerator.rb +13 -0
- data/lib/kitchen/transliterations.rb +19 -0
- data/lib/kitchen/type_casting_element_enumerator.rb +23 -0
- data/lib/kitchen/utils.rb +19 -0
- data/lib/kitchen/version.rb +3 -0
- data/lib/locales/en.yml +21 -0
- data/lib/notes.md +9 -0
- data/openstax_kitchen.gemspec +39 -0
- data/tutorials/00/expected_baked.html +3 -0
- data/tutorials/00/raw.html +3 -0
- data/tutorials/00/solution_1.rb +7 -0
- data/tutorials/00/solution_2.rb +6 -0
- data/tutorials/01/expected_baked.html +66 -0
- data/tutorials/01/raw.html +62 -0
- data/tutorials/01/solution_1.rb +16 -0
- data/tutorials/01/solution_2.rb +24 -0
- data/tutorials/02/expected_baked.html +207 -0
- data/tutorials/02/raw.html +201 -0
- data/tutorials/02/solution_1.rb +29 -0
- data/tutorials/03/expected_baked.html +33 -0
- data/tutorials/03/raw.html +31 -0
- data/tutorials/03/solution_1.rb +16 -0
- data/tutorials/03/solution_2.rb +15 -0
- data/tutorials/04/expected_baked.html +36 -0
- data/tutorials/04/raw.html +36 -0
- data/tutorials/04/solution_1.rb +20 -0
- data/tutorials/04/solution_2.rb +25 -0
- data/tutorials/05/expected_baked.html +11 -0
- data/tutorials/05/raw.html +11 -0
- data/tutorials/05/solution_1.rb +9 -0
- data/tutorials/check_it +64 -0
- data/tutorials/setup_my_recipes +30 -0
- metadata +278 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
<div class="os-eob os-index-container " data-type="composite-page" data-uuid-key="index">
|
2
|
+
<h1 data-type="document-title">
|
3
|
+
<span class="os-text"><%= I18n.t(:eob_index_title) %></span>
|
4
|
+
</h1>
|
5
|
+
<div data-type="metadata" style="display: none;">
|
6
|
+
<h1 data-type="document-title" itemprop="name"><%= I18n.t(:eob_index_title) %></h1>
|
7
|
+
<%= @metadata_elements.paste %>
|
8
|
+
</div>
|
9
|
+
<% @index.sections.each do |section| %>
|
10
|
+
<div class="group-by">
|
11
|
+
<span class="group-label"><%= section.name %></span>
|
12
|
+
<% section.items.each do |item| %>
|
13
|
+
<div class="os-index-item">
|
14
|
+
<% item.terms.each_with_index do |term, ii| %>
|
15
|
+
<% if ii == 0 %>
|
16
|
+
<span class="os-term" group-by="<%= term.group_by %>"><%= term.text %></span>
|
17
|
+
<% else %>
|
18
|
+
<span class="os-index-link-separator">, </span>
|
19
|
+
<% end %>
|
20
|
+
<a class="os-term-section-link" href="#<%= term.id %>">
|
21
|
+
<span class="os-term-section"><%= term.page_title %></span>
|
22
|
+
</a>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Kitchen
|
2
|
+
module Directions
|
3
|
+
module BakeNotes
|
4
|
+
|
5
|
+
def self.v1(book:)
|
6
|
+
book.notes.each do |note|
|
7
|
+
title = note.title&.cut
|
8
|
+
|
9
|
+
note.replace_children(with:
|
10
|
+
<<~HTML
|
11
|
+
<div class="os-note-body">#{note.children}</div>
|
12
|
+
HTML
|
13
|
+
)
|
14
|
+
|
15
|
+
if title
|
16
|
+
if note.indicates_autogenerated_title?
|
17
|
+
note.prepend(child:
|
18
|
+
<<~HTML
|
19
|
+
<h3 class="os-title" data-type="title">
|
20
|
+
<span class="os-title-label">#{note.autogenerated_title}</span>
|
21
|
+
</h3>
|
22
|
+
HTML
|
23
|
+
)
|
24
|
+
|
25
|
+
title.name = "h4"
|
26
|
+
title.add_class("os-subtitle")
|
27
|
+
title.replace_children(with:
|
28
|
+
<<~HTML
|
29
|
+
<span class="os-subtitle-label">#{title.children}</span>
|
30
|
+
HTML
|
31
|
+
)
|
32
|
+
note.first!(".os-note-body").prepend(child: title.raw)
|
33
|
+
else
|
34
|
+
title.name = "h3"
|
35
|
+
title.add_class("os-title")
|
36
|
+
title.replace_children(with:
|
37
|
+
<<~HTML
|
38
|
+
<span data-type="" id="#{title.id}" class="os-title-label">#{title.children}</span>
|
39
|
+
HTML
|
40
|
+
)
|
41
|
+
title.remove_attribute("id")
|
42
|
+
note.prepend(child: title.raw)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
note.prepend(child:
|
46
|
+
<<~HTML
|
47
|
+
<h3 class="os-title" data-type="title">
|
48
|
+
<span class="os-title-label">#{note.autogenerated_title}</span>
|
49
|
+
</h3>
|
50
|
+
HTML
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Kitchen::Directions::BakeNumberedTable
|
2
|
+
class V1
|
3
|
+
|
4
|
+
def bake(table:, number:)
|
5
|
+
table.wrap(%Q(<div class="os-table">))
|
6
|
+
|
7
|
+
table_label = "#{I18n.t(:table_label)} #{number}"
|
8
|
+
table.document.pantry(name: :link_text).store table_label, label: table.id
|
9
|
+
|
10
|
+
if table.top_titled?
|
11
|
+
table.prepend(sibling:
|
12
|
+
<<~HTML
|
13
|
+
<div class="os-table-title">#{table.title}</div>
|
14
|
+
HTML
|
15
|
+
)
|
16
|
+
table.title_row.trash
|
17
|
+
end
|
18
|
+
|
19
|
+
# TODO extra spaces added here to match legacy implementation, but probably not meaningful?
|
20
|
+
new_summary = table_label + " "
|
21
|
+
new_caption = ""
|
22
|
+
|
23
|
+
if (caption = table.caption&.cut)
|
24
|
+
new_summary += caption.text
|
25
|
+
new_caption = <<~HTML
|
26
|
+
\n<span class="os-caption">#{caption.children}</span>
|
27
|
+
HTML
|
28
|
+
end
|
29
|
+
|
30
|
+
table[:summary] = new_summary
|
31
|
+
|
32
|
+
if !table.unnumbered?
|
33
|
+
table.append(sibling:
|
34
|
+
<<~HTML
|
35
|
+
<div class="os-caption-container">
|
36
|
+
<span class="os-title-label">#{I18n.t(:table_label)} </span>
|
37
|
+
<span class="os-number">#{number}</span>
|
38
|
+
<span class="os-divider"> </span>
|
39
|
+
<span class="os-divider"> </span>#{new_caption}
|
40
|
+
</div>
|
41
|
+
HTML
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Kitchen
|
2
|
+
module Directions
|
3
|
+
module BakeStepwise
|
4
|
+
|
5
|
+
def self.v1(book:)
|
6
|
+
book.search("ol.stepwise").each do |ol|
|
7
|
+
ol.remove_class("stepwise")
|
8
|
+
ol.add_class("os-stepwise")
|
9
|
+
|
10
|
+
ol.search("li").each_with_index do |li, ii|
|
11
|
+
li.replace_children(with:
|
12
|
+
<<~HTML
|
13
|
+
<span class="os-stepwise-content">#{li.children}</span>
|
14
|
+
HTML
|
15
|
+
)
|
16
|
+
li.prepend(child:
|
17
|
+
<<~HTML
|
18
|
+
<span class="os-stepwise-token">#{I18n.t(:stepwise_step_label)} #{ii+1}. </span>
|
19
|
+
HTML
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Kitchen
|
2
|
+
module Directions
|
3
|
+
module BakeToc
|
4
|
+
|
5
|
+
def self.v1(book:)
|
6
|
+
li_tags = book.body.element_children.map do |element|
|
7
|
+
case element
|
8
|
+
when ChapterElement
|
9
|
+
li_for_chapter(element)
|
10
|
+
when PageElement, CompositePageElement
|
11
|
+
li_for_page(element)
|
12
|
+
when CompositeChapterElement
|
13
|
+
li_for_composite_chapter(element)
|
14
|
+
end
|
15
|
+
end.compact.join("\n")
|
16
|
+
|
17
|
+
book.first!("nav").replace_children(with: <<~HTML
|
18
|
+
<h1 class="os-toc-title">Contents</h1>
|
19
|
+
<ol>
|
20
|
+
#{li_tags}
|
21
|
+
</ol>
|
22
|
+
HTML
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.li_for_composite_chapter(chapter)
|
27
|
+
pages = chapter.element_children.only(CompositePageElement)
|
28
|
+
|
29
|
+
<<~HTML
|
30
|
+
<li class="os-toc-composite-chapter" cnx-archive-shortid="" cnx-archive-uri="">
|
31
|
+
<a href="##{chapter.title.id}">
|
32
|
+
#{chapter.title.children.to_s}
|
33
|
+
</a>
|
34
|
+
<ol class="os-chapter">
|
35
|
+
#{pages.map{|page| li_for_page(page)}.join("\n")}
|
36
|
+
</ol>
|
37
|
+
</li>
|
38
|
+
HTML
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.li_for_chapter(chapter)
|
42
|
+
pages = chapter.element_children.only(PageElement, CompositePageElement)
|
43
|
+
|
44
|
+
<<~HTML
|
45
|
+
<li class="os-toc-chapter" cnx-archive-shortid="" cnx-archive-uri="">
|
46
|
+
<a href="##{chapter.title.id}">
|
47
|
+
<span class="os-number"><span class="os-part-text">Chapter </span>#{chapter.count_in(:book)}</span>
|
48
|
+
<span class="os-divider"> </span>
|
49
|
+
<span class="os-text" data-type="" itemprop="">#{chapter.title.first!(".os-text").text}</span>
|
50
|
+
</a>
|
51
|
+
<ol class="os-chapter">
|
52
|
+
#{pages.map{|page| li_for_page(page)}.join("\n")}
|
53
|
+
</ol>
|
54
|
+
</li>
|
55
|
+
HTML
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.li_for_page(page)
|
59
|
+
li_class =
|
60
|
+
if page.is_a?(PageElement)
|
61
|
+
if page.has_ancestor?(:chapter)
|
62
|
+
"os-toc-chapter-page"
|
63
|
+
elsif page.is_appendix?
|
64
|
+
"os-toc-appendix"
|
65
|
+
elsif page.is_preface?
|
66
|
+
"os-toc-preface"
|
67
|
+
else
|
68
|
+
raise "do not know what TOC class to use for page with classes #{page.classes}"
|
69
|
+
end
|
70
|
+
elsif page.is_a?(CompositePageElement)
|
71
|
+
if page.is_index?
|
72
|
+
"os-toc-index"
|
73
|
+
elsif page.has_ancestor?(:composite_chapter) || page.has_ancestor?(:chapter)
|
74
|
+
"os-toc-chapter-composite-page"
|
75
|
+
else
|
76
|
+
raise "do not know what TOC class to use for page with classes #{page.classes}"
|
77
|
+
end
|
78
|
+
else
|
79
|
+
raise(ArgumentError, "don't know how to put `#{page.class}` into the TOC")
|
80
|
+
end
|
81
|
+
|
82
|
+
title = page.title.copy
|
83
|
+
|
84
|
+
# The part text gets inserted as a child to the number span
|
85
|
+
part_text = title.first(".os-part-text")
|
86
|
+
number = title.first(".os-number")
|
87
|
+
if part_text && number
|
88
|
+
part_text = part_text.cut
|
89
|
+
number.prepend(child: part_text.paste)
|
90
|
+
end
|
91
|
+
|
92
|
+
<<~HTML
|
93
|
+
<li class="#{li_class}" cnx-archive-shortid="" cnx-archive-uri="#{page.id}">
|
94
|
+
<a href="##{page.id}">
|
95
|
+
#{title.element_children.copy.paste}
|
96
|
+
</a>
|
97
|
+
</li>
|
98
|
+
HTML
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Kitchen
|
4
|
+
class Document
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
attr_accessor :location
|
8
|
+
attr_reader :config
|
9
|
+
|
10
|
+
def_delegators :config, :selectors
|
11
|
+
def_delegators :@nokogiri_document, :to_xhtml, :to_s, :to_xml, :to_html
|
12
|
+
|
13
|
+
def initialize(nokogiri_document:, config: nil)
|
14
|
+
@nokogiri_document = nokogiri_document
|
15
|
+
@location = nil
|
16
|
+
@config = config || Config.new_default
|
17
|
+
@next_paste_count_for_id = {}
|
18
|
+
@id_copy_suffix = "_copy_"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns an enumerator that iterates over all children of this document
|
22
|
+
# that match the provided selector or XPath arguments.
|
23
|
+
#
|
24
|
+
# @param selector_or_xpath_args [Array<String>] CSS selectors or XPath arguments
|
25
|
+
# @return [ElementEnumerator]
|
26
|
+
#
|
27
|
+
def search(*selector_or_xpath_args)
|
28
|
+
selector_or_xpath_args = [selector_or_xpath_args].flatten
|
29
|
+
|
30
|
+
ElementEnumerator.new do |block|
|
31
|
+
nokogiri_document.search(*selector_or_xpath_args).each do |inner_node|
|
32
|
+
element = Kitchen::Element.new(node: inner_node,
|
33
|
+
document: self,
|
34
|
+
short_type: Utils.search_path_to_type(selector_or_xpath_args))
|
35
|
+
self.location = element
|
36
|
+
block.yield(element)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the document's clipboard with the given name.
|
42
|
+
#
|
43
|
+
# @param name [Symbol, String] the name of the clipboard. String values are
|
44
|
+
# converted to symbols.
|
45
|
+
# @return [Clipboard]
|
46
|
+
#
|
47
|
+
def clipboard(name: :default)
|
48
|
+
(@clipboards ||= {})[name.to_sym] ||= Clipboard.new
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the document's pantry with the given name.
|
52
|
+
#
|
53
|
+
# @param name [Symbol, String] the name of the pantry. String values are
|
54
|
+
# converted to symbols.
|
55
|
+
# @return [Pantry]
|
56
|
+
#
|
57
|
+
def pantry(name: :default)
|
58
|
+
(@pantries ||= {})[name.to_sym] ||= Pantry.new
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the document's counter with the given name.
|
62
|
+
#
|
63
|
+
# @param name [Symbol, String] the name of the counter. String values are
|
64
|
+
# converted to symbols.
|
65
|
+
# @return [Counter]
|
66
|
+
#
|
67
|
+
def counter(name)
|
68
|
+
(@counters ||= {})[name.to_sym] ||= Counter.new
|
69
|
+
end
|
70
|
+
|
71
|
+
# Create a new Element
|
72
|
+
#
|
73
|
+
# TODO don't know if we need this
|
74
|
+
#
|
75
|
+
# @param name [String] the tag name
|
76
|
+
# @param args [Array<String, Hash>]
|
77
|
+
#
|
78
|
+
# @example div with a class
|
79
|
+
# create_element("div", class: "foo") #=> <div class="foo"></div>
|
80
|
+
# @example div with some content and a class
|
81
|
+
# cretae_element("div", "contents", class: "foo") #=> <div class="foo">contents</div>
|
82
|
+
# @example div created by block
|
83
|
+
# create_element("div") {|elem| elem['class'] = 'foo'} #=> <div class="foo"></div>
|
84
|
+
#
|
85
|
+
# @return [Element]
|
86
|
+
#
|
87
|
+
def create_element(name, *args, &block)
|
88
|
+
Kitchen::Element.new(
|
89
|
+
node: @nokogiri_document.create_element(name, *args, &block),
|
90
|
+
document: self,
|
91
|
+
short_type: "created_element_#{SecureRandom.hex(4)}"
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_element_from_string(string)
|
96
|
+
Kitchen::Element.new(
|
97
|
+
node: @nokogiri_document.create_element("div"),
|
98
|
+
document: self,
|
99
|
+
short_type: "created_element_#{SecureRandom.hex(4)}"
|
100
|
+
).element_children.first
|
101
|
+
end
|
102
|
+
|
103
|
+
def record_id_copied(id)
|
104
|
+
return if id.blank?
|
105
|
+
@next_paste_count_for_id[id] ||= 1
|
106
|
+
end
|
107
|
+
|
108
|
+
def modified_id_to_paste(original_id)
|
109
|
+
return nil if original_id.nil?
|
110
|
+
return "" if original_id.blank?
|
111
|
+
|
112
|
+
count = next_count_for_pasted_id(original_id)
|
113
|
+
|
114
|
+
# A count of 0 means the element was cut and this is the first paste, do not
|
115
|
+
# modify the ID; otherwise, use the uniquified ID.
|
116
|
+
if count == 0
|
117
|
+
original_id
|
118
|
+
else
|
119
|
+
"#{original_id}#{@id_copy_suffix}#{count}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns the underlying Nokogiri Document object
|
124
|
+
#
|
125
|
+
# @return [Nokogiri::XML::Document]
|
126
|
+
def raw
|
127
|
+
@nokogiri_document
|
128
|
+
end
|
129
|
+
|
130
|
+
protected
|
131
|
+
|
132
|
+
def next_count_for_pasted_id(id)
|
133
|
+
return if id.blank?
|
134
|
+
(@next_paste_count_for_id[id] ||= 0).tap do
|
135
|
+
@next_paste_count_for_id[id] += 1
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
attr_reader :nokogiri_document
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|