diff --git a/document.rb b/document.rb index c0418cc..c5b2e86 100644 --- a/document.rb +++ b/document.rb @@ -340,7 +340,7 @@ module RBMark class Document < DOMObject # (see ::RBMark::DOM::DOMObject.parse) def self.parse(text) - vacuum(super(normalize_newlines(text))) + merge(vacuum(super(normalize_newlines(text)))) end # Replace all forms of line endings with UNIX format newline @@ -359,6 +359,55 @@ module RBMark end document end + + # Merge adjacent lists with indent blocks as per markdownguide guidelines + def self.merge(document) + last_list = nil + delete_deferred = [] + document.children.each_with_index do |child, index| + if !last_list and [::RBMark::DOM::ULBlock, + ::RBMark::DOM::OLBlock].include? child.class + last_list = child + elsif last_list and mergeable?(last_list, child) + merge_adjacent(last_list, child) + delete_deferred.append(index) + else + last_list = nil + end + end + delete_deferred.reverse_each { |index| document.delete_at(index) } + document + end + + # Check if 2 elements can be merged + def self.mergeable?(list, child) + if child.is_a? ::RBMark::DOM::IndentBlock or + (child.is_a? ::RBMark::DOM::ULBlock and + list.is_a? ::RBMark::DOM::ULBlock) or + (child.is_a? ::RBMark::DOM::OLBlock and + list.is_a? ::RBMark::DOM::OLBlock and + child.children.first.properties[:number] > + list.children.last.properties[:number]) + true + else + false + end + end + + # Merge 2 elements + def self.merge_adjacent(left, right) + if right.is_a? ::RBMark::DOM::ULBlock or + right.is_a? ::RBMark::DOM::OLBlock + right.children.each do |child| + left.append(child) + end + elsif right.is_a? ::RBMark::DOM::IndentBlock + left.children.last.append( + *::RBMark::DOM::ListElement.parse(right.children.first.content) + .children + ) + end + end end # Paragraph in a document (separated by 2 newlines) @@ -534,13 +583,17 @@ module RBMark end # Indent block - class IndentBlock < Document + class IndentBlock < DOMObject self.begin = /^ {4}/ self.end = /(?:^(?! {4})|\Z)/ # (see RBMark::DOM::DOMObject.parse) def self.parse(text) - super(text.lines.map { |x| x[4..] }.join('')) + instance = new + element = ::RBMark::DOM::Text.new + element.content = text.lines.map { |x| x[4..] }.join('') + instance.append(element) + instance end end diff --git a/test.md b/test.md index efb7c14..5c49d3b 100644 --- a/test.md +++ b/test.md @@ -140,3 +140,10 @@ text --- gnomo + + indented preformatted text + indented preformatted text + function() peepeeopoopoo { + puts ass + } + indented preformatted text