How to generate rdoc-style collapsable code sections? - documentation

I am creating internal documentation for a C++ project using Doxygen. I am having Doxygen include the source for methods, etc., but this makes the page kind of hard to scan. I'd like it to behave like rdoc and hide the source in a block that is collapsed by default.
I thought that HTML_DYNAMIC_SECTIONS might let me do this, but alas, the changelog says that option only affects diagrams and graphs.
Maybe I could do it by editing the LAYOUT_FILE?
Anyhow, smart people, how can I coerce Doxygen to generate collapsable code sections?

if includ[ing] the source for methods, etc, [...] makes the page kind of hard to scan, why don't you just link to it (SOURCE_BROWSER = YES) instead of including it (INLINE_SOURCES = YES)? this would make the pages easier to scan and faster to load, and the source would still be accessible (at the expense of one more source page load). depends on how often you actually need to access the source, i guess.
that being said, there is a way to generate collapsible code sections (you will have to modify the source and recompile Doxygen, though):
collapsible sections in Doxygen's HTML output are marked with two nested <div>s like so:
<div class="dynheader"><div class="dynsection">
[collapsible section]
</div></div>
included code sections are marked like so: <div class="fragment"><pre class="fragment">...</pre></div>
thus, to make the included code sections collapsible, you have to either
modify the code that generates the <div class="fragment"><pre class="fragment">...</pre></div> to generate <div class="dynheader"><div class="dynsection">...</div></div> (and probably adjust some css), or
change the javascript initDynSections() function that scans and collapses the collapsible sections to recognize <div class="fragment"><pre class="fragment"> as one of them.
the implementation (or going the SOURCE_BROWSER route :)) is left as an exercise for the reader. good luck!
oh, and if you should succeed with a patch, it would be great if you could submit it to dimitri so that he can include it in a future version. thanks!

coming along here using the search engine of my choice i just want to leave a note here that it is not absolutely necessary to modify any doxygen source.
When this question was asked there was probably no possibility to embed pure html using the htmlonly tag but with this in mind one is able to create foldable container sections abusing a function named toggleVisibility
function toggleVisibility(linkObj)
{
var base = $(linkObj).attr('id');
var summary = $('#'+base+'-summary');
var content = $('#'+base+'-content');
var trigger = $('#'+base+'-trigger');
var src=$(trigger).attr('src');
if (content.is(':visible')===true) {
content.hide();
summary.show();
$(linkObj).addClass('closed').removeClass('opened');
$(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
content.show();
summary.hide();
$(linkObj).removeClass('closed').addClass('opened');
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
}
return false;
}
that is currently available every time the documentation is generated in a file called dynsections.js placed in the documentation root.
Regarding this code one gets to know the conditions to be able to create foldable code from his/her own documentation using Javascript avoiding inner execution faults in this function and preventing further javascript code from being uninterpreted.
dom element with a unique identifier id
another encapsulated dom element with unique identifier id-summary
another encapsulated dom element with unique identifier id-content
another encapsulated dom element with unique identifier id-trigger
the id-trigger element must contain a src attribute with at least 1 character
the class attributes of the main containers do not matter
With theese conditions in mind one can create the following code.
## Fold me
## <div id="example-div">
## <div id="example-div-summary"></div>
## <div id="example-div-content">
## <pre>
## foo
## bar
## </pre>
## </div>
## <div id="example-div-trigger" src="-"></div>
## </div>
## #htmlonly <script type="text/javascript">$("#example-div").ready(function() { toggleVisibility($("#example-div")); });</script> #endhtmlonly
The doxygen code above is used to document bash code using bash-doxygen so it might look a bit different from pure doxygen code. The first part involving the div containers is already described mentioning the conditions to fit the source of the function toggleVisibility and make it executable without any errors adjusting the doxygen comments for our needs.
The unique id prefix used in here is example-div. In line one there is a hyperref link setup to unfold a section using javascript directly in conjunction with some jQuery code.
What's left is the one liner at the end. It contains the jQuery script need to be run to initially fold the specific segment. For the bash-doxygen (and probably other languages) the block needs to be a one liner because of the script's block scope
Normally the contents between \htmlonly and \endhtmlonly is inserted as-is. When you want to insert a HTML fragment that has block scope like a table or list which should appear outside <p>..</p>, this can lead to invalid HTML. You can use \htmlonly[block] to make doxygen end the current paragraph and restart it after \endhtmlonly.
as noticed in the doxygen documentation and a comment below the right marked solution of the stackoverflow answer on including script tags in doxygen documentations.
Thank you for reading.
Hope this helps some people that come along here.

Related

In Docusaurus, is there can I preserve capitalization in anchors created from headings in docs?

I'm using Docusaurus to publish documentation for an open source library's API. The headings of my source markdown files correspond to the names of methods and properties for classes in the library. This all works fine.
However, the anchors that are created in the HTML are all lowercase. I want them to respect the capitalization used in the markdown file.
For example, this markdown header:
###.doSomething()
Generates the following HTML:
<h3>
<a aria-hidden="true" tabindex="-1" class="..." id="dosomething"></a>.
<code>.doSomething()</code>
<a class="..." href="#dosomething" title="...">#</a>
</h3>
As you can see, camelCase is transformed to lowercase. I would like to keep capitalization intact. Is it possible?
P.S. The markdown files are automatically generated from jsdoc comments. In jsdoc, links to a method or properties include capitalization.
TL;DR
Inside your project, navigate to the directory node_modules > github-slugger;
Open the index.js file;
Remove the line if (!maintainCase) string = string.toLowerCase()
The function will become something like this:
function slugger (string, maintainCase) {
if (typeof string !== 'string') return ''
// if (!maintainCase) string = string.toLowerCase() <-- remove this!
return string.trim()
.replace(specials, '')
.replace(emoji(), '')
.replace(whitespace, '-')
}
IMPORTANT!
If you update the docusaurus, you may need to apply this change again;
It may be necessary to edit the doc to see the changes, because of cache. Here I edited the doc file and it worked;
You must restart the docusaurus service after you make this change. And probably needs to clear the cache with npm cache clear --force;
Also, I think you should delete the folder .docusaurus to force the rebuild of all documents.
RESULT
The .md file:
---
id: intro
---
# Random title
### WriNTinG with CaSeS
test 1
### .doAnotherThink()
test 3
### .doCamelCaseWithSeveralLETTERS()
test 3
ROADMAP
I must say that this one was hard. First I tried to track down the anchor tags, then the description. Eventually I found about the github-slugger, and looked like that was the way.
But once I made the changes, nothing had happened to the document! So after hours trying, I gave up… Then, just for curiosity, I decide to see what the slug function did to the document, by adding a second header with the same name. And — luck! — it kept the original case.
It turns out that you can simply use explicit IDs to solve this issue: https://docusaurus.io/docs/next/markdown-features/headings#explicit-ids

Go template is adding extra quotes to output

I want to use the value of my variable in Go template as-is but Go is adding extra quotes around it. E.g., for a Go template like
{{.Site}}:{{.Port}}/{{.Path}}
I want to get the output as
Mysite:3000/from/here
but the template is giving me the following instead:
"Mysite":"3000"/"from/here"
So,
How can I fix it (get rid of all the extra quotes or better suspend them all)? See https://play.golang.org/p/uKpgXdLv5gM
Go template also changed "orgId=1&refresh=30s" to orgId=1\u0026refresh=30s, how to avoid that?
Moreover, if I add https:// to the front of my url, the output is truncated. How to fix that as well?
Finally, is it possible to escape "`" within "`"?
As per Go HTML template doc:
HTML templates treat data values as plain text which should be encoded so they can be safely embedded in an HTML document. The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts.
The security model used by this package assumes that template authors are trusted, while Execute's data parameter is not. More details are provided below.
It means JavaScript escaping is enabled whenever the go HTML template engine detects that it is within a <script> tag, (i.e., it has nothing to do with whether using regular " or not as the first commenter thinks). So
to get the output as
Mysite:3000/from/here
instead of:
"Mysite":"3000"/"from/here"
Do not wrap it with <script> & </script> tag.
Do the concatenation after template Execute().
Again, with <script> & </script> tag wrapped around, I'm getting:
var url = `"Mysite":"3000"/"from/here"/${othervars}?"orgId=1\u0026refresh=30s"`
vs. without <script> & </script> tag wrapped around it, I'm getting:
var url = `Mysite:3000/from/here/${othervars}?orgId=1&refresh=30s`
Just what I need.
However, my actual case is that I'm using go HTML template engine to process my .html template files, so I cannot really do the concatenation afterwards, as everything is defined in the .html template file. So, just as Martin Gallagher has shown in his code, for such case, using template function seems to be the only option.
But even that might not be a viable option, as this is what I'm getting out of Martin's code:
var url = "Mysite:3000\/from\/here?orgId=1\u0026refresh=30s"
It is still not exactly what I wanted:
var url = `Mysite:3000/from/here/${othervars}?orgId=1&refresh=30s`
So maybe with such case, it indeed has no ideal solution.

Can I fill a websharper template's hole without knowing its name at compile time

I am new using WebSharper and I am stuck in the current situation with WebSharper 4:
I have the following html template (some-template.html) :
<div class="container">
<div ws-replace="Content">
</div>
</div>
It defines a content hole with the name Content. Usually, one could fill it using the following in code (F#):
type SomeTemplate = WebSharper.UI.Templating.Template<"some-template.html">
let doc = SomeTemplate().Content(someElements)
In my scenario, I do not know the name of the template and the hole at compile time. Suppose I have a function:
let buildDom(tempalte : string, holeName : string, content : Doc list) : Doc =
let template = WebSharper.UI.Template<tempalte> // (1)
// template.FillHole(holeName, content) (2)
I do not know how to best deal with (1) -- creating the template, and (2) - locating and filling the hole. Reflection comes to mind, but I would like to know if there is a more elegant and performant approach.
A more general question -- is there a good way to have dynamic composition of html-templated sitelets? This is what I am trying to achieve, but if it is alredy done there could be no need to reinvent the wheel. I'd appreciate if you point me to such resources if available as well.
You can pass a dynamic template by passing a string to the constructor:
type SomeTemplate = WebSharper.UI.Templating.Template<"some-template.html">
let doc = SomeTemplate("<div>...</div>").SomeHole("some content").Doc()
but the holes are still typed statically based on the type provider. There is currently no API to implement dynamic holes.
This could be a nice and useful addition though; you should post a suggestion on github.

Is there a way to do string replacement/substitution in sql?

I have some records in a CMS that include HTML fragments with custom tags for a widget tool. The maker of the CMS has apparently updated their CMS without providing proper data conversion. Their widgets use keys for layout based on screen width such as block_lg, block_md, block_sm. The problem kicks in with the fact they used to have a block_xs and they have now shifted them all -- dropping the block_xs and instead placing a block_xl on the other end.
We don't really use these things, but their widget configurations do. What this means for us is the values for each key are identical. The problem occurs when the updated CMS code is looking for the 'block_xl' in any widget definition tags, it can't find it and errors out.
What I'm thinking then is that the new code will appear to 'ignore' the block_xs due to how it reads the tags. (and similarly, the old code will ignore block_xl) Since the values for each are identical, I need to basically read any widget definition and add a block_xl value to it matching the value of [any one of] the other width parameters.
Since the best place order-wise would be 'before' the block_lg value, it's probably easiest to do it as follows:
Replace any thing matching posix style regex matching /block_lg(="\d+,\d+")/ with: block_xl="$1" block_lg="$1"
Or whatever the equivalent of that would be.
Example of an existing CMS block with multiple widget definitions:
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="The Album" classes="highlight-bottom modish greenfont font52 fontlight"
enable_fullwidth="0" block_ids="127" lazyload="0"
block_lg="127,12," block_md="127,12," block_sm="127,12," block_xs="127,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
<!-- Image Block -->
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="What’s Your Favorite Cover Style?"
classes="zoo-widget-style2 modish grey font26 fontlight"
enable_fullwidth="0" block_ids="126" lazyload="0"
block_lg="126,12," block_md="126,12," block_sm="126,12," block_xs="126,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
What I would prefer to end up with from the above (adding block_xl):
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="The Album" classes="highlight-bottom modish greenfont font52 fontlight"
enable_fullwidth="0" block_ids="127" lazyload="0"
block_xl="127,12," block_lg="127,12," block_md="127,12," block_sm="127,12," block_xs="127,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
<!-- Image Block -->
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="What’s Your Favorite Cover Style?"
classes="zoo-widget-style2 modish grey font26 fontlight"
enable_fullwidth="0" block_ids="126" lazyload="0"
block_xl="126,12," block_lg="126,12," block_md="126,12," block_sm="126,12," block_xs="126,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
I know how to do it in php and if necessary, I will just replace it on my local DB and write an sql script to update the modified records, but the html blocks can be kind of big in some cases. It would be preferable, if it is possible, to make the substitutions right in the SQL but I'm not sure how to do it or if it's even possible to do.
And yes, there can be more than one instance of a widget in any given cms page or block. (i.e. there may be a need for more than one such substitutions with different local 'values' assigned to the block_lg)
If anyone can help me do it in SQL, it would be greatly appreciated.
for reference, the tables effected are called cms_page and cms_block, the name of the row in both cases is content
SW

Get variables in Sphinx templates

I can't figure out how to get variables into Sphinx documents via a template. I am certainly making an elementary mistake, but while there is lots of documentation for using Jinja/Flask templates for web service and some documentation for Sphinx using it, I am having trouble doing the following. Maybe it's not possible and I'm barking up the wrong tree, but then this is fairly different from how variables work in general in web (as opposed to doc) templates?
I am working within a much larger project. Suppose in my project's conf.py I make a variable, say
LANGS = ['en', 'de', 'cn']
I know that this works because if I do the docbuild (we have a custom docbuild but I don't think it does anything really crazy other than a customized logger and eating a bunch of 'chatter') with the following line in conf.py
print len(LANGS)
it shows up during the docbuild.
But now of course I want to access this variable in my template. As far as I can tell, we override index.rst with templates/index.html, which inherits from the basic layout.html for Sphinx. And if I do
<p>We have {{ LANGS|len }} languages</p>
I get
We have 0 languages
Now, this is weird, because sometimes I can cause an error in the build by referring to variables not defined (though not consistently), so that somehow it 'knows' that the variable is defined but thinks it has length zero. Or does a "null" variable have length zero automatically?
How do I get this variable defined - or is it not possible?
What I want to do is then do something for each language in the list (make an outside link, in particular), but I figure there is no point in trying {% for %}/{% endfor %} or whatever if I can't get this working. Maybe Sphinx implements only a subset of Jinja?
Anyway, please help!
There are at least two ways to pass variables to a template:
Via html_context:
A dictionary of values to pass into the template engine’s context for all pages. Single values can also be put in this dictionary using the -A command-line option of sphinx-build.
Example:
# conf.py:
html_context = {'num_langs': len(LANGS)}
<!-- template: -->
<p>We have {{ num_langs }} languages</p>
Via the html_theme_options. This requires adding an option to theme.conf (you can create a theme by inheriting from a standard one):
[options]
num_langs = 1
Then you can set num_langs in conf.py via html_theme_options:
html_theme_options = {'num_langs': len(LANGS)}
and use it in a template:
<p>We have {{ theme_num_langs }} languages</p>