diff --git a/lib/blankshell.rb b/lib/blankshell.rb index 08a1fbc..ddfc36c 100644 --- a/lib/blankshell.rb +++ b/lib/blankshell.rb @@ -114,7 +114,6 @@ module PointBlank def read_properties(text) properties = {} remaining = text - warn text.inspect if text.start_with? '[' # link label properties[:label], remaining = read_return_label(remaining) close_bracket = false @@ -258,6 +257,7 @@ module PointBlank newblock = switchclass.new newblock.content = block.content newblock.parser = nil + newblock.parent = block.parent block.parent[block.position] = newblock newblock end @@ -342,8 +342,8 @@ module PointBlank def consume(line, parent = nil, lazy: false) @lazy_triggered = lazy || @lazy_triggered return [nil, nil] if line.match?(/\A {0,3}\Z/) - return [nil, nil] if check_candidates(line, parent) return [nil, nil] if @closed + return [nil, nil] if check_candidates(line, parent) push(line) ["", nil] @@ -365,6 +365,13 @@ module PointBlank other = classes.filter do |cls| !(once ||= (cls == ::PointBlank::DOM::Paragraph)) end + underlines_match = ::PointBlank::DOM::Paragraph.valid_children.any? do |x| + x.parser.begin?(line) + end + if underlines_match && !@lazy_triggered + @closed = true + return false + end other.any? do |x| x.parser.begin? line end @@ -879,7 +886,8 @@ module PointBlank obj = ::PointBlank::DOM::Text.new string = string.gsub(/\\([!"\#$%&'()*+,\-.\/:;<=>?@\[\\\]\^_`{|}~])/, '\\1') - obj.content = string.strip + string = string.gsub("\n", " ") + obj.content = string obj end @@ -924,7 +932,7 @@ module PointBlank next unless part.last == :close next unless part[1].respond_to?(:reverse_walk) - backlog = part[1].reverse_walk(backlog) + backlog = part[1].reverse_walk(backlog, doc: @doc) end backlog end @@ -1041,6 +1049,7 @@ module PointBlank obj = ::PointBlank::DOM::Text.new string = string.gsub(/\\([!"\#$%&'()*+,\-.\/:;<=>?@\[\\\]\^_`{|}~])/, '\\1') + string = string.gsub("\n", " ") obj.content = string obj end @@ -1159,17 +1168,25 @@ module PointBlank # Build object and apply link info to it # @param capture [Array] + # @param doc [::PointBlank::DOM::DOMObject] # @return [::PointBlank::DOM::DOMObject] - def self.build_w_linkinfo(capture) + def self.build_w_linkinfo(capture, doc) linkinfo = capture[-1][2] obj = build(capture[1..-2]) + if linkinfo[:label] + if (props = doc.root.properties[:linkdefs][linkinfo[:label]]) + linkinfo = props + else + return nil + end + end obj.properties = linkinfo obj end # TODO: optimize, increase index instead of building buffers # (see ::PointBlank::Parsing::NullInline#reverse_walk) - def self.reverse_walk(backlog) + def self.reverse_walk(backlog, doc:) before = [] capture = [] open = true @@ -1184,7 +1201,8 @@ module PointBlank end return backlog if open - before + [cls.build_w_linkinfo(capture)] + block = cls.build_w_linkinfo(capture, doc) + block ? before + [block] : backlog end end @@ -1289,7 +1307,7 @@ module PointBlank end # (see ::PointBlank::Parsing::NullInline#reverse_walk) - def self.reverse_walk(backlog) + def self.reverse_walk(backlog, **_doc) until backlog.last.first.empty? capture = [] before = [] @@ -1351,7 +1369,7 @@ module PointBlank # (see ::PointBlank::Parsing::NullInline#tokenize) def self.tokenize(string) iterate_tokens(string, /(?: \n|\\\n)/) do |_before, token, matched| - next ["\n", self, :close] if token == " \\n" + next ["\n", self, :close] if token.start_with?(" \n") next ["\n", self, :close] if matched " " @@ -1359,7 +1377,7 @@ module PointBlank end # (see ::PointBlank::Parsing::NullInline#reverse_walk) - def self.reverse_walk(backlog) + def self.reverse_walk(backlog, **_doc) backlog[-1] = build([]) backlog end @@ -1507,6 +1525,14 @@ module PointBlank @children.dup end + # Get root element containing this child + # @return [::PointBlank::DOM::DOMObject] + def root + current_root = self + current_root = current_root.parent while current_root.parent + current_root + end + # Append child # @param child [DOMObject] def append_child(child) @@ -1519,14 +1545,9 @@ module PointBlank @children.append(child) end - # Append temp. child - # @param child [DOMObject, String] - def append_temp(child) - unless child.is_a?(::PointBlank::DOM::DOMObject) || - child.is_a?(String) - raise DOMError, "invlaid temp class #{child.class}" - end - + # Append temp child + # @param child [DOMObject] + def append_temp_child(child) @temp_children.append(child) end @@ -1546,8 +1567,8 @@ module PointBlank class InlinePre < DOMObject define_parser ::PointBlank::Parsing::CodeInline end - - # Linebreak + + # Hard Linebreak class InlineBreak < DOMObject define_parser ::PointBlank::Parsing::HardBreakInline end @@ -1628,14 +1649,10 @@ module PointBlank # Leaf block (virtual) class LeafBlock < DOMObject - # Virtual hook to push inlines in place of leaf blocks + # Virtual hook to delay inline processing def parse_inner - child = ::PointBlank::DOM::InlineRoot.new - child.content = content - scanner = ::PointBlank::Parsing::StackScanner.new(child) - scanner.scan - self.content = "" - child.each { |c| append_child(c) } + self.content = content.strip if content + root.append_temp_child(self) end end @@ -1651,6 +1668,24 @@ module PointBlank # Document root class Document < Block + # (see ::PointBlank::DOM::DOMObject#parse) + def self.parse(doc) + output = super(doc) + # This has to be done after the document gets processed due to the way link + # definitions have to be handled. + parse_inner = lambda do |block| + child = ::PointBlank::DOM::InlineRoot.new + child.parent = block.parent + child.content = block.content + scanner = ::PointBlank::Parsing::StackScanner.new(child) + scanner.scan + block.content = "" + child.each { |c| block.append_child(c) } + end + output.temp_children.each { |block| parse_inner.call(block) } + output.temp_children.clear + output + end end # Paragraph in a document (separated by 2 newlines) @@ -1659,14 +1694,10 @@ module PointBlank define_overlay ::PointBlank::Parsing::ParagraphUnderlineOverlay, 0 define_overlay ::PointBlank::Parsing::LinkReferenceOverlay - # Virtual hook to parse inline contents of a finished paragraph + # Virtual hook to delay inline processing def parse_inner - child = ::PointBlank::DOM::InlineRoot.new - child.content = content - scanner = ::PointBlank::Parsing::StackScanner.new(child) - scanner.scan - self.content = "" - child.each { |c| append_child(c) } + self.content = content.strip if content + root.append_temp_child(self) end end