'How to Escape Double Quotes on Prolog Web Server

I used the following Prolog code to display an HTML form with info_server(8000). but it doesn't work when a form item contains double-quotes. How can I escape the double quotes?

:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_error)).
:- use_module(library(http/html_write)).

:- use_module(library(http/http_client)).
:- http_handler('/', info_web_form, []).

info_server(Port) :-
        http_server(http_dispatch, [port(Port)]).

/*
browse http://localhost:8000/   
*/

       info_web_form(_Request) :-
                                                                                                                      format('Content-type: text/html~n~n', []),
                                                                            
data(Header,Footer), 

Loads the header and footer of the web page, which it reuses on different pages

format(Header,[]),

Displays the header

middle_form,

Displays the form

format(Footer,[]).

Displays the footer

                                                                                                  % When the form is submitted, it displays the landing page.
:- http_handler('/landing', landing_pad, []).

                                                                                                      landing_pad(Request) :-
                                                                                                              member(method(post), Request), !,
                                                                                                                  http_read_data(Request, Data, []),
                

                format('Content-type: text/html~n~n', []),

Data=[input=Input1, info=Hidden1, submit=_],
    
format(Input1,[]),

format(Hidden1,[]),

Displays the hidden data from the form, which is cut off because it contains double-quotes.

data(Header,Footer),

format(Header,[]),


middle_form,    

format(Footer,[]).


data(Header,Footer) :-

Header='<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>Title</title>
    <style type="text/css"> 
<!-- 

A:link {text-decoration: none;} 
A:visited {text-decoration: none;} 
A:hover {text-decoration: underline;} 

img {
 height: auto;
 max-width: 100%;
 object-fit: contain;
} 

table {table-layout: fixed; width: 100%;}

td {word-wrap: break-word;}

--> 
  </style>
  <!-- Displays text at readable size on both desktops and mobiles -->
    <meta name="viewport" content="width=device-width, initial-scale=1">

  </head>
  <!-- salmon coloured -->
  <body style="background-color: rgb(255, 239, 227);">

   
    <div style="text-align: center;">
      <table width="80%">
        <tbody>
          <tr>
            <td>
              <p>',

Footer='</p>
            </td>
          </tr>
        </tbody>
      </table>
      <br>

    <br>
  </body>
</html>'.


middle_form :-

Below is the hidden data, which is cut off with the double quote.

Hidden=[[a],"A",'a'],
    term_to_atom(Hidden,Hidden1),

Hidden1=Hidden2,
    concat_list(["
       
  <form action=\"/landing\" method=\"POST\">
  <label for=info></label>
  <input type=text id=input name=input value=''><br><br>
  <input type=hidden id=info name=info value=\"",Hidden2,"\"><br><br>
  <input type=submit name=submit value='Submit'>
</form>
"],Form_text1),
  

The call to atom_string below displays the form as an atom.

atom_string(Form_text,Form_text1),
    format(Form_text,[]).
    
    

The replace_new predicate replaces strings with strings in a string, for example replace_new('0ab0','a','c',A). A = "0cb0".

replace_new(A1,Find,Replace,F) :-
string_length(Replace,Replace_l),
string_concat("%",A1,A2),
string_concat(A2,"%",A),        split_string(A,Find,Find,B),findall([C,Replace],(member(C,B)),D),maplist(append,[D],[E]),concat_list(E,F1),string_concat(F2,G,F1),string_length(G,Replace_l),
    string_concat("%",F3,F2),   
    string_concat(F,"%",F3),!.
    

concat_list concatenates a list of strings to a string, for example: concat_list(["a","b","c"],D). D="abc"

concat_list([],""):- !.
concat_list(A1,B):-
    concat_list("",A1,B),!.

concat_list(A,List,B) :-
    concat_list1(A,List,B).

concat_list1(A,[],A):- !.
concat_list1(A,List,B) :-
    List=[Item|Items],
    string_concat(A,Item,C),
    concat_list1(C,Items,B).

When I view the web page at http://localhost:8000/, the hidden info value is partially lost when displayed on the landing page.



Solution 1:[1]

I worked out how to escape the double quotes, and it involved changing the code above from:

Hidden1=Hidden2,

to:

replace_new(Hidden1,"\"","&quot;",Hidden2), 

Making these changes replaces double quotes with &quot; and preserves the form data.

Note: This also assumes that the programmer uses double quotes around form data in <input type=hidden id=info name=info value=\"",Hidden2,"\">, eliminating single quotes in the data causing an error.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Lucian Green