diff --git a/src/formatter.cr b/src/formatter.cr index 8336c00..12e0814 100644 --- a/src/formatter.cr +++ b/src/formatter.cr @@ -9,12 +9,15 @@ module Tartrazine # This is the base class for all formatters. abstract class Formatter property name : String = "" + property theme : Theme = Tartrazine.theme("default-dark") - def format(text : String, lexer : Lexer, theme : Theme) : String + # Format the text using the given lexer. + def format(text : String, lexer : Lexer) : String raise Exception.new("Not implemented") end - def get_style_defs(theme : Theme) : String + # Return the styles, if the formatter supports it. + def style_defs : String raise Exception.new("Not implemented") end end diff --git a/src/formatters/ansi.cr b/src/formatters/ansi.cr index e37aa66..5fb6ece 100644 --- a/src/formatters/ansi.cr +++ b/src/formatters/ansi.cr @@ -4,20 +4,23 @@ module Tartrazine class Ansi < Formatter property? line_numbers : Bool = false - def format(text : String, lexer : Lexer, theme : Theme) : String + def initialize(@theme : Theme = Tartrazine.theme("default-dark"), @line_numbers : Bool = false) + end + + def format(text : String, lexer : Lexer) : String output = String.build do |outp| lexer.group_tokens_in_lines(lexer.tokenize(text)).each_with_index do |line, i| label = line_numbers? ? "#{i + 1}".rjust(4).ljust(5) : "" outp << label line.each do |token| - outp << colorize(token[:value], token[:type], theme) + outp << colorize(token[:value], token[:type]) end end end output end - def colorize(text : String, token : String, theme : Theme) : String + def colorize(text : String, token : String) : String style = theme.styles.fetch(token, nil) return text if style.nil? if theme.styles.has_key?(token) diff --git a/src/formatters/html.cr b/src/formatters/html.cr index 64ae4ed..7b4be85 100644 --- a/src/formatters/html.cr +++ b/src/formatters/html.cr @@ -17,19 +17,35 @@ module Tartrazine property? wrap_long_lines : Bool = false property weight_of_bold : Int32 = 600 - def format(text : String, lexer : Lexer, theme : Theme) : String - text = format_text(text, lexer, theme) + property theme : Theme + + def initialize(@theme : Theme = Tartrazine.theme("default-dark"), *, + @highlight_lines = [] of Range(Int32, Int32), + @class_prefix : String = "", + @line_number_id_prefix = "line-", + @line_number_start = 1, + @tab_width = 8, + @line_numbers : Bool = false, + @linkable_line_numbers : Bool = true, + @standalone : Bool = false, + @surrounding_pre : Bool = true, + @wrap_long_lines : Bool = false, + @weight_of_bold : Int32 = 600,) + end + + def format(text : String, lexer : Lexer) : String + text = format_text(text, lexer) if standalone? - text = wrap_standalone(text, theme) + text = wrap_standalone(text) end text end # Wrap text into a full HTML document, including the CSS for the theme - def wrap_standalone(text, theme) : String + def wrap_standalone(text) : String output = String.build do |outp| outp << "" outp << text outp << "" @@ -37,21 +53,21 @@ module Tartrazine output end - def format_text(text : String, lexer : Lexer, theme : Theme) : String + def format_text(text : String, lexer : Lexer) : String lines = lexer.group_tokens_in_lines(lexer.tokenize(text)) output = String.build do |outp| if surrounding_pre? pre_style = wrap_long_lines? ? "style=\"white-space: pre-wrap; word-break: break-word;\"" : "" - outp << "
"
+          outp << "
"
         end
-        outp << ""
+        outp << ""
         lines.each_with_index(offset: line_number_start - 1) do |line, i|
           line_label = line_numbers? ? "#{i + 1}".rjust(4).ljust(5) : ""
-          line_class = highlighted?(i + 1) ? "class=\"#{get_css_class("LineHighlight", theme)}\"" : ""
+          line_class = highlighted?(i + 1) ? "class=\"#{get_css_class("LineHighlight")}\"" : ""
           line_id = linkable_line_numbers? ? "id=\"#{line_number_id_prefix}#{i + 1}\"" : ""
           outp << "#{line_label} "
           line.each do |token|
-            fragment = "#{token[:value]}"
+            fragment = "#{token[:value]}"
             outp << fragment
           end
         end
@@ -61,10 +77,10 @@ module Tartrazine
     end
 
     # ameba:disable Metrics/CyclomaticComplexity
-    def get_style_defs(theme : Theme) : String
+    def style_defs : String
       output = String.build do |outp|
         theme.styles.each do |token, style|
-          outp << ".#{get_css_class(token, theme)} {"
+          outp << ".#{get_css_class(token)} {"
           # These are set or nil
           outp << "color: ##{style.color.try &.hex};" if style.color
           outp << "background-color: ##{style.background.try &.hex};" if style.background
@@ -87,7 +103,7 @@ module Tartrazine
     end
 
     # Given a token type, return the CSS class to use.
-    def get_css_class(token, theme)
+    def get_css_class(token : String) : String
       return class_prefix + Abbreviations[token] if theme.styles.has_key?(token)
 
       # Themes don't contain information for each specific
@@ -99,6 +115,7 @@ module Tartrazine
       }]
     end
 
+    # Is this line in the highlighted ranges?
     def highlighted?(line : Int) : Bool
       highlight_lines.any?(&.includes?(line))
     end
diff --git a/src/main.cr b/src/main.cr
index 414ced9..35b3be0 100644
--- a/src/main.cr
+++ b/src/main.cr
@@ -54,6 +54,8 @@ if options["--list-formatters"]
   exit 0
 end
 
+theme = Tartrazine.theme(options["-t"].as(String))
+
 if options["-f"]
   formatter = options["-f"].as(String)
   case formatter
@@ -61,9 +63,11 @@ if options["-f"]
     formatter = Tartrazine::Html.new
     formatter.standalone = options["--standalone"] != nil
     formatter.line_numbers = options["--line-numbers"] != nil
+    formatter.theme = theme
   when "terminal"
     formatter = Tartrazine::Ansi.new
     formatter.line_numbers = options["--line-numbers"] != nil
+    formatter.theme = theme
   when "json"
     formatter = Tartrazine::Json.new
   else
@@ -71,11 +75,9 @@ if options["-f"]
     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)
+      outf.puts formatter.style_defs
     end
     exit 0
   end
@@ -83,7 +85,7 @@ if options["-f"]
   lexer = Tartrazine.lexer(name: options["-l"].as(String), filename: options["FILE"].as(String))
 
   input = File.open(options["FILE"].as(String)).gets_to_end
-  output = formatter.format(input, lexer, theme)
+  output = formatter.format(input, lexer)
 
   if options["-o"].nil?
     puts output