[1X6 String and Text Utilities[0X [1X6.1 Text Utilities[0X This section describes some utility functions for handling texts within [5XGAP[0m. They are used by the functions in the [5XGAPDoc[0m package but may be useful for other purposes as well. We start with some variables containing useful strings and go on with functions for parsing and reformatting text. [1X6.1-1 WHITESPACE[0m [2X> WHITESPACE_________________________________________________[0Xglobal variable [2X> CAPITALLETTERS_____________________________________________[0Xglobal variable [2X> SMALLLETTERS_______________________________________________[0Xglobal variable [2X> LETTERS____________________________________________________[0Xglobal variable [2X> DIGITS_____________________________________________________[0Xglobal variable [2X> HEXDIGITS__________________________________________________[0Xglobal variable These variables contain sets of characters which are useful for text processing. They are defined as follows. [8X[10XWHITESPACE[0m[8X[0m [10X" \n\t\r"[0m [8X[10XCAPITALLETTERS[0m[8X[0m [10X"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[0m [8X[10XSMALLLETTERS[0m[8X[0m [10X"abcdefghijklmnopqrstuvwxyz"[0m [8X[10XLETTERS[0m[8X[0m concatenation of [10XCAPITALLETTERS[0m and [10XSMALLLETTERS[0m [8X[10XDIGITS[0m[8X[0m [10X"0123456789"[0m [8X[10XHEXDIGITS[0m[8X[0m [10X"0123456789ABCDEFabcdef"[0m [1X6.1-2 TextAttr[0m [2X> TextAttr___________________________________________________[0Xglobal variable The record [2XTextAttr[0m contains strings which can be printed to change the terminal attribute for the following characters. This only works with terminals which understand basic ANSI escape sequences. Try the following example to see if this is the case for the terminal you are using. It shows the effect of the foreground and background color attributes and of the [10X.bold[0m, [10X.blink[0m, [10X.normal[0m, [10X.reverse[0m and[10X.underscore[0m which can partly be mixed. [4X--------------------------- Example ----------------------------[0X [4Xextra := ["CSI", "reset", "delline", "home"];;[0X [4Xfor t in Difference(RecNames(TextAttr), extra) do[0X [4X Print(TextAttr.(t), "TextAttr.", t, TextAttr.reset,"\n");[0X [4Xod;[0X [4X------------------------------------------------------------------[0X The suggested defaults for colors [10X0..7[0m are black, red, green, brown, blue, magenta, cyan, white. But this may be different for your terminal configuration. The escape sequence [10X.delline[0m deletes the content of the current line and [10X.home[0m moves the cursor to the beginning of the current line. [4X--------------------------- Example ----------------------------[0X [4Xfor i in [1..5] do [0X [4X Print(TextAttr.home, TextAttr.delline, String(i,-6), "\c"); [0X [4X Sleep(1); [0X [4Xod;[0X [4X------------------------------------------------------------------[0X Whenever you use this in some printing routines you should make it optional. Use these attributes only, when the variable [10XANSI_COLORS[0m has the value [9Xtrue[0m. [1X6.1-3 WrapTextAttribute[0m [2X> WrapTextAttribute( [0X[3Xstr, attr[0X[2X ) ___________________________________[0Xfunction [6XReturns:[0X a string with markup The argument [3Xstr[0m must be a text as [5XGAP[0m string, possibly with markup by escape sequences as in [2XTextAttr[0m ([14X6.1-2[0m). This function returns a string which is wrapped by the escape sequences [3Xattr[0m and [10XTextAttr.reset[0m. It takes care of markup in the given string by appending [3Xattr[0m also after each given [10XTextAttr.reset[0m in [3Xstr[0m. [4X--------------------------- Example ----------------------------[0X [4Xgap> str := Concatenation("XXX",TextAttr.2, "BLUB", TextAttr.reset,"YYY");[0X [4X"XXX\033[32mBLUB\033[0mYYY"[0X [4Xgap> str2 := WrapTextAttribute(str, TextAttr.1);[0X [4X"\033[31mXXX\033[32mBLUB\033[0m\033[31mYYY\033[0m"[0X [4Xgap> str3 := WrapTextAttribute(str, TextAttr.underscore);[0X [4X"\033[4mXXX\033[32mBLUB\033[0m\033[4mYYY\033[0m"[0X [4Xgap> # use Print(str); and so on to see how it looks like.[0X [4X------------------------------------------------------------------[0X [1X6.1-4 FormatParagraph[0m [2X> FormatParagraph( [0X[3Xstr[, len][, flush][, attr][, widthfun], ]][0X[2X ) ___[0Xfunction [6XReturns:[0X the formatted paragraph as string This function formats a text given in the string [3Xstr[0m as a paragraph. The optional arguments have the following meaning: [8X[3Xlen[0m[8X[0m the length of the lines of the resulting text (default is [10X78[0m) [8X[3Xflush[0m[8X[0m can be [10X"left"[0m, [10X"right"[0m, [10X"center"[0m or [10X"both"[0m, telling that lines should be flushed left, flushed right, centered or left-right justified, respectively (default is [10X"both"[0m) [8X[3Xattr[0m[8X[0m is a list of two strings; the first is prepended and the second appended to each line of the result (can for example be used for indenting, [10X[" ", ""][0m, or some markup, [10X[TextAttr.bold, TextAttr.reset][0m, default is [10X["", ""][0m) [8X[3Xwidthfun[0m[8X[0m must be a function which returns the display width of text in [3Xstr[0m. The default is [10XLength[0m assuming that each byte corresponds to a character of width one. If [3Xstr[0m is given in [10XUTF-8[0m encoding one can use [2XWidthUTF8String[0m ([14X6.2-3[0m) here. This function tries to handle markup with the escape sequences explained in [2XTextAttr[0m ([14X6.1-2[0m) correctly. [4X--------------------------- Example ----------------------------[0X [4Xgap> str := "One two three four five six seven eight nine ten eleven.";;[0X [4Xgap> Print(FormatParagraph(str, 25, "left", ["/* ", " */"])); [0X [4X/* One two three four five */[0X [4X/* six seven eight nine ten */[0X [4X/* eleven. */[0X [4X------------------------------------------------------------------[0X [1X6.1-5 SubstitutionSublist[0m [2X> SubstitutionSublist( [0X[3Xlist, sublist, new[, flag][0X[2X ) ________________[0Xfunction [6XReturns:[0X the changed list This function looks for (non-overlapping) occurrences of a sublist [3Xsublist[0m in a list [3Xlist[0m (compare [2XPositionSublist[0m ([14XReference: PositionSublist[0m)) and returns a list where these are substituted with the list [3Xnew[0m. The optional argument [3Xflag[0m can either be [10X"all"[0m (this is the default if not given) or [10X"one"[0m. In the second case only the first occurrence of [3Xsublist[0m is substituted. If [3Xsublist[0m does not occur in [3Xlist[0m then [3Xlist[0m itself is returned (and not a [10XShallowCopy(list)[0m). [4X--------------------------- Example ----------------------------[0X [4Xgap> SubstitutionSublist("xababx", "ab", "a");[0X [4X"xaax"[0X [4X------------------------------------------------------------------[0X [1X6.1-6 StripBeginEnd[0m [2X> StripBeginEnd( [0X[3Xlist, strip[0X[2X ) _____________________________________[0Xfunction [6XReturns:[0X changed string Here [3Xlist[0m and [3Xstrip[0m must be lists. This function returns the sublist of list which does not contain the leading and trailing entries which are entries of [3Xstrip[0m. If the result is equal to [3Xlist[0m then [3Xlist[0m itself is returned. [4X--------------------------- Example ----------------------------[0X [4Xgap> StripBeginEnd(" ,a, b,c, ", ", ");[0X [4X"a, b,c"[0X [4X------------------------------------------------------------------[0X [1X6.1-7 StripEscapeSequences[0m [2X> StripEscapeSequences( [0X[3Xstr[0X[2X ) ______________________________________[0Xfunction [6XReturns:[0X string without escape sequences This function returns the string one gets from the string [3Xstr[0m by removing all escape sequences which are explained in [2XTextAttr[0m ([14X6.1-2[0m). If [3Xstr[0m does not contain such a sequence then [3Xstr[0m itself is returned. [1X6.1-8 RepeatedString[0m [2X> RepeatedString( [0X[3Xc, len[0X[2X ) _________________________________________[0Xfunction Here [3Xc[0m must be either a character or a string and [3Xlen[0m is a non-negative number. Then [2XRepeatedString[0m returns a string of length [3Xlen[0m consisting of copies of [3Xc[0m. [4X--------------------------- Example ----------------------------[0X [4Xgap> RepeatedString('=',51);[0X [4X"==================================================="[0X [4Xgap> RepeatedString("*=",51);[0X [4X"*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*"[0X [4X------------------------------------------------------------------[0X [1X6.1-9 NumberDigits[0m [2X> NumberDigits( [0X[3Xstr, base[0X[2X ) ________________________________________[0Xfunction [6XReturns:[0X integer [2X> DigitsNumber( [0X[3Xn, base[0X[2X ) __________________________________________[0Xfunction [6XReturns:[0X string The argument [3Xstr[0m of [2XNumberDigits[0m must be a string consisting only of an optional leading [10X'-'[0m and characters in [10X0123456789abcdefABCDEF[0m, describing an integer in base [3Xbase[0m with 2 <= [3Xbase[0m <= 16. This function returns the corresponding integer. The function [2XDigitsNumber[0m does the reverse. [4X--------------------------- Example ----------------------------[0X [4Xgap> NumberDigits("1A3F",16);[0X [4X6719[0X [4Xgap> DigitsNumber(6719, 16);[0X [4X"1A3F"[0X [4X------------------------------------------------------------------[0X [1X6.1-10 PositionMatchingDelimiter[0m [2X> PositionMatchingDelimiter( [0X[3Xstr, delim, pos[0X[2X ) _____________________[0Xfunction [6XReturns:[0X position as integer or [9Xfail[0m Here [3Xstr[0m must be a string and [3Xdelim[0m a string with two different characters. This function searches the smallest position [10Xr[0m of the character [10X[3Xdelim[0m[10X[2][0m in [3Xstr[0m such that the number of occurrences of [10X[3Xdelim[0m[10X[2][0m in [3Xstr[0m between positions [10X[3Xpos[0m[10X+1[0m and [10Xr[0m is by one greater than the corresponding number of occurrences of [10X[3Xdelim[0m[10X[1][0m. If such an [10Xr[0m exists, it is returned. Otherwise [9Xfail[0m is returned. [4X--------------------------- Example ----------------------------[0X [4Xgap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 0);[0X [4Xfail[0X [4Xgap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 1);[0X [4X2[0X [4Xgap> PositionMatchingDelimiter("{}x{ab{c}d}", "{}", 6);[0X [4X11[0X [4X------------------------------------------------------------------[0X [1X6.1-11 WordsString[0m [2X> WordsString( [0X[3Xstr[0X[2X ) _______________________________________________[0Xfunction [6XReturns:[0X list of strings containing the words This returns the list of words of a text stored in the string [3Xstr[0m. All non-letters are considered as word boundaries and are removed. [4X--------------------------- Example ----------------------------[0X [4Xgap> WordsString("one_two \n three!?");[0X [4X[ "one", "two", "three" ][0X [4X------------------------------------------------------------------[0X [1X6.1-12 Base64String[0m [2X> Base64String( [0X[3Xstr[0X[2X ) ______________________________________________[0Xfunction [2X> StringBase64( [0X[3Xbstr[0X[2X ) _____________________________________________[0Xfunction [6XReturns:[0X a string The first function translates arbitrary binary data given as a GAP string into a [13Xbase 64[0m encoded string. This encoded string contains only printable ASCII characters and is used in various data transfer protocols ([10XMIME[0m encoded emails, weak password encryption, ...). We use the specification in RFC 2045 ([7Xhttp://tools.ietf.org/html/rfc2045[0m). The second function has the reverse functionality. Here we also accept the characters [10X-_[0m instead of [10X+/[0m as last two characters. Whitespace is ignored. [4X--------------------------- Example ----------------------------[0X [4Xgap> b := Base64String("This is a secret!");[0X [4X"VGhpcyBpcyBhIHNlY3JldCEA="[0X [4Xgap> StringBase64(b); [0X [4X"This is a secret!"[0X [4X------------------------------------------------------------------[0X [1X6.2 Unicode Strings[0X The [5XGAPDoc[0m package provides some tools to deal with unicode characters and strings. These can be used for recoding text strings between various encodings. [1X6.2-1 Unicode Strings and Characters[0X [2X> Unicode( [0X[3Xlist[, encoding][0X[2X ) _____________________________________[0Xoperation [2X> UChar( [0X[3Xnum[0X[2X ) ____________________________________________________[0Xoperation [2X> IsUnicodeString_____________________________________________________[0Xfilter [2X> IsUnicodeCharacter__________________________________________________[0Xfilter [2X> IntListUnicodeString( [0X[3Xustr[0X[2X ) _____________________________________[0Xfunction Unicode characters are described by their [13Xcodepoint[0m, an integer in the range from 0 to 2^21-1. For details about unicode, see [7Xhttp://www.unicode.org[0m. The function [2XUChar[0m wraps an integer [3Xnum[0m into a [5XGAP[0m object lying in the filter [2XIsUnicodeCharacter[0m. Use [10XInt[0m to get the codepoint back. The argument [3Xnum[0m can also be a [5XGAP[0m character which is then translated to an integer via [2XINT_CHAR[0m ([14XReference: INT_CHAR[0m). [2XUnicode[0m produces a [5XGAP[0m object in the filter [2XIsUnicodeString[0m. This is a wrapped list of integers for the unicode characters in the string. The function [2XIntListUnicodeString[0m gives access to this list of integers. Basic list functionality is available for [2XIsUnicodeString[0m elements. The entries are in [2XIsUnicodeCharacter[0m. The argument [3Xlist[0m for [2XUnicode[0m is either a list of integers or a [5XGAP[0m string. In the latter case an [3Xencoding[0m can be specified as string, its default is [10X"UTF-8"[0m. Currently supported encodings can be found in [10XUNICODE_RECODE.NormalizedEncodings[0m (ASCII, ISO-8859-X, UTF-8 and aliases). The encoding [10X"XML"[0m means an ASCII encoding in which non-ASCII characters are specified by XML character entities. The encoding [10X"URL"[0m is for URL-encoded (also called percent-encoded strings, as specified in RFC 3986 (see here ([7Xhttp://www.ietf.org/rfc/rfc3986.txt[0m)). The listed encodings [10X"LaTeX"[0m and aliases cannot be used with [2XUnicode[0m. See the operation [2XEncode[0m ([14X6.2-2[0m) for mapping a unicode string to a [5XGAP[0m string. [4X--------------------------- Example ----------------------------[0X [4Xgap> ustr := Unicode("a and \366", "latin1");[0X [4XUnicode("a and ö")[0X [4Xgap> ustr = Unicode("a and ö", "XML"); [0X [4Xtrue[0X [4Xgap> IntListUnicodeString(ustr);[0X [4X[ 97, 32, 97, 110, 100, 32, 246 ][0X [4Xgap> ustr[7];[0X [4X'ö'[0X [4X------------------------------------------------------------------[0X [1X6.2-2 Encode[0m [2X> Encode( [0X[3Xustr[, encoding][0X[2X ) ______________________________________[0Xoperation [6XReturns:[0X a [5XGAP[0m string [2X> SimplifiedUnicodeString( [0X[3Xustr[, encoding][, "single"][0X[2X ) __________[0Xfunction [6XReturns:[0X a unicode string [2X> LowercaseUnicodeString( [0X[3Xustr[0X[2X ) ___________________________________[0Xfunction [6XReturns:[0X a unicode string [2X> UppercaseUnicodeString( [0X[3Xustr[0X[2X ) ___________________________________[0Xfunction [6XReturns:[0X a unicode string [2X> LaTeXUnicodeTable__________________________________________[0Xglobal variable [2X> SimplifiedUnicodeTable_____________________________________[0Xglobal variable [2X> LowercaseUnicodeTable______________________________________[0Xglobal variable The operation [2XEncode[0m translates a unicode string [3Xustr[0m into a [5XGAP[0m string in some specified [3Xencoding[0m. The default encoding is [10X"UTF-8"[0m. Supported encodings can be found in [10XUNICODE_RECODE.NormalizedEncodings[0m. Except for some cases mentioned below characters which are not available in the target encoding are substituted by '?' characters. If the [3Xencoding[0m is [10X"URL"[0m (see [2XUnicode[0m ([14X6.2-1[0m)) then an optional argument [3Xencreserved[0m can be given, it must be a list of reserved characters which should be percent encoded; the default is to encode only the [10X%[0m character. The encoding [10X"LaTeX"[0m substitutes non-ASCII characters and LaTeX special characters by LaTeX code as given in an ordered list [10XLaTeXUnicodeTable[0m of pairs [codepoint, string]. If you have a unicode character for which no substitution is contained in that list, you will get a warning and the translation is [10XUnicode(nr)[0m. In this case find a substitution and add a corresponding [codepoint, string] pair to [10XLaTeXUnicodeTable[0m using [2XAddSet[0m ([14XReference: AddSet[0m). Also, please, tell the [5XGAPDoc[0m authors about your addition, such that we can extend the list [10XLaTeXUnicodeTable[0m. (Most of the initial entries were generated from lists in the TeX projects encTeX and [10Xucs[0m.) There are some variants of this encoding: [10X"LaTeXleavemarkup"[0m does the same translations for non-ASCII characters but leaves the LaTeX special characters (e.g., any LaTeX commands) as they are. [10X"LaTeXUTF8"[0m does not give a warning about unicode characters without explicit translation, instead it translates the character to its [10XUTF-8[0m encoding. Make sure to setup your LaTeX document such that all these characters are understood. [10X"LaTeXUTF8leavemarkup"[0m is a combination of the last two variants. Note that the [10X"LaTeX"[0m encoding can only be used with [2XEncode[0m but not for the opposite translation with [2XUnicode[0m ([14X6.2-1[0m) (which would need far too complicated heuristics). The function [2XSimplifiedUnicodeString[0m can be used to substitute many non-ASCII characters by related ASCII characters or strings (e.g., by a corresponding character without accents). The argument [3Xustr[0m and the result are unicode strings, if [3Xencoding[0m is [10X"ASCII"[0m then all non-ASCII characters are translated, otherwise only the non-latin1 characters. If the string [10X"single"[0m in an argument then only substitutions are considered which don't make the result string longer. The translations are stored in a sorted list [10XSimplifiedUnicodeTable[0m. Its entries are of the form [10X[codepoint, trans1, trans2, ...][0m. Here [10Xtrans1[0m and so on is either an integer for the codepoint of a substitution character or it is a list of codepoint integers. If you are missing characters in this list and know a sensible ASCII approximation, then add an entry (with [2XAddSet[0m ([14XReference: AddSet[0m)) and tell the [5XGAPDoc[0m authors about it. (The initial content of [10XSimplifiedUnicodeTable[0m was mainly generated from the "[10Xtranstab[0m" tables by Markus Kuhn.) The function [2XLowercaseUnicodeString[0m gets and returns a unicode string and translates each uppercase character to its corresponding lowercase version. This function uses a list [10XLowercaseUnicodeTable[0m of pairs of codepoint integers. This list was generated using the file [11XUnicodeData.txt[0m from the unicode definition (field 14 in each row). The function [2XUppercaseUnicodeString[0m does the similar translation to uppercase characters. [4X--------------------------- Example ----------------------------[0X [4Xgap> ustr := Unicode("a and ö", "XML");[0X [4XUnicode("a and ö")[0X [4Xgap> SimplifiedUnicodeString(ustr, "ASCII");[0X [4XUnicode("a and oe")[0X [4Xgap> SimplifiedUnicodeString(ustr, "ASCII", "single");[0X [4XUnicode("a and o")[0X [4Xgap> ustr2 := UppercaseUnicodeString(ustr);;[0X [4Xgap> Print(Encode(ustr2, GAPInfo.TermEncoding), "\n");[0X [4XA AND Ã[0X [4X------------------------------------------------------------------[0X [1X6.2-3 Lengths of UTF-8 strings[0X [2X> WidthUTF8String( [0X[3Xstr[0X[2X ) ___________________________________________[0Xfunction [2X> NrCharsUTF8String( [0X[3Xstr[0X[2X ) _________________________________________[0Xfunction [6XReturns:[0X an integer Let [3Xstr[0m be a [5XGAP[0m string with text in UTF-8 encoding. There are three "lengths" of such a string which must be distinguished. The operation [2XLength[0m ([14XReference: Length[0m) returns the number of bytes and so the memory occupied by [3Xstr[0m. The function [2XNrCharsUTF8String[0m returns the number of unicode characters in [3Xstr[0m, that is the length of [10XUnicode([3Xstr[0m[10X)[0m. In many applications the function [2XWidthUTF8String[0m is more interesting, it returns the number of columns needed by the string if printed to a terminal. This takes into account that some unicode characters are combining characters and that there are wide characters which need two columns (e.g., for Chinese or Japanese). (To be precise: This implementation assumes that there are no control characters in [3Xstr[0m and uses the character width returned by the [10Xwcwidth[0m function in the GNU C-library called with UTF-8 locale.) [4X--------------------------- Example ----------------------------[0X [4Xgap> # A, German umlaut u, B, zero width space, C, newline[0X [4Xgap> str := Encode( Unicode( "AüB​C\n", "XML" ) );;[0X [4Xgap> Print(str);[0X [4XAüBâC[0X [4Xgap> # umlaut u needs two bytes and the zero width space three[0X [4Xgap> Length(str);[0X [4X9[0X [4Xgap> NrCharsUTF8String(str);[0X [4X6[0X [4Xgap> # zero width space and newline don't contribute to width[0X [4Xgap> WidthUTF8String(str);[0X [4X4[0X [4X------------------------------------------------------------------[0X [1X6.3 Print Utilities[0X The following printing utilities turned out to be useful for interactive work with texts in [5XGAP[0m. But they are more general and so we document them here. [1X6.3-1 PrintTo1[0m [2X> PrintTo1( [0X[3Xfilename, fun[0X[2X ) ________________________________________[0Xfunction [2X> AppendTo1( [0X[3Xfilename, fun[0X[2X ) _______________________________________[0Xfunction The argument [3Xfun[0m must be a function without arguments. Everything which is printed by a call [3Xfun()[0m is printed into the file [3Xfilename[0m. As with [2XPrintTo[0m ([14XReference: PrintTo[0m) and [2XAppendTo[0m ([14XReference: AppendTo[0m) this overwrites or appends to, respectively, a previous content of [3Xfilename[0m. These functions can be particularly efficient when many small pieces of text shall be written to a file, because no multiple reopening of the file is necessary. [4X--------------------------- Example ----------------------------[0X [4Xgap> f := function() local i; [0X [4X> for i in [1..100000] do Print(i, "\n"); od; end;; [0X [4Xgap> PrintTo1("nonsense", f); # now check the local file `nonsense'[0X [4X------------------------------------------------------------------[0X [1X6.3-2 StringPrint[0m [2X> StringPrint( [0X[3Xobj1[, obj2[, ...]][0X[2X ) _______________________________[0Xfunction [2X> StringView( [0X[3Xobj[0X[2X ) ________________________________________________[0Xfunction These functions return a string containing the output of a [10XPrint[0m or [10XViewObj[0m call with the same arguments. This should be considered as a (temporary?) hack. It would be better to have [2XString[0m ([14XReference: String[0m) methods for all [5XGAP[0m objects and to have a generic [2XPrint[0m ([14XReference: Print[0m)-function which just interprets these strings. [1X6.3-3 PrintFormattedString[0m [2X> PrintFormattedString( [0X[3Xstr[0X[2X ) ______________________________________[0Xfunction This function prints a string [3Xstr[0m. The difference to [10XPrint(str);[0m is that no additional line breaks are introduced by [5XGAP[0m's standard printing mechanism. This can be used to print lines which are longer than the current screen width. In particular one can print text which contains escape sequences like those explained in [2XTextAttr[0m ([14X6.1-2[0m), where lines may have more characters than [13Xvisible characters[0m. [1X6.3-4 Page[0m [2X> Page( [0X[3X...[0X[2X ) ______________________________________________________[0Xfunction [2X> PageDisplay( [0X[3Xobj[0X[2X ) _______________________________________________[0Xfunction These functions are similar to [2XPrint[0m ([14XReference: Print[0m) and [2XDisplay[0m ([14XReference: Display[0m), respectively. The difference is that the output is not sent directly to the screen, but is piped into the current pager; see [2XPAGER[0m ([14XReference: Pager[0m). [4X--------------------------- Example ----------------------------[0X [4Xgap> Page([1..1421]+0);[0X [4Xgap> PageDisplay(CharacterTable("Symmetric", 14));[0X [4X------------------------------------------------------------------[0X [1X6.3-5 StringFile[0m [2X> StringFile( [0X[3Xfilename[0X[2X ) ___________________________________________[0Xfunction [2X> FileString( [0X[3Xfilename, str[, append][0X[2X ) ____________________________[0Xfunction The function [2XStringFile[0m returns the content of file [3Xfilename[0m as a string. This works efficiently with arbitrary (binary or text) files. If something went wrong, this function returns [9Xfail[0m. Conversely the function [2XFileString[0m writes the content of a string [3Xstr[0m into the file [3Xfilename[0m. If the optional third argument [3Xappend[0m is given and equals [9Xtrue[0m then the content of [3Xstr[0m is appended to the file. Otherwise previous content of the file is deleted. This function returns the number of bytes written or [9Xfail[0m if something went wrong. Both functions are quite efficient, even with large files.