Skip to content

Instantly share code, notes, and snippets.

@stormwatch
Created June 11, 2020 09:01
Show Gist options
  • Save stormwatch/d722da527619e5ed13cace83564e4ff6 to your computer and use it in GitHub Desktop.
Save stormwatch/d722da527619e5ed13cace83564e4ff6 to your computer and use it in GitHub Desktop.
-module(text).
-export(
[
format/1,
rio/0,
super/0,
take_line/1,
take_line/2,
take_paragraph/1,
take_paragraph/2,
take_word/1,
take_word/2,
take_word/4
]).
rio() -> "The heat bloomed in December\n" ++
" as the carnival season\n" ++
" kicked into gear. \n" ++
"Nearly helpless with sun and glare, I avoided Rio's brilliant \n" ++
"sidewalks\n" ++
" and glittering beaches,\n" ++
"panting in dark corners\n" ++
" and waiting out the inverted southern summer.\n".
super() ->
"It's... supercalifragilisticexpialidocious!\n" ++
"Even though the sound of it is something quite atrocious\n" ++
"If you say it loud enough you'll always sound precocious:\n" ++
"Supercalifragilisticexpialidocious!\n" ++
" Um diddle diddle diddle, um diddle ay!\n" ++
" Um diddle diddle diddle, um diddle ay!\n" ++
" Um diddle diddle diddle, um diddle ay!\n" ++
" Um diddle diddle diddle, um diddle ay!\n" ++
"Because I was afraid to speak when I was just a lad\n" ++
"Me father gave me nose a tweak and told me I was bad\n" ++
" But then one day I learned a word that saved me achin' nose\n" ++
"The biggest word you ever heard, and this is how it goes:\n" ++
" Oh, supercalifragilisticexpialidocious!\n" ++
" Even though the sound of it is something quite atrocious\n" ++
" If you say it loud enough you'll always sound precocious\n" ++
"Supercalifragilisticexpialidocious!\n".
%% Most books use circa 66 chars per line.
-define(LINE_WIDTH, 66).
-define(DELIMITERS, "\s\n\t").
take_word(String) ->
take_word(String, ?LINE_WIDTH).
take_word(String, Length) ->
take_word(string:trim(String), Length, [], 0).
take_word("", MaxLength, Acc, CurrLength) ->
{CurrLength =< MaxLength, string:reverse(Acc), CurrLength, ""};
take_word([Char|Rest], MaxLength, Acc, CurrLength) ->
case lists:member(Char, ?DELIMITERS) of
true ->
{CurrLength =< MaxLength, string:reverse(Acc), CurrLength, string:trim(Rest, leading)};
false ->
take_word(Rest, MaxLength, [Char|Acc], CurrLength+1)
end.
take_line(String) ->
take_line(String, ?LINE_WIDTH).
take_line(String, Width) ->
take_line(String, Width, "", Width).
take_line("", _, Line, _) ->
{lists:reverse(Line), ""};
take_line(String, AvaliableWidth, Line, ColumnWidth) ->
{Fits, Word, Length, Rest} = take_word(String, AvaliableWidth),
case Fits of
true ->
take_line(Rest, AvaliableWidth-Length-1, [Word|Line], ColumnWidth);
false ->
case AvaliableWidth of
ColumnWidth ->
%% Word is too long; we ensure it gets its own line.
{[Word], Rest};
_ ->
{lists:reverse(Line), Word ++ [$\s|Rest]}
end
end.
take_paragraph(String) ->
take_paragraph(String, ?LINE_WIDTH).
take_paragraph(String, Width) ->
take_paragraph(String, Width, []).
take_paragraph("", _Width, Result) ->
lists:reverse(Result);
take_paragraph(String, Width, Result) ->
{Line, Rest} = take_line(String, Width),
%% io:format("Line: ~p Rest: ~p\n", [Line, Rest]),
take_paragraph(Rest, Width, [Line|Result]).
format_line([]) ->
io:nl();
format_line([Word]) ->
io:format(Word),
format_line([]);
format_line([Word|Words]) ->
io:format("~s ", [Word]),
format_line(Words).
format([Line|Lines]) ->
format_line(Line),
format(Lines);
format([]) ->
ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment