nimib icon indicating copy to clipboard operation
nimib copied to clipboard

Can't use nbCode inside a template

Open HugoGranstrom opened this issue 1 year ago • 10 comments

Using the now default codeAsInSource has the following problem (codeFromAst doesn't have this problem):

nbCode (or any block reading code) can't be used inside another template. This is due to the fact that here, the code is looking for "nbCode" to start the command before the code block. But if we for example have:

template notNbCode(body: untyped) =
  nbCode:
    body

notNbCode:
  echo "Hello world"

Then, because the block that is created has command "nbCode", it will not find notNbCode to match it and will continue upwards to look for the start of the code block. And it will only find it when it reaches inside the definition of the notNbCode template.

Expected output

echo "Hello world"

Actual output

body

bCode:
ho "Hello world"

Other notes

template nbCodeInBlock*(body: untyped): untyped =
  block:
    nbCode:
      body

This only works because nbCodeInBlock happens to start with nbCode...

Possible solutions

  • Change the criterion for finding the startLine of the code block to use something else than the command string. The problem is how to reliably do that.
  • Implement the template as a block, borrowing renderplan and partial from nbCode
template notNbCode(body: untyped) =
  newNbCodeBlock("notNbCode", body):
    captureStdout(nb.blk.output):
      body

nb.renderPlans["notNbCode"] = nb.renderPlans["nbCode"]
nb.partials["notNbCode"] = nb.partials["nbCode"]

notNbCode:
  echo "Hello world"

HugoGranstrom avatar Sep 17 '22 16:09 HugoGranstrom

Thanks for the detailed write up (you might want adding a mention adding that this is an issue with - now default - CodeAsInSource and it disappears when using CodeFromAst).

This is an issue that will not easily go away until a better way to do CodeAsInSource is available (if it is indeed possible).

Situation is not too bad though, since I guess the request of using a newNbCodeBlock is not too heavy. And for a quick hack, I think the possibility of having this work by starting the new command with nbCode (as in nbCodeInBlock) is something that we might want to continue support in the meantime.

The important thing is to be aware of this (I did not know nbCodeInBlock worked by "chance"). This issue is a good first step, I plan to mention this in nimconf presentation and probably it might be worth to have a short section on limits of codeAsInSource somewhere in the documentation.

pietroppeter avatar Sep 18 '22 05:09 pietroppeter

Thanks for the detailed write up (you might want adding a mention adding that this is an issue with - now default - CodeAsInSource and it disappears when using CodeFromAst).

Good point :+1:

This is an issue that will not easily go away until a better way to do CodeAsInSource is available (if it is indeed possible).

I can look into this, but it won't get a very high priority until after NimConf.

Situation is not too bad though, since I guess the request of using a newNbCodeBlock is not too heavy. And for a quick hack, I think the possibility of having this work by starting the new command with nbCode (as in nbCodeInBlock) is something that we might want to continue support in the meantime.

The problems start when you want to use a template to combine multiple blocks and have to create a new custom block that combines their renderPlans and partials. That is a bit cumbersome. But for single blocks, it's not too bad.

The important thing is to be aware of this (I did not know nbCodeInBlock worked by "chance"). This issue is a good first step, I plan to mention this in nimconf presentation and probably it might be worth to have a short section on limits of codeAsInSource somewhere in the documentation.

Indeed. A new document named caveats or limitations does sound like a good idea :D

HugoGranstrom avatar Sep 18 '22 14:09 HugoGranstrom