html to plain text

108 views
Skip to first unread message

sVIKs

unread,
Aug 28, 2013, 5:46:06 AM8/28/13
to erlang-i...@googlegroups.com
Я в Erlange новичок, но учусь...

Может кто-то встречал или подскажет как малой кровью и быстро превратить html в обычный читаемый текст (plain text)?

zheka_13

unread,
Aug 28, 2013, 5:47:49 AM8/28/13
to erlang-i...@googlegroups.com
а зачем?


2013/8/28 sVIKs <sv...@i.ua>
Я в Erlange новичок, но учусь...

Может кто-то встречал или подскажет как малой кровью и быстро превратить html в обычный читаемый текст (plain text)?

--
Ви отримали це повідомлення, оскільки підписалися на групу "Erlang в Україні" Груп Google.
Щоб скасувати підписку на цю групу та не отримувати листів із неї, надішліть електронний лист на адресу erlang-in-ukra...@googlegroups.com.
Щоб залишати дописи в цій групі, надішліть електронного листа за адресою erlang-i...@googlegroups.com.
Перейдіть до цієї групи за посиланням http://groups.google.com/group/erlang-in-ukraine.

sVIKs

unread,
Aug 29, 2013, 5:26:08 AM8/29/13
to erlang-i...@googlegroups.com
Делается модуль по обработке email-ов, так вот крупные почтовые сервисы отсылают e-mail в двух вариантах plain text и html, а некоторые только в одно, в котором было написано сообщение. Вот и надо сделать конвертер, либо, как вариант, посмотреть на какой нибудь аналог и сделать свой, а может есть что-то готовое.

среда, 28 августа 2013 г., 12:47:49 UTC+3 пользователь Evgen Polivoda написал:

Alexey Radetsky

unread,
Aug 29, 2013, 5:55:11 AM8/29/13
to erlang-i...@googlegroups.com
Я бы такую штуку на perl нарисовал. Есть много готового на cpan. 


Середа, 28 серпня 2013 р. 12:46:06 UTC+3 користувач sVIKs написав:

Сергей Прохоров

unread,
Aug 29, 2013, 6:46:24 AM8/29/13
to erlang-i...@googlegroups.com
О, у меня есть именно такое и именно для обработки емейлов (работает на моём сервисе http://dropmail.me/).
Используется HTML парсер из mochiweb

Извиняюсь за большой сниппет...


%% HTML to text utilites

%% Convert plain HTML binary to plain text binary by extracting all text
%% nodes inside <body> tag.
%% TODO: detect encoding and convert to utf-8
html_to_text(Html) ->
    Tree = try mochiweb_html:parse(Html)
           catch _:_ -> []
           end,
    Body = case find_html_tag(Tree, <<"body">>) of
               undefined ->
                   NewHtml = <<"<body>", Html/binary, "</body>">>,
                   %% html_to_text(NewHtml) ???
                   NewTree = mochiweb_html:parse(NewHtml),
                   find_html_tag(NewTree, <<"body">>);
               {_, _, _} = El ->
                   El
           end,
    preorder_text(Body).

%% Find first occurence of tag `Tag'
%% preorder tree walking
%% TODO: show a.href value
find_html_tag({Tag, _, _} = Element, Tag) ->
    Element;
find_html_tag({_, _, _} = Element, Tag) ->
    find_html_tag([Element], Tag);
find_html_tag([{Tag, _, _} = Element | _], Tag) ->
    Element;
find_html_tag([{_, _, Childs} | Rest], Tag) ->
    case find_html_tag(Childs, Tag) of
        undefined ->
            find_html_tag(Rest, Tag);
        Element ->
            Element
    end;
find_html_tag([_ | Rest], Tag) ->
    find_html_tag(Rest, Tag);
find_html_tag([], _) ->
    undefined.

preorder_text(Els) ->
    preorder_text1(Els, true, <<>>).

preorder_text1(Els, AddSpaces, Acc) when is_list(Els) ->
    lists:foldl(fun(El, Acc1) ->
                        preorder_text1(El, AddSpaces, Acc1)
                end, Acc, Els);
preorder_text1({<<"a">>, Attrs, Childs}, AddSpaces, Acc) ->
    case proplists:get_value(<<"href">>, Attrs) of
        undefined -> preorder_text1(Childs, AddSpaces, Acc);
        Href ->
            Anchor = case preorder_text1(Childs, AddSpaces, <<>>) of
                         <<" ", Rest/binary>> -> Rest;
                         Other -> Other
                     end,
            if Anchor == Href ->
                    <<Acc/binary, " ", Href/binary>>;
               true ->
                    <<Acc/binary, " [", Anchor/binary, "](", Href/binary, ")">>
            end
    end;
preorder_text1({_El, _At, Childs}, AddSpaces, Acc) ->
    preorder_text1(Childs, AddSpaces, Acc);
preorder_text1(Binary, true, Acc) when is_binary(Binary) ->
    <<Acc/binary, " ", Binary/binary>>;
preorder_text1(Binary, false, Acc) when is_binary(Binary) ->
    <<Acc/binary, Binary/binary>>;
preorder_text1(_, _, Acc) ->                         % comment/pi etc.
    Acc.


-ifdef(TEST).

preorder_text_test() ->
    Tree = {<<>>, [],
            [<<"v1">>,
             {<<>>, [],
              [<<"v2">>,
               {comment, <<"comment">>},
               <<"v3">>,
               <<"v4">>]},
             <<"v5">>,
             {<<>>, [], []},
             <<"v6">>
            ]},
    ?assertEqual(<<" v1 v2 v3 v4 v5 v6">>, preorder_text1(Tree, true, <<>>)).

preorder_text_href_test() ->
    Tree = {<<>>, [],
            [<<"pre">>,
            {<<"a">>, [{<<"href">>, <<"http://example.com/">>}],
             [<<"anchor">>]},
             <<"post">>]},
    ?assertEqual(<<" pre [anchor](http://example.com/) post">>, preorder_text1(Tree, true, <<>>)).

preorder_text_href_is_anchor_test() ->
    Tree = {<<>>, [],
            [<<"pre">>,
            {<<"a">>, [{<<"href">>, <<"http://example.com/">>}],
             [<<"http://example.com/">>]},
             <<"post">>]},
    ?assertEqual(<<" pre http://example.com/ post">>, preorder_text1(Tree, true, <<>>)).

-endif.


Помимо вытаскивания текстовых элементов оно ещё ссылки разворачивает из <a href="http://example.com/">text</a> в [text](http://example.com/). Если не нужно - легко отключается.
Ну и в TODO ещё нужно добавить выкидывание <script> и <style> тегов, это тоже просто, но руки не дошли.

среда, 28 августа 2013 г., 13:46:06 UTC+4 пользователь sVIKs написал:

Anton Nikishaev

unread,
Aug 30, 2013, 7:49:29 PM8/30/13
to erlang-i...@googlegroups.com

On Aug 29, 2013, at 1:26 PM, sVIKs <sv...@i.ua> wrote:

> Делается модуль по обработке email-ов, так вот крупные почтовые сервисы отсылают e-mail в двух вариантах plain text и html, а некоторые только в одно, в котором было написано сообщение. Вот и надо сделать конвертер, либо, как вариант, посмотреть на какой нибудь аналог и сделать свой, а может есть что-то готовое.


Вообще тут проще не велосипедить, а взять какой-нибудь pandoc и сконвертировать им в plain text или markdown.
Или вообще w3m my.html > out.txt, но pandoc няшней.


--
lelf

signature.asc

Anton Nikishaev

unread,
Aug 29, 2013, 11:49:20 AM8/29/13
to erlang-i...@googlegroups.com

On Aug 29, 2013, at 1:26 PM, sVIKs <sv...@i.ua> wrote:

> Делается модуль по обработке email-ов, так вот крупные почтовые сервисы отсылают e-mail в двух вариантах plain text и html, а некоторые только в одно, в котором было написано сообщение. Вот и надо сделать конвертер, либо, как вариант, посмотреть на какой нибудь аналог и сделать свой, а может есть что-то готовое.
>

sVIKs

unread,
Sep 12, 2013, 9:26:54 AM9/12/13
to erlang-i...@googlegroups.com


четверг, 29 августа 2013 г., 13:46:24 UTC+3 пользователь Сергей Прохоров написал:
...

Спасибо Сергей, Ваш метод оказался лучше, чем то что я наваял, но правда в моем случае не использовались доп. библиотеки и легко было добавить "\n" вместо соответственных тегов, но иногда в тексте встречались какие-то спецсимволы и re:replace(Data, ..., ..., [global, {return, binary},unicode]) просто падал с ошибкой. Убираешь unicode и все работает.

Ладно попробую Ваш допилить и довести до логического конца...

Сергей Прохоров

unread,
Sep 13, 2013, 8:09:13 AM9/13/13
to erlang-i...@googlegroups.com
А че, так же как сделана специальная обработка для <a> тега, так же можно добавить отдельные кейсы для <br> и <p> и что там у вас ещё. Очень просто делается.
Советую только почаще делать удаление множественных пробелов (заменять много пробелов/переносов строк на один. Иначе письмо, нормально выглядящее в html сильно расползётся в текстовой версии.

четверг, 12 сентября 2013 г., 17:26:54 UTC+4 пользователь sVIKs написал:

sVIKs

unread,
Sep 13, 2013, 10:52:42 AM9/13/13
to erlang-i...@googlegroups.com
Да, я уже все сделал, что надо. Еще раз спасибо, правда столкнулся с некоторыми особенностями mochiweb_html:parse. Иногда не полностью парсит теги, но это связанно с некорректной версткой самого html, но в браузерах все отображается как положено, но это ерунда. 

пятница, 13 сентября 2013 г., 15:09:13 UTC+3 пользователь Сергей Прохоров написал:
Reply all
Reply to author
Forward
0 new messages