# ~*~ encoding: utf-8 ~*~ # CriticMarkup # # Render CriticMarkup class Gollum::Filter::CriticMarkup < Gollum::Filter # Patterns inspired by https://github.com/DivineDominion/criticmarkup.tmbundle/blob/master/Syntaxes/criticmarkup.tmLanguage # All patterns use multiline matching (m flag) # Logic inspired by https://github.com/CriticMarkup/CriticMarkup-toolkit/blob/master/CLI/criticParser_CLI.py ADDITION_PATTERN = %r|{\+\+(?.*?)\+\+[ \t]*(\[(.*?)\])?[ \t]*\}|m DELETION_PATTERN = %r|{--(?.*?)--[ \t]*(\[(.*?)\])?[ \t]*\}|m SUBSTITUTION_PATTERN = %r|{~~(?.*?)~>(?.*?)~~}|m HIGHLIGHT_PATTERN = %r|{\=\=(?.*?)[ \t]*(\[(.*?)\])?[ \t]*\=\=\}{>>(?.*?)<<}|m COMMENT_PATTERN = %r|{>>(?.*?)<<}|m def extract(data) data.gsub! ADDITION_PATTERN do content = $~[:content] placeholder = generate_placeholder("#{content}#{@map.size}") # Is there a new paragraph followed by new text if content.start_with?("\n\n") && content != "\n\n" html = "\n\n \n\n#{content.gsub('\n', ' ')}" # Is the addition just a single new paragraph elsif content == "\n\n" html = "\n\n \n\n" # Is it added text followed by a new paragraph? elsif content.end_with?("\n\n") && content != "\n\n" html = "#{content.gsub('\n', ' ')}\n\n \n\n" else html = "#{content.gsub('\n', ' ')}" end @map[placeholder] = html placeholder end data.gsub! DELETION_PATTERN do content = $~[:content] placeholder = generate_placeholder("#{content}#{@map.size}") if content == "\n\n" html = " " else html = "#{content.gsub('\n\n', ' ')}" end @map[placeholder] = html placeholder end data.gsub! SUBSTITUTION_PATTERN do oldcontent = $~[:oldcontent] newcontent = $~[:newcontent] placeholder = generate_placeholder("#{oldcontent}#{newcontent}#{@map.size}") html = "#{oldcontent}#{newcontent}" @map[placeholder] = html placeholder end data.gsub! HIGHLIGHT_PATTERN do content = $~[:content] comment = $~[:comment] placeholder = generate_placeholder("#{content}#{@map.size}") html = "#{content}#{comment}" @map[placeholder] = html placeholder end data.gsub! COMMENT_PATTERN do content = $~[:content] placeholder = generate_placeholder("#{content}#{@map.size}") html = "#{content}" @map[placeholder] = html placeholder end data end def process(data) data.gsub! process_pattern do @map[$~[:placeholder]] end data end private def process_pattern /(?#{open_pattern}\h{40}#{close_pattern})/ end def generate_placeholder(content) "#{open_pattern}#{Digest::SHA1.hexdigest(content)}#{close_pattern}" end end