yard
yard copied to clipboard
Syntax highlighting of code in other languages than Ruby?
I'm working on adding additional documentation in a .md
document that ships with the API docs. In the docs I have C/C++ code examples for Ruby C Extensions. However, these code blocks doesn't get any syntax coloring. Is it possible with YARD? Via some addon gem or something?
ah! I found this in the WhatsNew.md file:
https://github.com/lsegal/yard/blob/main/docs/WhatsNew.md#multiple-syntax-highlighting-language-support-050
On that note, it describes using !!!LANGNAME
to indicate language. Does that mean normal markdown method of spesifying langue doesn't work?
```c++
// ...
```
```ruby
# ...
```
Also, where does one add a html_syntax_highlight_LANGNAME
type method?
So, I already had a custom yard plugin with a custom template. And I tried adding it to templates/default/layout/html/setup.rb
def html_syntax_highlight_cpp(source)
formatter = Rouge::Formatters::HTML.new
lexer = Rouge::Lexers::Cpp.new
formatter.format(lexer.lex(source))
end
And this worked! Is this the canonical way to do this? (At least for a template. I'm guessing it would be different if I wanted to make a yard plugin gem that worked across templates?)
And this worked! Is this the canonical way to do this? (At least for a template. I'm guessing it would be different if I wanted to make a yard plugin gem that worked across templates?)
YARD::Templates::Helpers::HtmlHelper is the module that houses all the syntax highlighting methods, and would be the generic way to support such a plugin.
FWIW there are a few YARD syntax highlight plugins out there today. I would also recommend potentially injecting client-side highlighting JS libraries if you're only providing minimal amounts of visible code snippets. Highlight.js and equivalents would work seamlessly with most templates and could be brought in with a 1 line script injection.
YARD::Templates::Helpers::HtmlHelper is the module that houses all the syntax highlighting methods, and would be the generic way to support such a plugin.
So a plugin would open that namespace and add methods to it?
FWIW there are a few YARD syntax highlight plugins out there today. I would also recommend potentially injecting client-side highlighting JS libraries if you're only providing minimal amounts of visible code snippets. Highlight.js and equivalents would work seamlessly with most templates and could be brought in with a 1 line script injection.
Oh, interesting. I didn't find those in my search. (my RubyGems foo is poor). I'll have a look and see if they cover my needs.
So a plugin would open that namespace and add methods to it?
Yep. Adding custom markup formats works the same way.
Thank you for the insights.
And format is only extracted via !!!LANGNAME
notation, not via Markdown code block notation:
```c++
// ...
```
?
And format is only extracted via !!!LANGNAME notation, not via Markdown code block notation:
Nope, both work, !!!LANGNAME
is just a syntax to support indented blocks in RDoc formatting, which doesn't support language annotations (since it has no concept of fencing). YARD will post-process HTML output to detect the language type generated by Markdown and other processors:
https://github.com/lsegal/yard/blob/d61dac0fffb97c1fb40e8170e229d359f1ba31c6/lib/yard/templates/helpers/html_helper.rb#L640-L655
(edit: fixed code snippet link)
Thanks! I don't know why I didn't see it working before, but now I do. I also tried out some of the other plugins, but none worked properly for my purpose. Most promising and closest to success was yard-coderay, but it didn't handle C++ syntax well. But your feedback and looking at yard-coderay I think I have what I need to make my own using Rouge. Only thing I have to resolve is that Rouge generate separate CSS code, not inline. So I need to figure out who to write that to file and link into the doc.
hm... I'm only seeing the !!!LANG
syntax working.
I inspected the calls to the code extracter and detect_lang_in_codeblock_attributes
is getting passed two empty strings. The HTML that YARD parses is having code blocks that are plain <pre><code>...</code></pre>
. The ```cpp
syntax isn't adding any class annotations to the code blocks it generates.
The HTML that YARD parses is having code blocks that are plain
<pre><code>...</code></pre>
It would be a requirement for the Markdown processor library you're using to generate language-aware fenced code blocks. YARD doesn't do the generation for markdown, it's up to the library to understand fencing syntax-- since it's not a standard Markdown feature, not all libraries support it. Redcarpet (YARD's "first-choice" Markdown parser lib) should support this.
Hm... Our code docs are using Rdoc, because of legacy reasons. But we have markdown pages included in the docs for additional info. Is it possible to set which markdown provider to use for the .md files only without switching all the documentation to use markdown syntax?
Markdown files (.md) already use the markdown parser regardless of what is selected as the markup type; that said, yard doc options don't directly support changing the markup library provider (-M) for secondary markup types (i.e. the ones beyond what is selected with -m). You can do it with an extension / code though, specifically by manually reordering the list in YARD::Templates::Helpers::MarkupHelper
:
https://github.com/lsegal/yard/blob/d61dac0fffb97c1fb40e8170e229d359f1ba31c6/lib/yard/templates/helpers/markup_helper.rb#L24-L34
That said, I'm not sure why you'd need to do this, since you should be able to gem install redcarpet
. In fact, any of the top 3 providers should support fenced code blocks.