feat: Support custom template for HTML standalone output

This commit is contained in:
Roberto Alsina 2025-02-21 19:43:09 -03:00
parent ed61a84553
commit aabe028767
3 changed files with 54 additions and 7 deletions

View File

@ -127,6 +127,33 @@ pico
Be careful not to build without any themes at all, nothing will work.
## Templates for standalone HTML output
If you are using the HTML formatter, you can pass a template to use for the output. The template is a string where the following placeholders will be replaced:
* `{{style_defs}}` will be replaced by the CSS styles needed for the theme
* `{{code}}` will be replaced by the highlighted code
This is an example template that changes the padding around the code:
```jinja2
<!DOCTYPE html>
<html>
<head>
<style>
{{style_defs}}
pre {
padding: 1em;
}
</style>
</head>
<body>
{{body}}
</body>
</html>
```
## Contributing
1. Fork it (<https://github.com/ralsina/tartrazine/fork>)

View File

@ -28,6 +28,13 @@ module Tartrazine
property? surrounding_pre : Bool = true
property? wrap_long_lines : Bool = false
property weight_of_bold : Int32 = 600
property template : String = <<-TEMPLATE
<!DOCTYPE html><html><head><style>
{{style_defs}}
</style></head><body>
{{body}}
</body></html>
TEMPLATE
property theme : Theme
@ -42,7 +49,8 @@ module Tartrazine
@standalone : Bool = false,
@surrounding_pre : Bool = true,
@wrap_long_lines : Bool = false,
@weight_of_bold : Int32 = 600)
@weight_of_bold : Int32 = 600,
@template : String = @template)
end
def format(text : String, lexer : Lexer) : String
@ -61,11 +69,15 @@ module Tartrazine
# Wrap text into a full HTML document, including the CSS for the theme
def wrap_standalone
output = String.build do |outp|
outp << "<!DOCTYPE html><html><head><style>"
outp << style_defs
outp << "</style></head><body>"
if @template.includes? "{{style_defs}}"
outp << @template.split("{{style_defs}}")[0]
outp << style_defs
outp << @template.split("{{style_defs}}")[1].split("{{body}}")[0]
else
outp << @template.split("{{body}}")[0]
end
end
{output.to_s, "</body></html>"}
{output.to_s, @template.split("{{body}}")[1]}
end
private def line_label(i : Int32) : String

View File

@ -10,8 +10,8 @@ Keep in mind that not all formatters support all features.
Usage:
tartrazine (-h, --help)
tartrazine FILE -f html [-t theme][--standalone][--line-numbers]
[-l lexer][-o output]
tartrazine FILE -f html [-t theme][--standalone [--template file]]
[--line-numbers][-l lexer][-o output]
tartrazine -f html -t theme --css
tartrazine FILE -f terminal [-t theme][-l lexer][--line-numbers]
[-o output]
@ -35,6 +35,7 @@ Options:
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
--template <file> Use a custom template for the HTML output [default: none]
--line-numbers Include line numbers in the output
-h, --help Show this screen
-v, --version Show version number
@ -64,6 +65,12 @@ if options["--list-formatters"]
end
theme = Tartrazine.theme(options["-t"].as(String))
template = options["--template"].as(String)
if template != "none" # Otherwise we will use the default template
template = File.open(template).gets_to_end
else
template = nil
end
if options["-f"]
formatter = options["-f"].as(String)
@ -73,6 +80,7 @@ if options["-f"]
formatter.standalone = options["--standalone"] != nil
formatter.line_numbers = options["--line-numbers"] != nil
formatter.theme = theme
formatter.template = template if template
when "terminal"
formatter = Tartrazine::Ansi.new
formatter.line_numbers = options["--line-numbers"] != nil