For those with knowledge of ancient coding one is familiar with the problem of trying to represent a string literal containing a string within the string.
My personal favorite solution to the problem is the triple quoted string. So often when I need to put a string within a string and format it nicely as input with SWI-Prolog I search for SWI-Prolog triple quoted string and then remember that the answer is not to be found that way.
Recently having the need to use JSON which is lots of strings on multiple lines, it would be nice to have something like triple quotes strings. If one knows that many of the SWI-Prolog predicates that accept strings also accept atoms, one can pass the value along as an atom that contains a string, e.g.
' "I am a string in an atom" '
The JSON data examples
Linear
{ "nodes": [], "edges": [] }
Multi-line
{
"nodes": [],
"edges": []
}
Examples:
% Notice the escape charters needed when the input value is a string.
example_string_linear :-
open_string("{ \"nodes\": [], \"edges\": [] }",Stream),
json_read_dict(Stream,Dict,[default_tag(graph)]),
format('Dict: ~w~n',[Dict]).
example_atom_linear :-
open_string('{ "nodes": [], "edges": [] }',Stream),
json_read_dict(Stream,Dict,[default_tag(graph)]),
format('Dict: ~w~n',[Dict]).
% Notice the escape charters needed when the input value is a string.
example_string_multiline :-
open_string("\c
{\n\c
\"nodes\":\n\c
[],\n\c
\"edges\":\n\c
[]\n\c
}",Stream),
json_read_dict(Stream,Dict,[default_tag(graph)]),
format('Dict: ~w~n',[Dict]).
example_atom_multiline :-
open_string('
{
"nodes": [],
"edges": []
}'
,Stream),
json_read_dict(Stream,Dict,[default_tag(graph)]),
format('Dict: ~w~n',[Dict]).
example_real_world :-
open_string('
{
"nodes": [
{
"data": {
"id": "a",
"name": "Glucose",
"image": "glucose.svg"
}
},
{
"data": {
"id": "b",
"name": "2pg",
"image": "2pg.svg"
}
}
],
"edges": [
{
"data" : {
"id": "ab",
"source": "a",
"target": "b"
}
}
]
}'
,Stream),
json_read_dict(Stream,Dict,[default_tag(graph)]),
format('Dict: ~w~n',[Dict]).
Clearly when the input is an atom and on multiple lines it is the most easy to comprehend. Also it is a cut and paste version of valid JSON, so no need to convert/add escape characters.
See: JSONLint - The JSON Validator
Example output:
?- example_string_linear.
Dict: graph{edges:[],nodes:[]}
true.
?- example_atom_linear.
Dict: graph{edges:[],nodes:[]}
true.
?- example_string_multiline.
Dict: graph{edges:[],nodes:[]}
true.
?- example_atom_multiline.
Dict: graph{edges:[],nodes:[]}
true.
?- example_real_world.
Dict: graph{edges:[graph{data:graph{id:ab,source:a,target:b}}],nodes:[graph{data:graph{id:a,image:glucose.svg,name:Glucose}},graph{data:graph{id:b,image:2pg.svg,name:2pg}}]}
true.
Personal notes
TODO: Quasi Quotation might also be a means and even a better means.