Class: TranslationDiff::Passage::Scanner
- Inherits:
-
Ox::Sax
- Object
- Ox::Sax
- TranslationDiff::Passage::Scanner
- Defined in:
- lib/translation_diff/passage.rb
Overview
Ox reports a byte position for every construct it sees; recording those is what lets rendering slice the source.
Defined Under Namespace
Classes: Mark
Constant Summary collapse
- PROTECTED =
Providers honour this class themselves under the HTML mode this gem sends, so the element must reach them whole.
"notranslate".freeze
- OPENING_ANGLE =
"<".ord
Instance Method Summary collapse
-
#attr(name, value) ⇒ Object
Attributes arrive straight after their own start element, so @pending is that element and never another.
- #cdata(_content) ⇒ Object
- #comment(_content) ⇒ Object
- #doctype(_content) ⇒ Object
- #end_element(_name) ⇒ Object
-
#initialize(source, opaque_elements:) ⇒ Scanner
constructor
Ox reports positions only to a handler that already has the ivar, so @pos exists before parsing starts.
- #instruct(_target) ⇒ Object
-
#runs ⇒ Object
Triples of [first byte, last byte + 1, prose?], contiguous, covering the source exactly once.
-
#start_element(name) ⇒ Object
Protection beats opacity on purpose: a caller wrapping a subtree asked for it to be passed through as it is.
- #value(_value) ⇒ Object
Constructor Details
#initialize(source, opaque_elements:) ⇒ Scanner
Ox reports positions only to a handler that already has the ivar, so @pos exists before parsing starts. opaque_elements is a caller-supplied set of element names, so it is normalised here rather than trusted as given.
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/translation_diff/passage.rb', line 46 def initialize(source, opaque_elements:) super() @source = source @opaque = opaque_elements.map { |element| element.to_s.downcase.to_sym } @pos = 0 @marks = [] @protected_depth = 0 @opaque_depth = 0 @opaque_bump = false @pending = nil end |
Instance Method Details
#attr(name, value) ⇒ Object
Attributes arrive straight after their own start element, so @pending is that element and never another. A protected element's own end_element takes the protected branch and never reaches the opaque decrement, so an opaque_depth this element raised has to be given back here or it would outlive the element that raised it.
78 79 80 81 82 83 84 85 |
# File 'lib/translation_diff/passage.rb', line 78 def attr(name, value) return unless @pending && protection?(name, value) @pending.prose = true @opaque_depth -= 1 if @opaque_bump @protected_depth = 1 @pending = nil end |
#cdata(_content) ⇒ Object
98 |
# File 'lib/translation_diff/passage.rb', line 98 def cdata(_content) = record(prose: false) |
#comment(_content) ⇒ Object
96 |
# File 'lib/translation_diff/passage.rb', line 96 def comment(_content) = record(prose: false) |
#doctype(_content) ⇒ Object
100 |
# File 'lib/translation_diff/passage.rb', line 100 def doctype(_content) = record(prose: false) |
#end_element(_name) ⇒ Object
87 88 89 90 91 92 |
# File 'lib/translation_diff/passage.rb', line 87 def end_element(_name) return @protected_depth -= 1 if @protected_depth.positive? @opaque_depth -= 1 if @opaque_depth.positive? record(prose: false) end |
#instruct(_target) ⇒ Object
102 |
# File 'lib/translation_diff/passage.rb', line 102 def instruct(_target) = record(prose: false) |
#runs ⇒ Object
Triples of [first byte, last byte + 1, prose?], contiguous, covering the source exactly once.
59 60 61 62 |
# File 'lib/translation_diff/passage.rb', line 59 def runs Ox.sax_html(self, StringIO.new(@source)) merge(bounds) end |
#start_element(name) ⇒ Object
Protection beats opacity on purpose: a caller wrapping a subtree asked for it to be passed through as it is. that increment if the element turns out to be protected -- its own end_element never gets the chance to.
67 68 69 70 71 72 73 |
# File 'lib/translation_diff/passage.rb', line 67 def start_element(name) return @protected_depth += 1 if @protected_depth.positive? @opaque_bump = @opaque_depth.positive? || @opaque.include?(name.to_s.downcase.to_sym) @opaque_depth += 1 if @opaque_bump @pending = mark(prose: false) end |
#value(_value) ⇒ Object
94 |
# File 'lib/translation_diff/passage.rb', line 94 def value(_value) = record(prose: @opaque_depth.zero?) |