Skip to content

Instantly share code, notes, and snippets.

@Joakineee
Created May 27, 2020 08:43
Show Gist options
  • Save Joakineee/658441693082f547c4fcc69db31db810 to your computer and use it in GitHub Desktop.
Save Joakineee/658441693082f547c4fcc69db31db810 to your computer and use it in GitHub Desktop.
text_processing exercise.
-module(format).
-export([text_processing/3]).
% Used to read a file into a list of lines.
% Example files available in:
% gettysburg-address.txt (short)
% dickens-christmas.txt (long)
% Get the contents of a text file into a list of lines.
% Each line has its trailing newline removed.
get_file_contents(Name) ->
{ok,File} = file:open(Name,[read]),
Rev = get_all_lines(File,[]),
lists:reverse(Rev).
% Auxiliary function for get_file_contents.
% Not exported.
get_all_lines(File,Partial) ->
case io:get_line(File,"") of
eof -> file:close(File),
Partial;
Line -> {Strip,_} = lists:split(length(Line)-1,Line),
get_all_lines(File,[Strip|Partial])
end.
% Show the contents of a list of strings.
% Can be used to check the results of calling get_file_contents.
show_file_contents([L|Ls]) ->
io:format("~s~n",[L]),
show_file_contents(Ls);
show_file_contents([]) ->
ok.
-spec text_processing(string(),string(),integer()) -> string().
text_processing(File,Format,MaxLen) ->
F = get_file_contents(File),
T = get_tokens(F,[]),
L = lists:concat(T),
case Format of
vb -> F;
cv -> io:fwrite(string:join(my_pad(fit_words(L,MaxLen,[],0,[]),MaxLen,both,[]),"\n"));
lp -> io:fwrite(string:join(fit_words(L,MaxLen,[],0,[]),"\n"));
rp -> io:fwrite(string:join(my_pad(fit_words(L,MaxLen,[],0,[]),MaxLen,leading,[]),"\n"));
ju -> io:fwrite(string:join(justify(fit_words(L,MaxLen,[],0,[]),MaxLen,[]),"\n"))
end.
%Generates a list of words from our text.
-spec get_tokens([list()],[T]) -> [T].
get_tokens([],Acc) ->
lists:reverse(Acc);
get_tokens([H|T],Acc) ->
get_tokens(T,[string:tokens(H, " ")|Acc]).
%From a list of words it creates a list of string with lengh < MaxLengh
-spec fit_words(list(),integer(),list(),integer(),[T]) -> [T].
fit_words([],_MaxLen,[],0,Acc) ->
lists:reverse(Acc);
fit_words([],MaxLen,CurrentLine,_CumulatedLen,Acc) ->
fit_words([],MaxLen,[],0,[string:join(lists:reverse(CurrentLine)," ")|Acc]);
fit_words([H|T],MaxLen,CurrentLine,CumulatedLen,Acc) ->
case length(H) + CumulatedLen =< MaxLen of
true -> fit_words(T,MaxLen,[H|CurrentLine],CumulatedLen + length(H) + 1 ,Acc);
false -> fit_words([H|T],MaxLen,[],0,[string:join(lists:reverse(CurrentLine)," ")|Acc])
end.
%calls pad function for every line in our text.
%we have to say if we want it leadding or trailing.
-spec my_pad([T],integer(),atom(),[T]) -> [T].
my_pad([],_MaxLen,_PadMode,Acc) ->
lists:reverse(Acc);
my_pad([H|T],MaxLen,PadMode,Acc) ->
my_pad(T,MaxLen,PadMode,[string:pad(H,MaxLen,PadMode)|Acc]).
%calls expand function for every line in our text.
%this tells spand function how spaces has to insert.
-spec justify([T],integer(),[T]) -> [T].
justify([],_MaxLen,Acc) ->
lists:reverse(Acc);
justify([H|T],MaxLen,Acc) ->
justify(T,MaxLen,[expand(H,[],MaxLen - length(H),0)|Acc]).
%expands a string inserting spaces until the desired length is reached.
-spec expand(string(),integer(),string(),integer()) -> string().
expand([],Acc,0,_Previous) -> lists:reverse(Acc);
expand([H|T],Acc,0,_Previous) -> expand(T,[H|Acc],0,H);
expand([$\s|T],Acc,ExpandLength,$\s) -> expand(T,[$\s|Acc],ExpandLength,$\s);
expand([$\s|T],Acc,ExpandLength,_Previous) -> expand(T,[$\s,$\s|Acc],ExpandLength - 1,$\s);
expand([H|T],Acc,ExpandLength,_Previous) -> expand(T,[H|Acc],ExpandLength,H);
expand([],Acc,ExpandLength,_Previous) -> expand(lists:reverse(Acc),[],ExpandLength,0).
%sample_outputs:
%
%
%
%
%
%149> format:text_processing("text",cv,60).
% The heat bloomed in December as the carnival season kicked
% into gear. Nearly helpless with sun and glare, I avoided
%Rio's brilliant sidewalks and glittering beaches, panting in
% dark corners and waiting out the inverted southern summer. ok
%
%
%
%
%150> format:text_processing("text",lp,40).
%The heat bloomed in December as the
%carnival season kicked into gear. Nearly
%helpless with sun and glare, I avoided
%Rio's brilliant sidewalks and glittering
%beaches, panting in dark corners and
%waiting out the inverted southern
%summer.ok
%
%151> format:text_processing("text",rp,40).
% The heat bloomed in December as the
%carnival season kicked into gear. Nearly
% helpless with sun and glare, I avoided
%Rio's brilliant sidewalks and glittering
% beaches, panting in dark corners and
% waiting out the inverted southern
% summer.ok
%
%2> format:text_processing("text",ju,50).
%The heat bloomed in December as the carnival
%season kicked into gear. Nearly helpless with sun
%and glare, I avoided Rio's brilliant sidewalks and
%glittering beaches, panting in dark corners and
%waiting out the inverted southern summer.ok
%
%
%
%
%3> format:text_processing("text",ju,30).
%The heat bloomed in December
%as the carnival season kicked
%into gear. Nearly helpless
%with sun and glare, I avoided
%Rio's brilliant sidewalks and
%glittering beaches, panting in
%dark corners and waiting out
%the inverted southern summer.ok
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment