1:-module(tidylog_text, [text//2]).    2
    3% Describe Prolog text (quoted atoms, code lists, built-in strings)
    4
    5:- use_module(library(tidylog/common), [ parsing//0
    6                                       , when_generating//1
    7                                       , when_parsing//1
    8                                       ]).    9
   10text(Type,Text) -->
   11    when_generating(text_codes(Type,Text,Codes)),
   12
   13    quote(Type),
   14    content(Type,Codes),
   15    quote(Type),
   16
   17    when_parsing(text_codes(Type,Text,Codes)).
   18
   19
   20text_codes(atom,Atom,Codes) :-
   21    when(ground(Atom),atom(Atom)),
   22    atom_codes(Atom,Codes).
   23text_codes(codes,Codes,Codes).
   24text_codes(string,String,Codes) :-
   25    when(ground(String),string(String)),
   26    string_codes(String,Codes).
   27
   28
   29quote(Type) -->
   30    [C],
   31    { quote_char(Type,C) }.
   32
   33
   34quote_char(atom,0'').
   35quote_char(codes,0'`). %'
   36quote_char(string,0'"). %'
   37
   38
   39content(Type,[C|Codes]) -->
   40    "\\",
   41    [Esc],
   42    escape(Esc,Type,C),
   43    content(Type,Codes).
   44content(Type,[C|Codes]) -->
   45    quote(Type),
   46    quote(Type),
   47    { quote_char(Type,C) },
   48    content(Type,Codes).
   49content(Type,[C|Codes]) -->
   50    [C],
   51    content(Type,Codes).
   52content(_,[]) -->
   53    [].
   54
   55
   56% escape(Char,Type,Code)
   57escape(0's,_,0'\s) -->
   58    parsing.
   59escape(Q,Type,Q) -->
   60    { quote_char(Type,Q) }.
   61escape(Esc,_,C) -->
   62    { escape_char(Esc,C) }.
   63escape(C,_,C) -->
   64    parsing.
   65
   66
   67escape_char(0'\\, 0'\\).
   68escape_char(0'a, 0'\a).
   69escape_char(0'b, 0'\b).
   70escape_char(0'e, 0'\e).
   71escape_char(0'f, 0'\f).
   72escape_char(0'n, 0'\n).
   73escape_char(0'r, 0'\r).
   74escape_char(0't, 0'\t).
   75escape_char(0'v, 0'\v)