Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a guide for implementing custom HTML formatters #1415

Merged
merged 3 commits into from
Feb 5, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,55 @@ The built-in formatters are:
highlighted text for use in the terminal. `theme` must be an instance of
`Rouge::Theme`, or a `Hash` structure with `:theme` entry.

#### Writing your own HTML formatter

If the above formatters are not sufficient, and you wish to customize the layout
of the HTML document, we suggest writing your own HTML formatter. This can be
accomplished by subclassing `Rouge::Formatters::HTML` and overriding specific
methods:

``` ruby
class MyFormatter < Rouge::Formatters::HTML

# this is the main entry method. override this to customize the behavior of
# the HTML blob as a whole. it should receive an Enumerable of (token, value)
# pairs and yield out fragments of the resulting html string. see the docs
# for the methods available on Token.
def stream(tokens, &block)
yield "<div class='my-outer-div'>"

tokens.each do |token, value|
# for every token in the output, we render a span
yield span(token, value)
end

yield "</div>"
end

# or, if you need linewise processing, try:
def stream(tokens, &block)
token_lines(tokens).each do |line_tokens|
yield "<div class='my-cool-line'>"
line_tokens.each do |token, value|
yield span(token, value)
end
yield "</div>"
end
end

# Override this method to control how individual spans are rendered.
# The value `safe_value` will already be HTML-escaped.
def safe_span(token, safe_value)
# in this case, "text" tokens don't get surrounded by a span
if token == Token::Tokens::Text
safe_value
else
"<span class=\"#{token.shortname}\">#{safe_value}</span>"
end
end
end
```

### Lexer Options

* `debug: false` will print a trace of the lex on stdout.
Expand Down