libasciidoc icon indicating copy to clipboard operation
libasciidoc copied to clipboard

Allow using unescape in templates to unescape HTML

Open DavidGamba opened this issue 3 years ago • 2 comments

I am working on a custom backend, mostly a copy of the xhtml5 one. For code content I need to wrap the content in CDATA blocks so I need the HTML to be unescaped.

Would you consider adding this functionality in core? I was thinking something like the following:

I can create a PR if you think it is valuable.

diff --git pkg/renderer/sgml/html_escape.go pkg/renderer/sgml/html_escape.go
index d168976..96190d1 100644
--- pkg/renderer/sgml/html_escape.go
+++ pkg/renderer/sgml/html_escape.go
@@ -1,6 +1,7 @@
 package sgml
 
 import (
+   "html"
    "strings"
 )
 
@@ -10,6 +11,10 @@ func EscapeString(s string) string {
    return htmlEscaper.Replace(s)
 }
 
+func UnescapeString(s string) string {
+   return html.UnescapeString(s)
+}
+
 var htmlEscaper = strings.NewReplacer(
    `<`, "<", // keep as-is (we do not want `<`)
    `>`, ">", // keep `&lgt;` as-is (we do not want `>`)
diff --git pkg/renderer/sgml/renderer.go pkg/renderer/sgml/renderer.go
index e9a7147..cd55aad 100644
--- pkg/renderer/sgml/renderer.go
+++ pkg/renderer/sgml/renderer.go
@@ -37,6 +37,7 @@ func NewRenderer(t Templates) Renderer {
    // Establish some default function handlers.
    r.functions = funcMap{
        "escape":              EscapeString,
+       "unescape":            UnescapeString,
        "trimRight":           trimRight,
        "trimLeft":            trimLeft,
        "trim":                trimBoth,

DavidGamba avatar Oct 24 '21 07:10 DavidGamba

hello @DavidGamba I'm fine with adding such an unescape func, but before that could you share an example so I can understand when you would need to use it?

xcoulon avatar Oct 25 '21 07:10 xcoulon

This is my source code template for a pseudo xhtml based backend (a la dockbook):

<programlisting>
  <![CDATA[
    {{ unescape .Content }}
    ]]>
</programlisting>

Since I am placing the code inside a CDATA block, I expect to pass the plain text representation of the text, not the HTML escaped one.

Because my backed is using the default sgml renderer, the current implementation of sgmlRendered.renderListingBlock uses the default renderSourceBlock and it seems there is quite a bit of logic with numbering and highlights and stuff so it is not easy to just override one method to avoid getting my source code quoted into HTML.

The easiest path to leverage the default sgml renderer is to add that UnescapeString to the FuncMap and use it as my example above shows.

But maybe there is a "proper" solution to be found somewhere that doesn't imply me copying the entire implementation of renderSourceBlock just to avoid escaping the text at the end. Maybe creating a new type, the source code block could leverage that type and maybe my override could just make that type to not execute a template but return the plain text.

DavidGamba avatar Oct 26 '21 05:10 DavidGamba