Implemented decent version of the CLI

This commit is contained in:
Roberto Alsina 2024-08-11 11:49:42 -03:00
parent e40c8b586c
commit e295256573
4 changed files with 111 additions and 30 deletions

View File

@ -1,5 +1,5 @@
build: $(wildcard src/**/*.cr) $(wildcard lexers/*xml) $(wildcard styles/*xml) shard.yml build: $(wildcard src/**/*.cr) $(wildcard lexers/*xml) $(wildcard styles/*xml) shard.yml
shards build -Dstrict_multi_assign -Dno_number_autocast shards build -Dstrict_multi_assign -Dno_number_autocast -d --error-trace
release: $(wildcard src/**/*.cr) $(wildcard lexers/*xml) $(wildcard styles/*xml) shard.yml release: $(wildcard src/**/*.cr) $(wildcard lexers/*xml) $(wildcard styles/*xml) shard.yml
shards build --release shards build --release
static: $(wildcard src/**/*.cr) $(wildcard lexers/*xml) $(wildcard styles/*xml) shard.yml static: $(wildcard src/**/*.cr) $(wildcard lexers/*xml) $(wildcard styles/*xml) shard.yml

View File

@ -5,6 +5,22 @@ module Tartrazine
bake_folder "../lexers", __DIR__ bake_folder "../lexers", __DIR__
end end
# Get the lexer object for a language name
# FIXME: support aliases, paths, mimetypes, etc
def self.lexer(name : String) : Lexer
Lexer.from_xml(LexerFiles.get("/#{name}.xml").gets_to_end)
end
# Return a list of all lexers
# FIXME: support aliases
def self.lexers : Array(String)
lexers = Set(String).new
LexerFiles.files.each do |file|
lexers << file.path.split("/").last.split(".").first
end
lexers.to_a.sort!
end
# This implements a lexer for Pygments RegexLexers as expressed # This implements a lexer for Pygments RegexLexers as expressed
# in Chroma's XML serialization. # in Chroma's XML serialization.
# #
@ -173,8 +189,4 @@ module Tartrazine
# A token, the output of the tokenizer # A token, the output of the tokenizer
alias Token = NamedTuple(type: String, value: String) alias Token = NamedTuple(type: String, value: String)
def self.lexer(name : String) : Lexer
Lexer.from_xml(LexerFiles.get("/#{name}.xml").gets_to_end)
end
end end

View File

@ -1,35 +1,92 @@
require "docopt"
require "./**" require "./**"
HELP = <<-HELP HELP = <<-HELP
tartrazine: a syntax highlighting tool tartrazine: a syntax highlighting tool
Usage: Usage:
tartrazine (-h, --help)
tartrazine FILE -f html [-t theme][--standalone][--line-numbers] tartrazine FILE -f html [-t theme][--standalone][--line-numbers][-l lexer] [-o output]
[-l lexer] [-o output][--css] tartrazine -f html -t theme --css
tartrazine FILE -f terminal [-t theme][-l lexer][-o output] tartrazine FILE -f terminal [-t theme][-l lexer][-o output]
tartrazine FILE -f json [-o output] tartrazine FILE -f json [-o output]
tartrazine --list-themes tartrazine --list-themes
tartrazine --list-lexers tartrazine --list-lexers
tartrazine --list-formatters
tartrazine --version
-f <formatter> Format to use (html, terminal, json) Options:
-t <theme> Theme to use (see --list-themes) -f <formatter> Format to use (html, terminal, json)
-l <lexer> Lexer (language) to use (see --list-lexers) -t <theme> Theme to use, see --list-themes [default: default-dark]
-o <output> Output file (default: stdout) -l <lexer> Lexer (language) to use, see --list-lexers [default: plaintext]
--standalone Generate a standalone HTML file -o <output> Output file. Default is stdout.
--css Generate a CSS file for the theme --standalone Generate a standalone HTML file, which includes
--line-numbers Include line numbers in the output all style information. If not given, it will generate just
a HTML fragment ready to include in your own page.
--css Generate a CSS file for the theme called <theme>.css
--line-numbers Include line numbers in the output
-h, --help Show this screen
-v, --version Show version number
HELP HELP
lexer = Tartrazine.lexer("crystal") options = Docopt.docopt(HELP, ARGV)
theme = Tartrazine.theme(ARGV[1])
# formatter = Tartrazine::Json.new # Handle version manually
formatter = Tartrazine::Html.new if options["--version"]
formatter.standalone = true puts "tartrazine #{Tartrazine::VERSION}"
formatter.class_prefix = "hl-" exit 0
formatter.line_number_id_prefix = "ln-" end
formatter.line_numbers = true
formatter.highlight_lines = [3..7, 20..30] if options["--list-themes"]
formatter.linkable_line_numbers = false puts Tartrazine.themes.join("\n")
formatter.wrap_long_lines = false exit 0
puts formatter.format(File.read(ARGV[0]), lexer, theme) end
if options["--list-lexers"]
puts Tartrazine.lexers.join("\n")
exit 0
end
if options["--list-formatters"]
puts "html\njson\nterminal"
exit 0
end
if options["-f"]
formatter = options["-f"].as(String)
case formatter
when "html"
formatter = Tartrazine::Html.new
formatter.standalone = options["--standalone"] != nil
formatter.line_numbers = options["--line-numbers"] != nil
when "terminal"
formatter = Tartrazine::Ansi.new
when "json"
formatter = Tartrazine::Json.new
else
puts "Invalid formatter: #{formatter}"
exit 1
end
theme = Tartrazine.theme(options["-t"].as(String))
if formatter.is_a?(Tartrazine::Html) && options["--css"]
File.open("#{options["-t"].as(String)}.css", "w") do |outf|
outf.puts formatter.get_style_defs(theme)
end
exit 0
end
lexer = Tartrazine.lexer(options["-l"].as(String))
input = File.open(options["FILE"].as(String)).gets_to_end
output = formatter.format(input, lexer, theme)
if options["-o"].nil?
puts output
else
File.open(options["-o"].as(String), "w") do |outf|
outf.puts output
end
end
end

View File

@ -10,6 +10,11 @@ require "xml"
module Tartrazine module Tartrazine
alias Color = Sixteen::Color alias Color = Sixteen::Color
class ThemeFiles
extend BakedFileSystem
bake_folder "../styles", __DIR__
end
def self.theme(name : String) : Theme def self.theme(name : String) : Theme
begin begin
return Theme.from_base16(name) return Theme.from_base16(name)
@ -23,9 +28,16 @@ module Tartrazine
end end
end end
class ThemeFiles # Return a list of all themes
extend BakedFileSystem def self.themes
bake_folder "../styles", __DIR__ themes = Set(String).new
ThemeFiles.files.each do |file|
themes << file.path.split("/").last.split(".").first
end
Sixteen::DataFiles.files.each do |file|
themes << file.path.split("/").last.split(".").first
end
themes.to_a.sort!
end end
class Style class Style