nimib icon indicating copy to clipboard operation
nimib copied to clipboard

NbBlock as a container

Open pietroppeter opened this issue 1 year ago • 18 comments

currently you cannot nest block inside one another e.g. you cannot do stuff like:

nbCode:
   nbRawOutput: "<div>"
   echo "hello"
   nbRawOutput: "</div>

the above is not a great use case, a better use case would be to create html tabs:

nbTabs:
  tab("example 1"):
    nbText: "my example 1"
    nbCode: discard
  tab("example 2"):
    nbText: "my example 2"
    nbCode: discard
  tab("example 3"):
    nbText: "my example 3"
    nbCode: discard

and also nimislides has a similar use case when it does:

slide:
  slide:
    ...
  slide:
    ...

as a first thought there should be 3 changes to make:

  • change block making it a variant type based on a isContainer field. If it is container you have fields blocks: seq[NbBlock], blk: NbBlock as in NbDoc
  • need also to change nb object to track who is current container, either nb itself or some container block (so that the newNbBlock template can be called with correct container where to add the block)
  • finally we will need to change rendering, which should be straightforward

it is possible that this does not break too much the api, so it could be considered for 0.3.x

pietroppeter avatar Jul 13 '22 10:07 pietroppeter

Sounds good, something I've noticed is that we will probably have to take extra care of stdout capturing. Right now when we create a new block there are multiple things being echo'd by the newBlock template which would get in the way of our capturing. Also if we do

nbCode:
  nbCode:
    echo "Hello world"
  echo "Hello world again"

Which nbCode should capture the innermost "Hello world"?

HugoGranstrom avatar Jul 13 '22 10:07 HugoGranstrom

yes, that would be a possible issue (and the advice might just be: don't do that 😛), although in principle the current template captureStdout that we use might just work for that (it takes current stdout file pointer, creates a new file pointer when capturing then it puts it back).

pietroppeter avatar Jul 13 '22 10:07 pietroppeter

Haha ok then 🤣 Ohh 😮 yes that might actually work, but we would have to do something about the echos when creating a block as they will be captured by nbCode no matter how we do it. (Unless we disarm it around the echos specifically somehow without ignoring the bodies stdout)

HugoGranstrom avatar Jul 13 '22 10:07 HugoGranstrom

we would have to do something about the echos when creating a block as they will be captured by nbCode no matter how we do it.

ah right. in principle they could be not echos but something that is based on a stdout tracked initially... but honestly I do think that (at least in the beginning) we might just discourage people of nesting inside nbCode (or in general when captureStdout is involved).

pietroppeter avatar Jul 13 '22 10:07 pietroppeter

Now that I think of it we really don't want to nest things in nbCode either way as the output of that block has to be placed somewhere and I'm not entirely sure where it would be, it could very well be that it screws up the code block or something 😅 so yeah that's not a problem. It would be nice to be able to show how to use nimib in nimib without writing the code as strings but we have the "wrap it in a template and nbCode the template definition" for that 😎

HugoGranstrom avatar Jul 13 '22 10:07 HugoGranstrom

We could even automate that process with a specific nbNimibCode:

template nbNimibCode(body: untyped) =
  nbCode:
    template temp() {.gensym.} =
      body
  # Highjack the nbCode block:
  nb.blk.command = "nbNimibCode"
  temp()

and then add a step in the rendering plan of nbNimibCode which removes the first template line and unindents the code one step so the final code shown is just body.

This would allow us to do:

nbNimibCode:
  nbText: "Hello world"

without any problems with capturing stdout.

HugoGranstrom avatar Jul 13 '22 11:07 HugoGranstrom