This commit is contained in:
Roberto Alsina 2024-08-22 21:58:21 -03:00
parent bd3df10d2c
commit a2884c4c78

View File

@ -10,37 +10,44 @@ module Tartrazine
# Get the lexer object for a language name # Get the lexer object for a language name
# FIXME: support mimetypes # FIXME: support mimetypes
def self.lexer(name : String? = nil, filename : String? = nil) : BaseLexer def self.lexer(name : String? = nil, filename : String? = nil) : BaseLexer
if name.nil? && filename.nil? return lexer_by_name(name) if name && name != "autodetect"
lexer_file_name = LEXERS_BY_NAME["plaintext"] return lexer_by_filename(filename) if filename
elsif name && name != "autodetect"
lexer_file_name = LEXERS_BY_NAME.fetch(name.downcase, nil) Lexer.from_xml(LexerFiles.get("/#{LEXERS_BY_NAME["plaintext"]}.xml").gets_to_end)
if lexer_file_name.nil? && name.includes? "+" end
# Delegating lexer
language, root = name.split("+", 2) private def self.lexer_by_name(name : String) : BaseLexer
language_lexer = lexer(language) lexer_file_name = LEXERS_BY_NAME.fetch(name.downcase, nil)
root_lexer = lexer(root) return create_delegating_lexer(name) if lexer_file_name.nil? && name.includes? "+"
return DelegatingLexer.new(language_lexer, root_lexer) raise Exception.new("Unknown lexer: #{name}") if lexer_file_name.nil?
elsif lexer_file_name.nil?
raise Exception.new("Unknown lexer: #{name}")
end
else
# Guess by filename
candidates = Set(String).new
LEXERS_BY_FILENAME.each do |k, v|
candidates += v.to_set if File.match?(k, File.basename(filename.to_s))
end
case candidates.size
when 0
lexer_file_name = LEXERS_BY_NAME["plaintext"]
when 1
lexer_file_name = candidates.first
else
raise Exception.new("Multiple lexers match the filename: #{candidates.to_a.join(", ")}")
end
end
Lexer.from_xml(LexerFiles.get("/#{lexer_file_name}.xml").gets_to_end) Lexer.from_xml(LexerFiles.get("/#{lexer_file_name}.xml").gets_to_end)
end end
private def self.lexer_by_filename(filename : String) : BaseLexer
candidates = Set(String).new
LEXERS_BY_FILENAME.each do |k, v|
candidates += v.to_set if File.match?(k, File.basename(filename))
end
case candidates.size
when 0
lexer_file_name = LEXERS_BY_NAME["plaintext"]
when 1
lexer_file_name = candidates.first
else
raise Exception.new("Multiple lexers match the filename: #{candidates.to_a.join(", ")}")
end
Lexer.from_xml(LexerFiles.get("/#{lexer_file_name}.xml").gets_to_end)
end
private def self.create_delegating_lexer(name : String) : BaseLexer
language, root = name.split("+", 2)
language_lexer = lexer(language)
root_lexer = lexer(root)
DelegatingLexer.new(language_lexer, root_lexer)
end
# Return a list of all lexers # Return a list of all lexers
def self.lexers : Array(String) def self.lexers : Array(String)
LEXERS_BY_NAME.keys.sort! LEXERS_BY_NAME.keys.sort!