clearing the number line

This commit is contained in:
Yessiest 2023-02-13 13:20:23 +04:00
parent e3ff2331ad
commit 60821677af
2 changed files with 230 additions and 50 deletions

View File

@ -1,92 +1,187 @@
## Filter-based Markdown translator. ## Filter-based Markdown translator.
#
module Markdown module Markdown
## Translator for linear tags in Markdown. ## Superclass that defines behaviour of all translators
# A linear tag is any tag that starts anywhere on the line, and closes on the same exact line. # @abstract Don't use directly - it only defins the ability to chain translators
class LinearTagTranslator class AbstractTranslator
def initialize(text) attr_accessor :input
@input = text attr_accessor :output
def initialize()
@chain = []
end end
def escape(text) def +(nextTranslator)
text.sub /([*`~_!\[])/,"\\\1" @chain.append nextTranslator
return self
end end
def to_html 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 # Newline
.sub /\s{2}[\n\r]/,"<br/>" .sub(/\s{2}[\n\r]/,"<br/>")
# Inline code (discord style) # Inline code (discord style)
.sub /(?<!\\)``(.*?[^\\])``/, { |code| .gsub(/(?<!\\)``(.*?[^\\])``/) {
"<code>#{self.escape code}</code>" code = Regexp.last_match[1]
"<code>#{code.gsub /[*`~_!\[]/,"\\\\\\0"}</code>"
} }
# Inline code (Markdown style) # Inline code (Markdown style)
.sub /(?<!\\)`(.*?[^\\])`/, { |code| .gsub(/(?<!\\)`(.*?[^\\])`/) {
"<code>#{self.escape code}</code>" code = Regexp.last_match[1]
"<code>#{code.gsub /[*`~_!\[]/,"\\\\\\0"}</code>"
} }
# Bold-italics # Bold-italics
.sub /(?<!\\)\*\*\*(.*?[^\\])\*\*\*/,"<i><b>\1</b></i>" .gsub(/(?<!\\)\*\*\*(.*?[^\\])\*\*\*/,"<i><b>\\1</b></i>")
# Bold # Bold
.sub /(?<!\\)\*\*(.*?[^\\])\*\*/,"<b>\1</b>" .gsub(/(?<!\\)\*\*(.*?[^\\])\*\*/,"<b>\\1</b>")
# Italics # Italics
.sub /(?<!\\)\*(.*?[^\\])\*/,"<i>\1</i>" .gsub(/(?<!\\)\*(.*?[^\\])\*/,"<i>\\1</i>")
# Strikethrough # Strikethrough
.sub /(?<!\\)~~(.*?[^\\])~~/,"<s>\1</s>" .gsub(/(?<!\\)~~(.*?[^\\])~~/,"<s>\\1</s>")
# Underline # Underline
.sub /(?<!\\)__(.*?[^\\])__/,"<span style=\"text-decoration: underline\">\1</span>" .gsub(/(?<!\\)__(.*?[^\\])__/,"<span style=\"text-decoration: underline\">\\1</span>")
# Image # Image
.sub /(?<!\\)!\[(.*)\]\((.*)\)/,"<img src=\"\2\" alt=\"\1\" />" .gsub(/(?<!\\)!\[(.*)\]\((.*)\)/,"<img src=\"\\2\" alt=\"\\1\" />")
# Link # Link
.sub /(?<!\\)\[(.*)\]\((.*)\)/,"<a href=\"\2\">\1</a>" .gsub(/(?<!\\)\[(.*)\]\((.*)\)/,"<a href=\"\\2\">\\1</a>")
super
end end
end end
## Translator for linear leftmost tags. ## 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. # 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 class LeftmostTagTranslator < AbstractTranslator
def initalize(text) def initialize(text)
@input = text @input = text
@output = text
super()
end end
def to_html def to_html
# Headers # Headers
@input.sub(/(?<!\\)(\#{1,4})([^\n\r]*)/) { |level,content| @output = @input.split("\n").map do |x|
x.gsub(/^(?<!\\)(\#{1,4})([^\n\r]*)/) {
level,content = Regexp.last_match[1..2]
"<h#{level.length}>"+content+"</h#{level.length}>" "<h#{level.length}>"+content+"</h#{level.length}>"
} }
end.join("\n")
super
end end
end end
## Translator for code blocks in Markdown. ## Translator for code blocks in markdown
# First in terms of precedence. # Code blocks can have syntax highlighting. This class implements an attribute for providing a syntax highlighter, one handler per requested output.
class CodeBlocksTranslator class CodeBlockTranslator < AbstractTranslator
def initialize(text def initialize(text)
@input = text
@output = text
super()
end
def to_html
@output = @input.gsub(/(?<=\n)(?<!\\)```([\w_-]*)(.*?)```/) {
language,code = Regexp.last_match[1..2]
code = Markdown::html_highlighter.call(language,code)
"<code>#{code}</code>"
}
super()
end
end end
## Translator for quotes in Markdown. ## Translator for quotes in Markdown.
# These deserve their own place in hell. # 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 class QuoteTranslator < AbstractTranslator
def initialize(text, level: 0) def initialize(text)
if text.is_a? Array then if text.is_a? Array then
@lines = text @lines = text
elsif text.is_a? String then elsif text.is_a? String then
@lines = text.split("\n\n") @lines = text.split("\n")
end end
@output = text
super()
end
def input= (v)
@lines = v.split("\n")
@output = v
end
def input
@lines.join("\n")
end end
def to_html def to_html
stack = [] stack = []
range = [] range = []
state = false
@lines.each_with_index { |x,index| @lines.each_with_index { |x,index|
if x.match(/^\s{0,1}>/) and state == false then if x.match /^\s*> ?/ then
range.append index range[0] = index if not range[0]
state = true range[1] = index
end else
if (not x.match /^\s{0,1}>/) and state == true then stack.append(range[0]..range[1]) if range[0] and range[1]
range.append index-1
state = false
stack.append(range[0]..range[1])
range = [] range = []
end end
} }
range.each { |r| stack.append(range[0]..range[1]) if range[0] and range[1]
stack.reverse.each { |r|
@lines[r.begin] = "<blockquote>\n"+@lines[r.begin]
@lines[r.end] = @lines[r.end]+"\n</blockquote>"
@lines[r] = @lines[r].map { |line|
line.sub /^(\s*)> ?/,"\\1 "
}
@lines[r] = QuoteTranslator.new(@lines[r]).to_html @lines[r] = QuoteTranslator.new(@lines[r]).to_html
} }
@lines = @lines.map { |x| @output = @lines.join("\n")
(x.sub /^\s{0,1}>/,"") 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 end
end end

95
test.rb
View File

@ -1,7 +1,92 @@
require "minitest" require_relative "markdown"
require "markdown" puts Markdown::LinearTagTranslator.new(<<CODE
class LinearParsingTest << Minitest::Test *Italics*
def setup **Bold**
@lparser = ***Bolitalics***
__underline__
__underline plus ***bolitalics***__
___invalid underline___
~~strikethrough ~~
`code that ignores ***all*** __Markdown__ [tags](https://nevergonnagiveyouup)`
me: google en passant
them: [holy hell!](https://google.com/q?=en+passant)
CODE
).to_html
puts Markdown::LeftmostTagTranslator.new(<<CODE
# Header v1
## Header v2
### Header v3
#### Header v4
##### Invalid header
#### Not a header
*** Also #### Not a header ***
CODE
).to_html
puts Markdown::QuoteTranslator.new(<<CODE
> 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(<<CODE
```markdown
shmarkshmark
# pee pee
# piss
**ass**
__cock__
cock__
piss__
`shmark shmark`
```
CODE
).to_html
puts (Markdown::QuoteTranslator.new(<<TEXT
> 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