Word wrap: Difference between revisions
Content added Content deleted
(Added Quackery.) |
(Added AppleScript.) |
||
Line 479: | Line 479: | ||
For more sophisticated algorithms (the extra credit), one could derive |
For more sophisticated algorithms (the extra credit), one could derive |
||
a class '''Word_Wrap.<something>''' from '''Word_Wrap.Basic'''. |
a class '''Word_Wrap.<something>''' from '''Word_Wrap.Basic'''. |
||
=={{header|AppleScript}}== |
|||
Being a scripting language, AppleScript would normally be used just to tell some scriptable text process what fonts and margins to use and leave that process to sort out its own wraps. But the "greedy" algorithm's easy to implement for line widths measured in characters: |
|||
<lang applescript>on wrapParagraph(para, lineWidth) |
|||
if (para is "") then return para |
|||
set astid to AppleScript's text item delimiters |
|||
set AppleScript's text item delimiters to {space, tab} -- Doesn't include character id 160 (NO-BREAK SPACE). |
|||
script o |
|||
property wrds : para's text items -- Space- or tab-delimited chunks. |
|||
end script |
|||
set spaceWidth to (count space) -- ;-) |
|||
set spaceLeft to lineWidth |
|||
set theLines to {} |
|||
set i to 1 |
|||
repeat with j from 1 to (count o's wrds) |
|||
set wordWidth to (count item j of o's wrds) |
|||
if (wordWidth + spaceWidth > spaceLeft) then |
|||
set end of theLines to text 1 thru (-1 - wordWidth) of (text from text item i to text item j of para) |
|||
set i to j |
|||
set spaceLeft to lineWidth - wordWidth |
|||
else |
|||
set spaceLeft to spaceLeft - (wordWidth + spaceWidth) |
|||
end if |
|||
end repeat |
|||
set end of theLines to text from text item i to end of para |
|||
set AppleScript's text item delimiters to character id 8232 -- U+2028 (LINE SEPARATOR). |
|||
set output to theLines as text |
|||
set AppleScript's text item delimiters to astid |
|||
return output |
|||
end wrapParagraph |
|||
local para |
|||
set para to "If there is a way to do this that is built-in, trivial, or provided in a standard library, show that. Otherwise implement the minimum length greedy algorithm from Wikipedia." |
|||
return wrapParagraph(para, 70) & (linefeed & linefeed) & wrapParagraph(para, 40)</lang> |
|||
{{output}} |
|||
<lang applescript>"If there is a way to do this that is built-in, trivial, or provided |
|||
in a standard library, show that. Otherwise implement the minimum |
|||
length greedy algorithm from Wikipedia. |
|||
If there is a way to do this that is |
|||
built-in, trivial, or provided in a |
|||
standard library, show that. Otherwise |
|||
implement the minimum length greedy |
|||
algorithm from Wikipedia."</lang> |
|||
However, it's more efficient to look for the last space in each line than to see how many "words" will fit: |
|||
<lang applescript>on wrapParagraph(para, lineWidth) |
|||
set theLines to {} |
|||
set spaceTab to space & tab |
|||
set len to (count para) |
|||
set i to 1 |
|||
repeat until (i > len) |
|||
set j to i + lineWidth - 1 |
|||
if (j < len) then |
|||
repeat with j from j to i by -1 |
|||
if (character j of para is in spaceTab) then exit repeat |
|||
end repeat |
|||
-- The "greedy" algorithm keeps words which are longer than or |
|||
-- the same length as the line width intact. Do the same here. |
|||
if (j = i) then |
|||
repeat with j from (i + lineWidth) to len |
|||
if (character j of para is in spaceTab) then exit repeat |
|||
end repeat |
|||
end if |
|||
else |
|||
set j to len |
|||
end if |
|||
set end of theLines to text i thru j of para |
|||
set i to j + 1 |
|||
end repeat |
|||
set astid to AppleScript's text item delimiters |
|||
set AppleScript's text item delimiters to character id 8232 -- U+2028 (LINE SEPARATOR). |
|||
set output to theLines as text |
|||
set AppleScript's text item delimiters to astid |
|||
return output |
|||
end wrapParagraph</lang> |
|||
Using AppleScriptObjC, the second approach can be achieved with a regular expression: |
|||
<lang applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later |
|||
use framework "Foundation" |
|||
on wrapParagraph(para, lineWidth) |
|||
if (para is "") then return para |
|||
set str to current application's class "NSMutableString"'s stringWithString:(para) |
|||
-- Replace each run of up to (lineWidth - 1) characters followed by a space or a tab, |
|||
-- or by the end of the paragraph, with itself and a LINE SEPARATOR character. |
|||
tell str to replaceOccurrencesOfString:(".{1," & (lineWidth - 1) & "}(?:[ \\t]|\\Z)") withString:("$0" & character id 8232) ¬ |
|||
options:(current application's NSRegularExpressionSearch) range:({0, its |length|()}) |
|||
-- Remove the LINE SEPARATOR inserted at the end. |
|||
tell str to replaceOccurrencesOfString:(character id 8232) withString:("") ¬ |
|||
options:(0) range:({(its |length|()) - 2, 2}) |
|||
return str as text |
|||
end wrapParagraph</lang> |
|||
=={{header|Arturo}}== |
=={{header|Arturo}}== |