diff --git a/markdown.rb b/markdown.rb index 32f2fcb..3be5015 100644 --- a/markdown.rb +++ b/markdown.rb @@ -1,92 +1,187 @@ ## Filter-based Markdown translator. +# module Markdown - ## Translator for linear tags in Markdown. - # A linear tag is any tag that starts anywhere on the line, and closes on the same exact line. - class LinearTagTranslator - def initialize(text) - @input = text + ## Superclass that defines behaviour of all translators + # @abstract Don't use directly - it only defins the ability to chain translators + class AbstractTranslator + attr_accessor :input + attr_accessor :output + def initialize() + @chain = [] end - def escape(text) - text.sub /([*`~_!\[])/,"\\\1" + def +(nextTranslator) + @chain.append nextTranslator + return self end def to_html - @input + output = @output + @chain.each { |x| + x = x.new(output) if x.class == Class + x.to_html + output = x.output + } + return output + end + end + module_function + def html_highlighter; @html_highlighter end + def html_highlighter= v; @html_highlighter = v end + ## Translator for linear tags in Markdown. + # A linear tag is any tag that starts anywhere on the line, and closes on the same exact line. + class LinearTagTranslator < AbstractTranslator + def initialize(text) + @input = text + @output = text + super() + end + def to_html + @output = @input # Newline - .sub /\s{2}[\n\r]/,"
" + .sub(/\s{2}[\n\r]/,"
") # Inline code (discord style) - .sub /(?#{self.escape code}" + .gsub(/(?#{code.gsub /[*`~_!\[]/,"\\\\\\0"}" } # Inline code (Markdown style) - .sub /(?#{self.escape code}" + .gsub(/(?#{code.gsub /[*`~_!\[]/,"\\\\\\0"}" } # Bold-italics - .sub /(?\1" + .gsub(/(?\\1") # Bold - .sub /(?\1" + .gsub(/(?\\1") # Italics - .sub /(?\1" + .gsub(/(?\\1") # Strikethrough - .sub /(?\1" + .gsub(/(?\\1") # Underline - .sub /(?\1" + .gsub(/(?\\1") # Image - .sub /(?" + .gsub(/(?") # Link - .sub /(?\1" + .gsub(/(?\\1") + super end end ## Translator for linear leftmost tags. # Leftmost linear tags open on the leftmost end of the string, and close once the line ends. These tags do not need to be explicitly closed. - class LeftmostTagTranslator - def initalize(text) + class LeftmostTagTranslator < AbstractTranslator + def initialize(text) @input = text + @output = text + super() end def to_html # Headers - @input.sub(/(?"+content+"" - } + @output = @input.split("\n").map do |x| + x.gsub(/^(?"+content+"" + } + end.join("\n") + super end end - ## Translator for code blocks in Markdown. - # First in terms of precedence. - class CodeBlocksTranslator - def initialize(text + ## Translator for code blocks in markdown + # Code blocks can have syntax highlighting. This class implements an attribute for providing a syntax highlighter, one handler per requested output. + class CodeBlockTranslator < AbstractTranslator + def initialize(text) + @input = text + @output = text + super() + end + def to_html + @output = @input.gsub(/(?<=\n)(?#{code}" + } + super() + end end ## Translator for quotes in Markdown. - # These deserve their own place in hell. - class QuoteTranslator - def initialize(text, level: 0) + # These deserve their own place in hell. As if the "yaml with triangle brackets instead of spaces" syntax wasn't horrible enough, each quote is its own markdown context. + class QuoteTranslator < AbstractTranslator + def initialize(text) if text.is_a? Array then @lines = text elsif text.is_a? String then - @lines = text.split("\n\n") + @lines = text.split("\n") end + @output = text + super() + end + def input= (v) + @lines = v.split("\n") + @output = v + end + def input + @lines.join("\n") end def to_html stack = [] range = [] - state = false @lines.each_with_index { |x,index| - if x.match(/^\s{0,1}>/) and state == false then - range.append index - state = true - end - if (not x.match /^\s{0,1}>/) and state == true then - range.append index-1 - state = false - stack.append(range[0]..range[1]) + if x.match /^\s*> ?/ then + range[0] = index if not range[0] + range[1] = index + else + stack.append(range[0]..range[1]) if range[0] and range[1] range = [] end } - range.each { |r| + stack.append(range[0]..range[1]) if range[0] and range[1] + stack.reverse.each { |r| + @lines[r.begin] = "
\n"+@lines[r.begin] + @lines[r.end] = @lines[r.end]+"\n
" + @lines[r] = @lines[r].map { |line| + line.sub /^(\s*)> ?/,"\\1 " + } @lines[r] = QuoteTranslator.new(@lines[r]).to_html } - @lines = @lines.map { |x| - (x.sub /^\s{0,1}>/,"") + @output = @lines.join("\n") + super + end + end + + ## Table parser + # translates tables from a format in markdown to an html table + class TableTranslator < AbstractTranslator + def initialize(text) + @input = text + @output = text + super() + end + def to_html + lines = @output.split("\n") + table_testline = -1 + table_start = -1 + table_column_count = 0 + tables = [] + cur_table = [] + lines.each_with_index { |line,index| + if (line.start_with? / *\|/) and (line.match /^ *\|.*\|/) then + table_start = index + table_column_count = line.count "|" + cur_table.push (line.split "|") + end + if (table_start != -1) and (line.match /^ *\|([^\|]*\|){#{table_column_count-1}}$/) then + if (table_testline == -1) then + if (line.match /^ *\|(\-*\|){#{table_column_count-1}}$/) then + table_testline = 1 + else + table_start = -1 + cur_table = [] + end + else + cur_table.push (line.split "|") + end + end + puts cur_table } + super() end end end diff --git a/test.rb b/test.rb index 14eb156..d7cd45e 100644 --- a/test.rb +++ b/test.rb @@ -1,7 +1,92 @@ -require "minitest" -require "markdown" -class LinearParsingTest << Minitest::Test - def setup - @lparser = +require_relative "markdown" +puts Markdown::LinearTagTranslator.new(< Quote begins +> +> yea +> # header btw +> > nextlevel quote +> > more quote +> > those are quotes +> > yes +> > > third level quote +> > > yes +> > second level again +> > > third level again +> > second level oioioi +> > +> > > third +> > > +> > > +> > > +> +> +> +> fin +CODE + ).to_html +puts Markdown::CodeBlockTranslator.new(< Here's a bunch of shit i guess lmao idk +```markdown +test +test +test +*** test *** +piss +cock +__cock__ +# hi +``` +> ok +> here i go pissing +> ***time to take a piss*** +> > pissing +> > "what the hell are you doing" +> > i'm taking a pieeees +> > "why areyou not jomping at me thats what yourshupposed to do +> > I might do it focking later +> > ok +> # bug +> __cum__ +__mashup__ + +TEXT + )+Markdown::QuoteTranslator+Markdown::LeftmostTagTranslator+Markdown::LinearTagTranslator) + .to_html