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