Class: DocsUI::Code
- Inherits:
-
Phlex::HTML
- Object
- Phlex::HTML
- DocsUI::Code
- Includes:
- Phlex::Rails::Helpers::ContentSecurityPolicyNonce
- Defined in:
- app/components/docs_ui/code.rb
Overview
A syntax-highlighted code block for docs and demo panels. Rouge does the highlighting; an optional filename/label sits in a title bar like a real docs code sample. Self-contained: it injects its own Rouge theme CSS so no separate stylesheet asset is required.
render DocsUI::Code.new(ruby_source) # ruby, no title
render DocsUI::Code.new(py, lexer: :python, filename: "a.py") # any language
Any language Rouge knows (~200 lexers) works by its name or alias — python, go, rust, elixir, kotlin, swift, json, dockerfile, ... — no allowlist. Add friendly lexer aliases via DocsKit.configure (code_lexer_aliases). An unknown language falls back to plaintext (never raises). (Tab labels are a DocsUI::Example concern — set via code_language_labels, not here; Code has no label, only a filename.)
Constant Summary collapse
- FORMATTER =
Rouge::Formatters::HTML.new
Instance Method Summary collapse
-
#initialize(source, lexer: :ruby, filename: nil) ⇒ Code
constructor
A new instance of Code.
- #view_template ⇒ Object
Constructor Details
#initialize(source, lexer: :ruby, filename: nil) ⇒ Code
Returns a new instance of Code.
25 26 27 28 29 |
# File 'app/components/docs_ui/code.rb', line 25 def initialize(source, lexer: :ruby, filename: nil) @source = source.to_s.strip @lexer = lexer @filename = filename end |
Instance Method Details
#view_template ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'app/components/docs_ui/code.rb', line 31 def view_template # Nonce the inline theme CSS so it survives a nonce-based style-src. Off a # request there is no nonce (see #csp_nonce) and Phlex omits a nil-valued # attribute, so the no-nonce markup is unchanged. style(nonce: csp_nonce) { highlight_css } resolved = lexer div(class: "not-prose my-4 overflow-hidden rounded-box border border-base-300 bg-base-300/40") do if @filename # data-md-lang carries the RESOLVED Rouge tag (ruby/python/plaintext/…) so # DocsKit::MarkdownExport emits a ```lang fence without re-resolving the # language. It's the real lexer tag, not the requested alias. div(class: "code-highlight overflow-x-auto p-4 text-sm leading-relaxed", data: { md_lang: resolved.tag }) do pre { raw(safe(FORMATTER.format(resolved.lex(@source)))) } end end end |