Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rendering a custom block with contents that should not be displayed #52

Closed
finanalyst opened this issue Nov 16, 2024 · 15 comments
Closed

Comments

@finanalyst
Copy link
Contributor

@thoughtstream Your thoughts? @lizmat @codesections @vrurg please clarify if I have not got this right.

Suppose there is a custom block which has contents in the RakuDoc source which should only be shown if the custom block is correctly executed. But if the renderer does not recognise the Custom block, or the output format does not support the intended custom output, there should be a defined mechanism for not displaying the content.

For example,

=begin InLineImage
<data in base64>
=end InLineImage

Alternatively the contents might include some SQL the author would prefer is not displayed

The suggestion is to have a metadata option available for all custom blocks, eg. :not-rendered<ignore>

If a custom block has :not-rendered<ignore> AND the renderer does not recognise the custom block, then instead of rendering the contents of the custom block as text (the current fallback), the contents would be ignored, with perhaps a message that the contents are ignored.

@thoughtstream
Copy link

As far as I can tell, there are actually four possible responses
when a renderer encounters a user-defined block that
it doesn’t know how to handle:

  • Fall back on plaintext, and emit a warning
  • Don’t render it at all, but emit a warning
  • Fall back on plaintext, but don’t emit a warning
  • Don’t render it at all, and don’t emit a warning

In other words, there are actually two orthogonal boolean metaflags
needed here:

  • :warn / :!warn
  • :fallback / :!fallback

(Note: I’m not wed to those particular names, but you get the idea).

We define the default behaviour on encountering an unknown block type to be: :warn :fallback,
but the end-user can reconfigure individual user-defined blocks to any other preferred combination
of the two options.

@codesections
Copy link
Contributor

codesections commented Nov 17, 2024

That seems like good behavior when :warn or :fallback have boolean values, but it would be ideal if they could also have string values (just as an <img> that can't be displayed is replaced by it's alt attribute in HTML).

For example, the base64 image could be replaced with ASCII-art (especially if it depicted a flow chart or similar, which seems reasonable in the doc context)

@finanalyst
Copy link
Contributor Author

@codesections I think the specification should be the simplest possible, and actions that can be unabiguously enabled.
We are discussing here custom blocks and contents about with there is no information whatsoever. Ignoring the contents or rendering them as text are both unambiguous because the RakuDoc source is itself text based.
The idea of ASCII art in place of base64 implies there is information about the contents.

@codesections
Copy link
Contributor

Ignoring the contents or rendering them as text are both unambiguous because the RakuDoc source is itself text based.

Agreed. But rendering replacement text instead of the contents is equally unambiguous for the same reason.

@finanalyst
Copy link
Contributor Author

@codesections

But rendering replacement text instead of the contents is equally unambiguous for the same reason
Not sure what you mean here.
Suppose we have

=begin MyUnsupportedBlock
9203u42j3nde)U**UHUIHA
=end MyUnsupportedBlock

In order to enter the meaningless data 9203u42j3nde)U**UHUIHA into a RakuDoc source, it has to be in some Unicode set of characters.
So for :fallback, the result would be something like

Unknown block "MyUnsupportedBlock"
9203u42j3nde)U**UHUIHA

together with a warning message

If, however, :!fallback (fallback is False), nothing at all would be rendered, but a warning message would be generated.

There is no replacement text, just the text version of the source.

@codesections
Copy link
Contributor

Right, but I'm suggesting that we allow replacement text with :fallback. So your example might turn into

=begin MyUnsupportedBlock :fallback('[The "Password Strength xkcd webcomic, available at https://xkcd.com/936]') :!warning
9203u42j3nde)U**UHUIHA
=end MyUnsupportedBlock

Which would render

[The "Password Strength" xkcd webcomic, available at https://xkcd.com/936/]

My point is that letting :fallback supply replacement text is just as unambiguous as rendering 9203u42j3nde)U**UHUIHA as text, because both need to be entered in RakuDoc source.

(That wouldn't be true if :fallback could contain a non-text value, but that's not what I'm proposing.)

@vrurg
Copy link

vrurg commented Nov 18, 2024

First of all, whichever solution is eventually chosen it has to be globally configurable for cases when potentially unrenderable blocks are rather common within document body. Remembering to always add :not-rendered or whichever is tedious and thus – error-prone.

The :fallback("text") is about to be it, especially if it can be set globally per block type. I emphasize the "per" because the text could explain how to get that block rendering work.

For less common cases where block content could be replaced with meaningful textual representation I was having in mind something like this:

=begin MyCustom
....
=else 
If you see this message then check out L<this link|https://...> or refer to L<#Rendering> section.
=end

If the =else is actually another form of =begin but with a bit different semantics then the following is possible:

=begin SVG 
...
=else Img
....
=else 
...
=end

So that if SVG is the best to represent a concept but rarely used renderer then more common Img can replace it (though it wouldn't do all the author expects from SVG). Apparently, if none of two are part of the rendering system then the plain RakuDoc block will come to help.

@codesections
Copy link
Contributor

^^^ seems like a good approach, but I'm not sure about the =end at the end. Typically, it wouldn't be a bare =end, right? So, where it might be =end SVG – but that gets slightly confusing with the Img in between. Bikeshedding slightly, maybe it should be

=begin SVG 
...
=orbegin Img
....
=elsebegin para 
...
=end SVG

That draws on
https://docs.raku.org/language/control#with_orwith_without but maybe that's not the right control structure – I'm open to other ideas. I feel that we could draw on some existing control structure, though.

@thoughtstream
Copy link

Note that we already provide an :alt metaoption for formulae.
There is no reason it couldn't be enabled for user-defined blocks as well.
Then :fallback could remain a boolean metaoption.

Of course, that isn't as powerful as the "control structure" approaches @vrurg and @codesections have suggested.
I need to think about those approaches a little longer. I'm not happy with either the bare =end (in @vrurg's example)
or the missing =end Img and =end para (in @codesections' example).

@finanalyst
Copy link
Contributor Author

If there is a consensus that a more powerful control structure needs to be added, then I think this should be a part of the next specification (RakuDoc v3). It will considerably change the specification as it stands now. Implementing such a change will not be simple. What needs to be considered is the consequence of these conditional structures when embedded in other RakuDoc blocks.

Futhermore, we are only discussing custom blocks at present. They are not yet widely used because only my Raku::Pod::Render and RakuAST::RakuDoc::Render modules allow for custom blocks. Pod::To::HTML did not allow for them. Consequently, there is not much use of them in the wild. I would suggest that before introducing extra complexity now, we allow for some use of the existing functionality and see what other changes need to be made.

I would also suggest looking at issue #51 about DOC use. I have outlined some of the existing complexity of rendering custom blocks.

A simple :fallback and :error is easy to implement and consistent with the :toc option. A heading or custom block by default have :toc while =para and =nested have a default :!toc. This means that by default =head is included in the toc, while paragraphs and indented paragraphs are not included in the TOC, but could be if desired.

We would only need to decide which value of :fallback and :error are default. My strong preference is for both to be True by default. This is because it is only the author who wants to hide something that will need to include :!fallback and :!error. This would deal with @vrurg's concern about forgetting about including them.

@thoughtstream
Copy link

I agree that further discussion of these proposed more-powerful features should be tabled for now
and revisited in the future when the RakuDoc v3 spec is being considered.

However, as an interim measure, I think we should allow user-defined blocks to optionally specify
an :alt metaoption (i.e. just like a formula block can). If this metaoption is present,
its contents would become the fallback rendering (i.e. instead than rendering the block's raw contents).
The render-the-raw-contents fallback behaviour would, of course, still apply if the unrenderable
user-defined block doesn't specify an :alt.

I also agree that the defaults for the two new boolean metaoptions should both be True.

However, I still think that :warn (a verb) would be a better name than :error (a noun).
Mostly because I think of errors as begin serious/fatal, which being unable to properly render
a user-defined block clearly isn't.

@finanalyst
Copy link
Contributor Author

@codesections The :alt suggestion by @thoughtstream seems best as the overide. An empty :alt would be an empty string, so would be the minimal.
@thoughtstream I was wondering about extending :error or rather :!error. Since this is a different issue, I am raising it separately.

@finanalyst
Copy link
Contributor Author

I will raise a PR to introduce explicit text about :alt for custom blocks.

@finanalyst
Copy link
Contributor Author

closing as resolved. for the time being

@finanalyst
Copy link
Contributor Author

closing as resolved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants