Brian Dunning's FileMaker Custom Functions

icio_linewrap ( Text ; Size ; Originalsize )

A recursive line formatter/breaker and word wrapper that implements Knuth's algorithm

  Average rating: 4.6 (27 votes) Log in to vote

Chris Jones   Chris Jones
Inter-CIO Limited
http://www.inter-cio.com

Share on Facebook Share on Twitter

  Sample input:
icio_linewrap ("01234¶56789";3;3)
  Sample output:
012
34
567
89

  Function definition: (Copy & paste into FileMaker's Edit Custom Function window)

function icio_linewrap (Text, Size, Originalsize)

This function breaks lines of text passed to it in param Text
and intelligently does so to the character count passed in param Size.
Param Originalsize is utilterian and only used to pass on whatever value is given to it. It is not intrinsically used in this function.
The function implements Knuth's algorithm.
The function calls several other functions (icio_striptrailingspaces, icio_stripleadingspaces
and icio_finddelimiter).
icio_striptrailingspaces is used to strip out any spaces that occur contiguously before a CR at the end
of a string. It is provided below.
icio_stripleadingspaces is used to strip out any spaces that occur contiguously before a passed Character at the beginning
of a string. It is also provided below.
icio_finddelimiter is used to find a delimiter that does not appear in the string passed to it. The function
is also provoded below.
All of the above fuctions MUST be installed for this function to operate correctly.

The icio_linewrap function will preserve existing line breaks, break correctly at word boundaries, and split text strings
passed to it that are longer than the Size specified. It recurses to fully process the entire Text passed to it.

I have not yet managed to return a ? from this function after exhausting testing!

Param Text - the text string to be processed
Param Size - the maximum length of each line in characters
Param Originalsize - utiliterian to allow a value to be passed on during recursion (not specifically used in this function). Defaults to the value of Size if passed as ""
---------------------------------------------------------------
The function icio_striptrailingspaces is documented here if required:
---------------------------------------------------------------
//function icio_striptrailingspaces (Text; LastChar)

//This function reverse scans a passed string (param Text) and replaces " " & LastChar with LastChar at the end of Text
//LastChar can be "" to strip off any trailing spaces
//Param Text - the string to scan
//Param LastChar - the Last character to use (if any)
//if passed as "", "⅋" or a non-appearing character will be used
//Requires custom function icio_finddelimiter(Text;Delimiter);

Let
(
[
//Store the length of the passed Text
LengthText = Length(Text);

//Find a usable delimiter
Delimiter = icio_finddelimiter(Text;"");

//Store a copy of the original text
OriginalText = Text;

//Deal with Delimiter being a " " - use the delimiter to replace all refs to LastChar being a space
Text = Case (
LastChar=" " and Right(Text;1) = " "; Left(Text;LengthText-1) & Delimiter;
Text
);
LastChar = Case (
LastChar=" "; Delimiter;
LastChar
);
//End dealing with Delimiter being a " "

//Check whether anything to process
End = If(LengthText = 0 or (LastChar ≠ "" and LastChar ≠ Right(Text;1));
1;
0
);

//Strip last char off Text if LastChar is something
Text = If(LastChar ≠ "" and End =0;
Left(Text;LengthText-1);
Text
);

//Store the passed Text with all spaces removed
nospaces=If(End = 0;
Substitute(Text; " "; "");
Text
);

//Strip all the trailing spaces off Text if any are found
Text = If(IsEmpty(nospaces) or End = 1;
"";
Left(Text; Position(Text; Right(nospaces; 1); Length(Text);-1 ) )
);

//Add the Delimiter to the end of Text if there is a delimiter
Text = If(End = 0 and LastChar ≠ "";
Text & LastChar;
Text
);

//Re-store the length of Text
LengthText = Length(Text);

//Replace the delimiter at the end of Text with a space if there is a trailing delimiter
Text = Case (
LastChar = Delimiter and End =0; Left(Text;LengthText-1) & " ";
Text
);

//Return the Original Text if it was not processed - otherwise return the processed text
Text = Case(
End = 1; OriginalText;
Text
)
];
Text
)
---------------------------------------------------------------
The function icio_stripleadingspaces is documented here if required:
---------------------------------------------------------------
//function icio_stripleadingspaces (Text; LastChar)

//This functions scans a passed string (param Text) and recursively removes all contiguous " " up to LastChar
//LastChar can be "" to strip off any contiguous leading spaces up to the first non-space character
//Param Text - the string to scan
//Param LastChar - the Last character to use or ""


Let
(
[
//Store the length of Text
LengthText = Length(Text);

//Set a flag if we have nothing to process
End = If(LengthText = 0 or (LengthText=1 and LastChar = Left(Text;1));
1;
0
);

//LastChar is either "", " " or another char

//Store Text with all spaces removed
Substance = If(End = 0;
Substitute(Text; " "; "");
""
);

//Store the length of the stripped Text
LengthSubstance = Length(Substance);

//Grab the first character in the stripped Text, if there is one - otherwise return null string
FirstInSubstance = If(End=0;
If(LengthSubstance>0;
Left(Substance;1);
""
);
""
);

//Process Text and return it
Text = If(End = 1;
"";
Case (
LastChar = "" and LengthSubstance = 0; "";
LastChar = "" and LengthSubstance > 0; Right(Text;LengthText-Position(Text;FirstInSubstance;1;1)+1);
LastChar = " " and LengthSubstance = 0 and LengthText > 0; Right(Text;1);
LastChar = " " and LengthSubstance > 0 and LengthText > 0; Right(Text;LengthText-Position(Text;FirstInSubstance;1;1)+2);
LengthSubstance = 0 and LengthText > 0; Text;
LengthSubstance > 0 and LengthText > 0; Right(Text;LengthText-Position(Text;FirstInSubstance;1;1)+1);
Text
)
)
];
Text
)
---------------------------------------------------------------
The function icio_finddelimiter is documented here if required:
---------------------------------------------------------------
//icio_finddelimiter (Text;Delimiter)

//Finds a 3 character delimiter that does not appear in Text
//Uses standard ASCII characters
//If Delimiter is passed as "", starts by testing "|^-"
//Param Text = the string to be examined
//Param Delimiter = the 3 character string to be tested
//Exits with a unique 3 character Delimiter that does not appear in Text

Let(
[
//Set Flag
End = 0;

//Store the Length of Text
LengthText = Length(Text);

//Set Delimiter to |^- if none was provided
Delimiter = If(Delimiter = "";
"|^-";
Delimiter
);

//Set Flag if nothing to process
End = If(PatternCount(Text;Delimiter) = 0 or LengthText = 0;
1;
0
);

//Set Delimiter to a special character string that does not appear in Text
Delimiter = If(End = 1;
Delimiter;
Case (
Delimiter = "|^-"; "^-|";
Delimiter = "^-|"; "-|^";
Delimiter = "-|^"; "|-^";
Delimiter = "|-^"; "-^|";
Delimiter = "-^|"; "^|-";
Delimiter
)
)
];

//Recurse until we have a valid Delimiter and return it
If(End = 1;
Delimiter;
icio_finddelimiter(Text;Delimiter)
)
)
---------------------------------------------------------------

Chris Jones
ICIO Limited, United Kingdom
chris.jones@inter-cio.com

 

Comments

Lee Smith   Lee Smith
Jun 21, 2012
Your cf breaks at icio_findpos
 
Chris Jones   Chris Jones, Oxford, UK
Jun 21, 2012
@Lee Smith

You need to ensure you have the function icio_findpos installed as per the documentation!
 
Chris Jones   Chris Jones, Oxford, UK
Jul 3, 2012
Revised to allow for special delimiters to deal with Space characters
 

Log in to post comments.

 

Note: these functions are not guaranteed or supported by BrianDunning.com. Please contact the individual developer with any questions or problems.

Support this website.

This library has been a free commmunity resource for FileMaker users and developers for 20 years. It receives no funding and has no advertisements. If it has helped you out, I'd really appreciate it if you could contribute whatever you think it's worth: