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.
#
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]/,"<br/>"
.sub(/\s{2}[\n\r]/,"<br/>")
# Inline code (discord style)
.sub /(?<!\\)``(.*?[^\\])``/, { |code|
"<code>#{self.escape code}</code>"
.gsub(/(?<!\\)``(.*?[^\\])``/) {
code = Regexp.last_match[1]
"<code>#{code.gsub /[*`~_!\[]/,"\\\\\\0"}</code>"
}
# Inline code (Markdown style)
.sub /(?<!\\)`(.*?[^\\])`/, { |code|
"<code>#{self.escape code}</code>"
.gsub(/(?<!\\)`(.*?[^\\])`/) {
code = Regexp.last_match[1]
"<code>#{code.gsub /[*`~_!\[]/,"\\\\\\0"}</code>"
}
# Bold-italics
.sub /(?<!\\)\*\*\*(.*?[^\\])\*\*\*/,"<i><b>\1</b></i>"
.gsub(/(?<!\\)\*\*\*(.*?[^\\])\*\*\*/,"<i><b>\\1</b></i>")
# Bold
.sub /(?<!\\)\*\*(.*?[^\\])\*\*/,"<b>\1</b>"
.gsub(/(?<!\\)\*\*(.*?[^\\])\*\*/,"<b>\\1</b>")
# Italics
.sub /(?<!\\)\*(.*?[^\\])\*/,"<i>\1</i>"
.gsub(/(?<!\\)\*(.*?[^\\])\*/,"<i>\\1</i>")
# Strikethrough
.sub /(?<!\\)~~(.*?[^\\])~~/,"<s>\1</s>"
.gsub(/(?<!\\)~~(.*?[^\\])~~/,"<s>\\1</s>")
# Underline
.sub /(?<!\\)__(.*?[^\\])__/,"<span style=\"text-decoration: underline\">\1</span>"
.gsub(/(?<!\\)__(.*?[^\\])__/,"<span style=\"text-decoration: underline\">\\1</span>")
# Image
.sub /(?<!\\)!\[(.*)\]\((.*)\)/,"<img src=\"\2\" alt=\"\1\" />"
.gsub(/(?<!\\)!\[(.*)\]\((.*)\)/,"<img src=\"\\2\" alt=\"\\1\" />")
# Link
.sub /(?<!\\)\[(.*)\]\((.*)\)/,"<a href=\"\2\">\1</a>"
.gsub(/(?<!\\)\[(.*)\]\((.*)\)/,"<a href=\"\\2\">\\1</a>")
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(/(?<!\\)(\#{1,4})([^\n\r]*)/) { |level,content|
"<h#{level.length}>"+content+"</h#{level.length}>"
}
@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}>"
}
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)(?<!\\)```([\w_-]*)(.*?)```/) {
language,code = Regexp.last_match[1..2]
code = Markdown::html_highlighter.call(language,code)
"<code>#{code}</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] = "<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 = @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

95
test.rb
View File

@ -1,7 +1,92 @@
require "minitest"
require "markdown"
class LinearParsingTest << Minitest::Test
def setup
@lparser =
require_relative "markdown"
puts Markdown::LinearTagTranslator.new(<<CODE
*Italics*
**Bold**
***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