How to preserve JS expressions unquoted in arguments

I can’t figure out how to preserve a JS expression in an HTML argument in html_write. Here is an example from the HTMX book (Extending HTML As Hypermedia). I want to generate this expression in HTML:

  <button hx-get="/contacts" hx-target="#main" hx-swap="outerHTML" hx-trigger="click, keyup[ctrlKey && key == 'L'] from:body">(1)

From the SWI docs (SWI-Prolog -- The HTTP server libraries) it looks to me as if the most promising rule for writing arguments would be:

“”"

  • Format-Arguments*:
    Use format/3 and emit the result as quoted value.
    “”"

So I would expect this to work:

button(['hx-get'(#(contacts_GET)),
        'hx-target'('#main'),
        'hx-swap'(outerHTML),
        'hx-trigger'('click, keyup[ctrlKey && key == "L"] from:body'-[])
       ],
       "Get the Contacts"),

But it always quotes the special characters:

<button hx-get="/contacts" hx-target="#main" hx-swap="outerHTML" hx-trigger="click, keyup[ctrlKey &amp;&amp; key == &quot;L&quot;] from:body">Get the Contacts</button>

I tried numerous other variants (too many to remember or list), but couldn’t find anything that worked.

I also played around with \js_call and \js_script and found that while js_script preserves characters, js_call doesn’t, which seems contrary to the docs:

\js_script("function foo() { return true && !false; }"),

script(language('text/javascript'),\js_call("foo(true && !false)")),
<script type="text/javascript">
function foo() { return true && !false; }
</script>
<script language="text/javascript">
foo(true &amp;&amp; !false)();

</script>

Full program: :- use_module(library(http/http_server)).:- use_module(library(http/http_files - Pastebin.com

Where am I going wrong? Is there another syntactic trick I am unaware of?

BTW, HTMX and SWI Prolog backend seems to be a promising combination.

Provided escaping inside html tag attribute value - Stack Overflow is correct, & always needs to be escaped. Quotes need to be escaped if they are not the open quote. Possibly using &#39; is more portable. Possibly we should first check the quotes inside the attribute and use the other quote to delimit the attributes.

Still, I think quoting should be fine. If I load your code into FF, the DOM is what one expects.

js_call//2 supposed to generate JavaScript function call expression from a function name and Prolog data. It should probably raise a domain/type error on a string.

Still, I think quoting should be fine. If I load your code into FF, the DOM is what one expects.

Oh blimey, you are actually right! It was my mistake that I didn’t get over the quoting to realize it actually works. Well, I had a capital letter in the binding instead of a lowercase one, and I only looked at the quoting.

Thanks Jan, for taking the time to respond!