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

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

Related

What is the VS Code TextMate syntax for JSON inside an HTML attribute

I would like to add a grammar rule similar to the one found here. What that rule does is enable VSCode's JSON editor when it encounters an html file with
<script type="application/json">#Edit JSON</script>
What I would like is the same JSON editor support whenever it encounters a html attribute in this form:
<my-chart data='{"hello": "world"}'></my-chart>
In other words, any attribute that uses single quotes, inside of which it starts with a { and ends with a }, or starts with a [ and ends with a ].
Any suggestions what that should look like?
I've basically found a way. WIP

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.

How to apply metadata to all files in a content directory

I have a content directory called foo and I want all files under that directory to have an extra metadata item foovar: default, unless explicitly overridden in the file header. I think I'm supposed to do this with EXTRA_PATH_METADATA, but I can't figure out what incantation it wants.
(for my current use case I'm trying to apply template: sometemplate within this dir, but I'm interested in solving the general case as it would make several related headaches go away)
I think what you're looking for is actually DEFAULT_METADATA. Check out this portion of the documentation:
DEFAULT_METADATA = {}
The default metadata you want to use for all articles and pages.
So, in your case it might look something like this in your config file:
DEFAULT_METADATA = {'foovar': 'default'}
Then to assign your custom template(s), see this portion of the documentation.
This wasn't possible at the time I asked. I've since sent the devs a PR adding support, and it's been merged to master. Presumably it will go out in the next release. It makes EXTRA_PATH_METADATA recursive, so you can apply settings to a subdir like this:
EXTRA_PATH_METADATA = {'dirname/subdir': {'status': 'hidden'}}

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>

How to generate rdoc-style collapsable code sections?

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.