Open pietroppeter opened 2 years ago
What about the new block nbCodeSkip
?
Should the global option enable line numbers for both, or only for nbCode
?
Should this work for nbPython
code blocks too?
IMO, we should have a single switch in nimib that all the official nbCode
-like blocks use. nbPython
will be moved to nimibex but I think we should implement it for it as well.
Yes I think one way to implement a global switch for all code like blocks would be to make sure that nbCodeSource
partial is general enough to support all code blocks and is used by all code blocks. Then implement a addLineNumbers
renderProc and make sure it is present in all code blocks. This proc would only adds line numbers if a boolean flag enableLineNumbers
is present (and true) in either block context or (only if not present) it would check the presence of enableLineNumbers true in doc context. In this way can have a global switch (add enable true in doc context), that can be switched off for specific blocks (add enable false to specific block). Also line numbers can be added only to specific blocks if disabled globally (add enable true for specific block).
notes from call nimib speaking hours:
proc addLineNumbers(doc: var NbDoc, blk: var NbBlock) =
if blk.context["enableLineNumbers].castBoolor doc.context["enableLineNumbers].castBool:
blk.context["codeHighlighted"] = addLineNumbersToHIghlightedCode(blk.context["codeHighlighted"].castStr)
template enableLineNumbersDoc =
nb.context["enableLineNumber"] = true
template enableLineNumbersBlock =
nb.blk.context["enableLineNumber"] = true
assert addLineNumbersToHIghlightedCode("""
func</span> decode(secret: openArray[<span class="hljs-built_in">int</span>]): <span class="hljs-built_in">string</span> =
<span class="hljs-comment">## classified by NSA as <strong>TOP SECRET</strong></span>
<span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> secret:
<span class="hljs-literal">result</span>.add <span class="hljs-built_in">char</span>(c)
""") == """
<span class="hljs-comment">1</span> func</span> decode(secret: openArray[<span class="hljs-built_in">int</span>]): <span class="hljs-built_in">string</span> =
<span class="hljs-comment">2</span> <span class="hljs-comment">## classified by NSA as <strong>TOP SECRET</strong></span>
<span class="hljs-comment">3</span> <span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> secret:
<span class="hljs-comment">4</span> <span class="hljs-literal">result</span>.add <span class="hljs-built_in">char</span>(c)
"""
I noticed that the example you gave to me has one issue. If someone tries to select the code, he would also select the line numbers. I have asked ChatGPT4 for a small html/JS example to render a code block snippet with a copy-to-clipboard button and lines numbering.
// Here is your code snippet
function helloWorld() {
console.log('Hello, world!');
}
```
It encloses the code inside <pre>
and <code>
tags which could be replaced by <span class="hljs-comment">
but inside a <pre>
. I do not know how I could do something similar as the JS code.
Hello, I am not sure how to integrate the last changes that I made in my draft Pull Request, to the code block template. I guess that I have to give as argument nb and nb.blk so my best guess for now is to change the template definition in src/nimib.nim:
template nbCode*(body: untyped) =
newNbCodeBlock("nbCode", body):
addLineNumbers(nb, nb.blk)
captureStdout(nb.blk.output):
body
This does absolutely nothing. Would you have any hint on how to proceed?
We have something we call renderPlan
which are procs that are run when we render a proc. We do the code highlighting in the renderPlan
for example. It is defined here: https://github.com/pietroppeter/nimib/blob/e256687a007f4e45e7f0291d5be96121aea9a470/src/nimib/renders.nim#L48
A renderPlan
consists of a list of renderProc
s that are run in order. So that would be the correct place to add this feature.
I think the reason your example doesn't work is because the codeHighlighted
hasn't been filled yet in the context because it is filled on render. So you pass in an empty string to your proc basically. And then it is overridden on render.
Let me know if you want a more thorough explaination, but it might take some time. I'm quite busy at the moment π
To flesh out my previous answer, you could say nimib has 3 phases when it generates a document:
render.nim
. nbCode: echo "Hello world"
. This will populate the block with its inputs in its context object. In the case of nbCode
these are the raw code and captured output. So the problem you had was that you tried to add the line numbers in step 2 while the highlighted code wasn't available until step 3. But if you add it as a renderProc and add it to the renderPlan och nbCode it should be available to you.
Thank you for the explanations. I was able to move forward and debug the code. There are still discussions to have on the enableLineNumbersBlock
and the HTML rendering of the numbers, but otherwise, I have a working proof of concept.
I wish you all the best for your work.
Awesome, thanks π regarding the copy-ability of the code blocks without including the line numbers, is wrapping the code in a table the usual solution to this? If so I'd say we could try it out and see how it works out π
If I believe the above JS generated by ChatGPT4 (thus highly not reliable), it's first approach is a div container. It replaces in the above HTML:
<div class="code-container">
<button id="copyButton" class="copy-button">Copy</button>
<pre id="code"><code class="line-numbers">1
2
3
4</code><code>// Here is your code snippet
function helloWorld() {
console.log('Hello, world!');
}</code></pre>
</div>
I am unsure of what is the βusualβ method here. It could be interpreted as table values as well as element of a div. I'll give in a second post a table solution.
from a google search, it appears there are alternative approaches that do not even need to add numbers in text but automatically generate them through css, it seems something we could explore if it works for us too: https://stackoverflow.com/a/41354764
Hello, I tried to update the HTML approach but I don't remember exactly what I had in mind for the HTML div approach. The table approach is too complex and risky. It removes code's indentation.
Both approaches, CSS and HTML should be tested, as some CSS styling might turn off line numbers. I think that generating them through CSS is the best approach, as it can be changed on the fly.
we were discussing about this with @HugoGranstrom during speaking hours, it is not clear to us how we can help? do you plan to work on the CSS one and we should discard the HTML one? to you want a review on the PR for the HTML approach (#220) and see if we can merge that? Let us know and thanks for working on this!
This css has an interesting recipe based on simple css and html manipulation: https://css.winterveil.net/
we should have the ability to add line numbers to code blocks, both those generate by
nbCode
andnbFile
. Ideally it should be something customizable by single block and one could set a global option. defaults would probably be to have it disabled in code blocks produce bynbCode
and maybe enabled for blocks produce bynbFile
.