% This LaTeX document was generated using the LaTeX backend of PlDoc, % The SWI-Prolog documentation system \section{library(strings): String utilities} \label{sec:strings} \begin{tags} \mtag{See also}- \predref{format}{3} can format to a string as well. The \file{library(lynx/format)} provides primitive to wrap long strings. \\- The core system provides many additional string processing predicates. \tag{To be done} There are probably many other high level string predicates that belong in this library. For example, predicates similar to the functions in \url{https://docs.python.org/3/library/textwrap.html} \end{tags} This module provides string handling utilities, currently notably for dealing with multi-line strings and \textit{interpolation}. The library provides a couple of primitives as well definitions for the \const{string} \textit{quasi quotation} syntax. The latter allows for constructing both single line and multi-line long strings based on template interpolation. Below is a simple example using the quasi quotation syntax. \begin{code} test(To) :- write({|string(To)|| | Dear {To}, | | I'm happy to announce a string interpolation quasi quoter. |}. \end{code} \textbf{Warning} The general purpose string interpolation implemented by this library should \textbf{not} be used to create strings for a formal language such as HTML, JavaScript, SQL, etc. because the result will be subject to \textbf{injection attacks}, providing a serious \textbf{security risc}. The core idea of quasi quotation is to know about the target language and interpolate Prolog data into the template \textbf{while respecting the syntax of the target language}, notable to \textbf{escape certain characters where needed}. See also \file{library(http/html_write)} and \file{library(http/js_write)} which define quasi quotation rules for HTML and JavaScript.\vspace{0.7cm} \begin{description} \predicate{string}{4}{+Content, +Args, +Binding, -DOM} Implements the quasi quotation syntax \const{string}. If the first character of the content is a newline (i.e., there is a newline \textit{immediately} after the \verb$||$ token) this first uses \predref{dedent_lines}{3} to the remove common white space prefix from the lines. This is called with the option \verb$chars("\s\t|")$, i.e., also removing \verb$|$ characters and \verb$tab(8)$. If the quasi quotation syntax carries arguments (e.g., \verb$string(To)$), the string is compiled into a function that produces the result of interpolating the arguments into the template. See user functions on dict objects. If there are no arguments, the result is simply the final string. \begin{tags} \mtag{See also}- \predref{interpolate_string}{4} for the interpolation syntax. \\- Section for examples and discussion. \tag{To be done} Specify tab width and allow for \{@Goal\} templates. \end{tags} \predicate{interpolate_string}{4}{:In, -Out, +Map, +Options} Establish a string from a template by replacing patterns. Supported patterns are: \begin{description} \curltermitem{Name}If \arg{Map} contains \verb$Name=Value$, insert \arg{Value} using \predref{write}{1}. If \arg{Name} does not appear in \arg{Map}, raise an existence error. \arg{Name} must satisfy the rules for a Prolog variable.\curltermitem{Name,Default}As above, but if \arg{Name} does not appear in \arg{Map}, use \arg{Value}\curltermitem{@(Goal)}Insert the output (to \verb$current_output$) of \arg{Goal} here. For safety reasons only accepted if \arg{Options} contains \verb$goals(true)$ \end{description} \predicate[det]{string_lines}{2}{?String, ?Lines} True when \arg{String} represents \arg{Lines}. This follows the normal text convention that a line is defined as a possible empty string followed by a newline character ("\Bn{}"). E.g. \begin{code} ?- string_lines("a\nb\n", L). L = ["a", "b"]. ?- string_lines(S, ["a", "b"]). S = "a\nb\n". \end{code} This predicate is a true \textit{relation} if both arguments are in canonical form, i.e. all text is represented as strings and the first argument ends with a newline. The implementation tolerates non-canonical input: other types than strings are accepted and \arg{String} does not need to end with a newline. \begin{tags} \tag{See also} \predref{split_string}{4}. Using \verb$split_string(String, "\n", "", Lines)$ on a string that ends in a newline adds an additional empty string compared to \predref{string_lines}{2}. \end{tags} \predicate{dedent_lines}{3}{+In, -Out, +Options} Remove shared indentation for all lines in a string. Lines are separated by "\Bn{}" -- conversion to and from external forms (such as "\bsl{}r\Bn{}") are typically done by the I/O predicates. A final "\Bn{}" is preserved. \arg{Options}: \begin{description} \termitem{tab}{N} Assume tabs at columns of with \arg{N}. When omitted, tabs are taken literally and only exact matches are removed. \termitem{chars}{CodesOrString} Characters to remove. This can notably be used to remove additional characters such as \verb$*$ or `\Sbar{}`. Default is \verb$" \t"$. \end{description} \predicate[det]{indent_lines}{3}{+Prefix, +In, -Out} Add \arg{Prefix} to the beginning of lines in \arg{In}. Lines are separated by "\Bn{}" -- conversion to and from external forms (such as "\bsl{}r\Bn{}") are typically done by the I/O predicates. Lines that consist entirely of whitespace are left as-is. \predicate[det]{indent_lines}{4}{:Filter, +Prefix, +In, -Out} Similar to \predref{indent_lines}{3}, but only adds \arg{Prefix} to lines for which \verb$call(Filter, Line)$ succeeds. \end{description}