Class: Kotoshu::Documents::Document
- Inherits:
-
Object
- Object
- Kotoshu::Documents::Document
- Defined in:
- lib/kotoshu/documents/document.rb
Overview
Document abstraction for structure-aware spell and grammar checking. Pairs the flattened text a checker scans with the source positions of each TextNode, so errors can be reported against the original markup-bearing source.
Subclasses (or plugins) populate text_nodes with one entry per
contiguous text run, each carrying the SourceRange it occupies
in the source. The base class provides the bidirectional
offset-mapping logic — it walks the nodes to recover a source
range from a flattened offset.
Kotoshu ships only PlainTextDocument; format-specific parsers (Markdown, AsciiDoc, etc.) live in plugins.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#format ⇒ Object
readonly
Returns the value of attribute format.
-
#language_code ⇒ Object
readonly
Returns the value of attribute language_code.
-
#source ⇒ Object
readonly
Returns the value of attribute source.
-
#text_nodes ⇒ Object
readonly
Returns the value of attribute text_nodes.
Instance Method Summary collapse
-
#each_node(&block) ⇒ Object
Iterate text nodes.
-
#flattened_length ⇒ Object
Total character length of the flattened text.
-
#flattened_offset?(offset) ⇒ Boolean
True when
offsetfalls within the flattened text. -
#flattened_text ⇒ String
The flattened text — concatenation of every node's
text. -
#initialize(text_nodes:, source: nil, format: :plain, language_code: nil) ⇒ Document
constructor
A new instance of Document.
-
#source_range_at(flattened_offset) ⇒ SourceRange?
Recover the SourceRange of the TextNode that contains the given flattened offset.
-
#source_range_for(flattened_start, flattened_end = nil) ⇒ SourceRange?
Recover the SourceRange spanning a flattened sub-range.
Constructor Details
#initialize(text_nodes:, source: nil, format: :plain, language_code: nil) ⇒ Document
Returns a new instance of Document.
27 28 29 30 31 32 33 34 35 |
# File 'lib/kotoshu/documents/document.rb', line 27 def initialize(text_nodes:, source: nil, format: :plain, language_code: nil) raise ArgumentError, "text_nodes cannot be empty" if text_nodes.nil? || text_nodes.empty? @text_nodes = text_nodes.freeze @source = source @format = format @language_code = language_code freeze end |
Instance Attribute Details
#format ⇒ Object (readonly)
Returns the value of attribute format.
19 20 21 |
# File 'lib/kotoshu/documents/document.rb', line 19 def format @format end |
#language_code ⇒ Object (readonly)
Returns the value of attribute language_code.
19 20 21 |
# File 'lib/kotoshu/documents/document.rb', line 19 def language_code @language_code end |
#source ⇒ Object (readonly)
Returns the value of attribute source.
19 20 21 |
# File 'lib/kotoshu/documents/document.rb', line 19 def source @source end |
#text_nodes ⇒ Object (readonly)
Returns the value of attribute text_nodes.
19 20 21 |
# File 'lib/kotoshu/documents/document.rb', line 19 def text_nodes @text_nodes end |
Instance Method Details
#each_node(&block) ⇒ Object
Iterate text nodes. Returns an Enumerator when no block given.
96 97 98 99 100 |
# File 'lib/kotoshu/documents/document.rb', line 96 def each_node(&block) return enum_for(:each_node) unless block @text_nodes.each(&block) end |
#flattened_length ⇒ Object
Total character length of the flattened text.
46 47 48 |
# File 'lib/kotoshu/documents/document.rb', line 46 def flattened_length @text_nodes.sum(&:length) end |
#flattened_offset?(offset) ⇒ Boolean
True when offset falls within the flattened text.
51 52 53 |
# File 'lib/kotoshu/documents/document.rb', line 51 def flattened_offset?(offset) offset >= 0 && offset < flattened_length end |
#flattened_text ⇒ String
The flattened text — concatenation of every node's text.
This is what the checker actually scans.
41 42 43 |
# File 'lib/kotoshu/documents/document.rb', line 41 def flattened_text @text_nodes.map(&:text).join end |
#source_range_at(flattened_offset) ⇒ SourceRange?
Recover the SourceRange of the TextNode that contains the given flattened offset. Returns nil for out-of-range offsets.
Note: this returns the node's source range, not a one-char slice. For a tighter range, use #source_range_for with a flattened sub-range.
64 65 66 67 68 69 |
# File 'lib/kotoshu/documents/document.rb', line 64 def source_range_at(flattened_offset) return nil unless flattened_offset?(flattened_offset) node = node_at(flattened_offset) node&.source_range end |
#source_range_for(flattened_start, flattened_end = nil) ⇒ SourceRange?
Recover the SourceRange spanning a flattened sub-range.
The start of the result is the start of the node containing
flattened_start; the end is the end of the node containing
flattened_end - 1. Useful for errors that span multiple
text nodes (e.g. a grammar error like "an friend" that
crosses a markup boundary).
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/kotoshu/documents/document.rb', line 81 def source_range_for(flattened_start, flattened_end = nil) return nil unless flattened_offset?(flattened_start) end_offset = flattened_end ? flattened_end - 1 : flattened_length - 1 end_offset = [end_offset, flattened_length - 1].min return nil unless flattened_offset?(end_offset) start_node = node_at(flattened_start) end_node = node_at(end_offset) return nil unless start_node && end_node start_node.source_range.union(end_node.source_range) end |