mirror of
https://github.com/ralsina/tartrazine.git
synced 2024-09-20 07:21:22 +00:00
Many cleanups
This commit is contained in:
parent
58e8dac038
commit
a3a7b5bd9a
@ -68,8 +68,7 @@ module Tartrazine
|
|||||||
line_id = linkable_line_numbers? ? "id=\"#{line_number_id_prefix}#{i + 1}\"" : ""
|
line_id = linkable_line_numbers? ? "id=\"#{line_number_id_prefix}#{i + 1}\"" : ""
|
||||||
outp << "<span #{line_id} #{line_class} style=\"user-select: none;\">#{line_label} </span>"
|
outp << "<span #{line_id} #{line_class} style=\"user-select: none;\">#{line_label} </span>"
|
||||||
line.each do |token|
|
line.each do |token|
|
||||||
fragment = "<span class=\"#{get_css_class(token[:type])}\">#{HTML.escape(token[:value])}</span>"
|
outp << "<span class=\"#{get_css_class(token[:type])}\">#{HTML.escape(token[:value])}</span>"
|
||||||
outp << fragment
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
outp << "</code></pre>"
|
outp << "</code></pre>"
|
||||||
@ -105,15 +104,17 @@ module Tartrazine
|
|||||||
|
|
||||||
# Given a token type, return the CSS class to use.
|
# Given a token type, return the CSS class to use.
|
||||||
def get_css_class(token : String) : String
|
def get_css_class(token : String) : String
|
||||||
return class_prefix + Abbreviations[token] if theme.styles.has_key?(token)
|
if !theme.styles.has_key? token
|
||||||
|
# Themes don't contain information for each specific
|
||||||
# Themes don't contain information for each specific
|
# token type. However, they may contain information
|
||||||
# token type. However, they may contain information
|
# for a parent style. Worst case, we go to the root
|
||||||
# for a parent style. Worst case, we go to the root
|
# (Background) style.
|
||||||
# (Background) style.
|
parent = theme.style_parents(token).reverse.find { |dad|
|
||||||
class_prefix + Abbreviations[theme.style_parents(token).reverse.find { |parent|
|
theme.styles.has_key?(dad)
|
||||||
theme.styles.has_key?(parent)
|
}
|
||||||
}]
|
theme.styles[token] = theme.styles[parent]
|
||||||
|
end
|
||||||
|
class_prefix + Abbreviations[token]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Is this line in the highlighted ranges?
|
# Is this line in the highlighted ranges?
|
||||||
|
@ -225,9 +225,9 @@ module Tartrazine
|
|||||||
# A Lexer state. A state has a name and a list of rules.
|
# A Lexer state. A state has a name and a list of rules.
|
||||||
# The state machine has a state stack containing references
|
# The state machine has a state stack containing references
|
||||||
# to states to decide which rules to apply.
|
# to states to decide which rules to apply.
|
||||||
class State
|
struct State
|
||||||
property name : String = ""
|
property name : String = ""
|
||||||
property rules = [] of Rule
|
property rules = [] of BaseRule
|
||||||
|
|
||||||
def +(other : State)
|
def +(other : State)
|
||||||
new_state = State.new
|
new_state = State.new
|
||||||
|
63
src/rules.cr
63
src/rules.cr
@ -15,30 +15,12 @@ module Tartrazine
|
|||||||
alias Match = BytesRegex::Match
|
alias Match = BytesRegex::Match
|
||||||
alias MatchData = Array(Match)
|
alias MatchData = Array(Match)
|
||||||
|
|
||||||
class Rule
|
abstract struct BaseRule
|
||||||
property pattern : Regex = Regex.new ""
|
abstract def match(text : Bytes, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
||||||
|
abstract def initialize(node : XML::Node)
|
||||||
|
|
||||||
property actions : Array(Action) = [] of Action
|
property actions : Array(Action) = [] of Action
|
||||||
|
|
||||||
def match(text : Bytes, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
|
||||||
match = pattern.match(text, pos)
|
|
||||||
# We don't match if the match doesn't move the cursor
|
|
||||||
# because that causes infinite loops
|
|
||||||
return false, pos, [] of Token if match.empty? || match[0].size == 0
|
|
||||||
tokens = [] of Token
|
|
||||||
actions.each do |action|
|
|
||||||
tokens += action.emit(match, lexer)
|
|
||||||
end
|
|
||||||
return true, pos + match[0].size, tokens
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize(node : XML::Node, multiline, dotall, ignorecase)
|
|
||||||
@xml = node.to_s
|
|
||||||
pattern = node["pattern"]
|
|
||||||
pattern = "(?m)" + pattern if multiline
|
|
||||||
@pattern = Regex.new(pattern, multiline, dotall, ignorecase, true)
|
|
||||||
add_actions(node)
|
|
||||||
end
|
|
||||||
|
|
||||||
def add_actions(node : XML::Node)
|
def add_actions(node : XML::Node)
|
||||||
node.children.each do |child|
|
node.children.each do |child|
|
||||||
next unless child.element?
|
next unless child.element?
|
||||||
@ -47,9 +29,32 @@ module Tartrazine
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
struct Rule < BaseRule
|
||||||
|
property pattern : Regex = Regex.new ""
|
||||||
|
property actions : Array(Action) = [] of Action
|
||||||
|
|
||||||
|
def match(text : Bytes, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
||||||
|
match = pattern.match(text, pos)
|
||||||
|
|
||||||
|
# No match
|
||||||
|
return false, pos, [] of Token if match.size == 0
|
||||||
|
return true, pos + match[0].size, actions.flat_map { |action| action.emit(match, lexer) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(node : XML::Node)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(node : XML::Node, multiline, dotall, ignorecase)
|
||||||
|
pattern = node["pattern"]
|
||||||
|
pattern = "(?m)" + pattern if multiline
|
||||||
|
@pattern = Regex.new(pattern, multiline, dotall, ignorecase, true)
|
||||||
|
add_actions(node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# This rule includes another state. If any of the rules of the
|
# This rule includes another state. If any of the rules of the
|
||||||
# included state matches, this rule matches.
|
# included state matches, this rule matches.
|
||||||
class IncludeStateRule < Rule
|
struct IncludeStateRule < BaseRule
|
||||||
property state : String = ""
|
property state : String = ""
|
||||||
|
|
||||||
def match(text, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
def match(text, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
||||||
@ -62,7 +67,6 @@ module Tartrazine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def initialize(node : XML::Node)
|
def initialize(node : XML::Node)
|
||||||
@xml = node.to_s
|
|
||||||
include_node = node.children.find { |child|
|
include_node = node.children.find { |child|
|
||||||
child.name == "include"
|
child.name == "include"
|
||||||
}
|
}
|
||||||
@ -72,17 +76,14 @@ module Tartrazine
|
|||||||
end
|
end
|
||||||
|
|
||||||
# This rule always matches, unconditionally
|
# This rule always matches, unconditionally
|
||||||
class UnconditionalRule < Rule
|
struct UnconditionalRule < BaseRule
|
||||||
|
NO_MATCH = [] of Match
|
||||||
|
|
||||||
def match(text, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
def match(text, pos, lexer) : Tuple(Bool, Int32, Array(Token))
|
||||||
tokens = [] of Token
|
return true, pos, actions.flat_map { |action| action.emit(NO_MATCH, lexer) }
|
||||||
actions.each do |action|
|
|
||||||
tokens += action.emit([] of Match, lexer)
|
|
||||||
end
|
|
||||||
return true, pos, tokens
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(node : XML::Node)
|
def initialize(node : XML::Node)
|
||||||
@xml = node.to_s
|
|
||||||
add_actions(node)
|
add_actions(node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user