Дуже простий і швидкий HTML->TEXT

image

Всі бачили переглядач html-файлів в TotalCommander. Загорівся ідеєю написати простий і дуже маленький текстовий браузер для своєї операційки. Спочатку, дивився в бік asm-xml — відмінний парсер, проте ну дуже вже великий (мій межа — 64 кілобайти, не технічний, просто принцип такий). Нижче описаний дуже простий спосіб отримання тексту з html.



Відразу обмовлюся, що код мені потрібен саме незалежний, (для своєї ОС), тому всі готові бібліотеки відпадають відразу. Чому assembler? — тільки тому що все в моїй ОС пишеться на ньому. Але метод можна пересунути на будь-яку мову…

Отже, оскільки важливий маленький розмір коду — від класичного парсера з побудовою дерева, парсингом ієрархічної структури вирішив відмовитися. Пішов «в лоб».

Власне, процес складається з декількох етапів.
Спочатку потрібно позбавитися від вмісту тегів script — тільки тих, де код написаний безпосередньо, а не там, де підключаються зовнішні скрипти. Чому? Просто дійшов досвідченим шляхом, коли виявив, що деякі, дуже великі, сценарії ламають логіку мого парсера)

Далі йде основний цикл. Ми крок за кроком (точніше байт за байтом) проходимо всі теги (шукаємо відкриття і закриття тега). Тобто у нас в підсумку виходить не дерево тегів, а список, що складається з рядків преполненных dword заголовками.
Якщо текст не підпадає під тег і записуємо його просто як текст.

Структура тимчасова виглядає так (касным виділені заголовки — позначення тегів):

image

Поясню момент. Здавалося б, логічніше кожному тегу видати відповідний хеш або ідентифікатор. Але, для цього потрібно парсити всі види тегів, наприклад: <p <p style=… — треба окремо перевіряти. А у нас же — просто прохід до файлу з порівнянням через кожен байт чотирьох байт:
inc esi
 
cmp byte[esi + 0], '<'
 

Якщо це відкриваючий тег, то <p class… перетворюємо в :p:
Це, звичайно ж, ледарство, говнокод і т. п., але це швидко, коротко і ефективно!

Ну а далі, власне, беремо цей список і рядок за рядком, в залежності від типу тега, віддаємо на обробку відповідної процедури, яка пише вже у вихідний буфер. (Є ще дрібниці естетичні — прибираємо повторення прогалин, переносів і т. п.)

Чекаю коментарів виду: «говнокод», «учи матчасть» і т. п. Тому скажу відразу: код (в кінці статті посилання) — це просто прототип, написаний «на коліні», а щодо «алгоритму» — згоден, це важко назвати алгоритмом, але він працює! Всього 4Кб програма!

За посиланням робочий приклад (перевіряв також на исходнике html головної сторінки хабра — скрін внизу) — все працює. Єдино — обмеження розміру файлу (просто поки не додав виділення пам'яті, використовую 3 по 64 Кб неинициализированных буфера). Після роботи програма видасть два файла — в одному список тимчасовий, у другому — готовий текст. Врахуйте, що в тексті переноси — це 0x0A, тому дивимося TotalCommander'ом в режимі тексту.

Тест на документі «W3C Reformulating HTML in XML»:
image

Тест на головну сторінку Хабрахабра:
image

Ісходник + win32binary

А тепер питання: у кого вийде менше, ніж 4Кб?
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.