Формат хранения страниц

Структура дерева заметок

При создании программы OutWiker был выбран формат хранения заметок, когда каждая страница представлена папкой в файловой системе с некоторыми служебными файлами. Это решение уменьшает вероятность одновременной порчи всех заметок по сравнению со способом хранением всех заметок в одном файле: если какой-нибудь файл, относящийся к заметке попадет на “битый” сектор жесткого диска, то будет испорчена только эта заметка, а не все дерево заметок. Кроме того, поскольку все записи хранятся в текстовом виде, вы можете просматривать их (а при желании и редактировать) даже не имея под рукой OutWiker. Также такой формат хранения позволяет легко организовать “прикрепленные” к заметке файлы, поэтому OutWiker можно использовать и для каталогизации файлов.

Такое хранение заметок подразумевает, что файлы и папки заметок могут быть в любой момент изменены внешними средствами, например, файловыми менеджерами, с помощью них вы можете переносить заметки из одной ветви дерева в другую или даже в другое дерево с заметками, а если вам не хватает возможностей встроенного в OutWiker редактора, то вы можете редактировать заметки с помощью любого текстового редактора, способного открывать и сохранять файлы в кодировке UTF-8, для этого можно воспользоваться плагином ExternalTools.

Однако такой способ хранения, а особенно предположение, что заметки могут изменяться без участия OutWiker, накладывает ряд ограничений. Во-первых, под Windows на данный момент вы ограничены в длине пути до файла, она не может превышать 255 символов (есть пути обхода этого ограничения, возможно, в будущем эта проблема будет преодолена). Во-вторых, поскольку любая заметка может изменяться без участия OutWiker, нет возможности сделать какой-либо кэш с общей информацией обо всех заметках, например, индекс для поиска или информацию о тегах заметок. Поэтому при глобальном поиске приходится каждый раз заново просматривать содержимое каждой заметки, что может занимать достаточно долгое время.

Как уже было сказано, каждая заметка - это просто папка с некоторыми служебными файлами внутри другой папки-заметки, поэтому для создания вложенной заметки достаточно создать папку с именем вложенной заметки, а в ней создать два файла: __page.opt и __page.text (этот файл не нужен для страниц глобального поиска). Формат хранения каждого типа заметок может отличаться, но файл __page.opt должен присутствовать всегда, о его формате будет написано ниже.

При работе с исходниками OutWiker, например, при создании плагина папки и файлы явно создавать не нужно, для создания заметок и работы с прикрепленными файлами существуют специальные классы внутри API OutWiker (классы, предназначенные для работы со страницами содержатся в файле src/outwiker/core/tree.py.

Также в папке с заметкой может храниться значок, установленный для заметки. Файл со значком может записан в различных графических форматах, но рекомендуется использовать формат png. В этом случае файл со значком должен иметь имя __icon.png. Изображение значка должно иметь размер 16x16 пикселей и может использовать прозрачность. Чтобы внешний вид заметок не зависел от настроек программы OutWiker на различных компьютерах, файл значков копируется в папку с заметкой.

Стиль страниц хранится в файле __style.html. Если нужно, в папке __style могут находиться дополнительные файлы. Подразумевается, что основные определения стиля хранятся в __style.html, а в папке __style могут находиться рисунки или скрипты на языке JavaScript, необходимые для отображения стиля. Если для страницы устанавливается стиль по умолчанию, то файл __style.html и папка __style просто удаляются.

Ограничения на имена заметок

На имена заметок накладываются некоторые ограничения. Во-первых, ограничения накладывает файловая система. Если под Linux имя директории не может включать в себя только нулевой символ (0), а в остальном вы не ограничены, то под Windows вы не можете создать папку (и, соответственно, заметку) с символами >, <, |, ?, *, : и ”. Если вы работаете под Linux, то при попытке создать заметку, содержащую в имени один из этих символов, вы получите предупреждение, показанное на следующем рисунке, но создать заметку сможете.

../../_images/warning.png

Под Windows вам этого сделать не удастся.

Другое ограничение связано со внутренним устройством OutWiker. Все папки внутри папки с заметками, начинающиеся с символов __ (два символа подчеркивания), программа считает служебными директориями и не отображает в дереве заметок. Например, все прикрепленные файлы содержатся в папке __attach внутри каждой заметки (в случае, если прикрепленные файлы есть). Про хранение вложенных файлов будет сказано ниже.

Также ограничения выражаются в том, что внутри одной заметки не может быть двух вложенных заметок с одинаковыми именами.

Обойти эти ограничения можно с помощью псевдонимов.

Формат файла __page.opt

Файл __page.opt является основным файлом в папке заметки, именно он определяет формат страницы, а также различные ее настройки, но этот файл не содержит содержимое страницы, которое видит пользователь (для этого служит файл __page.text).

Файл __page.opt является текстовым и представляет собой ini-файл. То есть в нем содержатся разделы, обозначенные квадратными скобками, а за названием раздела расположены параметры в формате “имя=значение”. Файл должен быть записан в кодировке UTF-8. Ниже приведен пример файла __page.opt, пока не обращайте особого внимания на параметры, мы их рассмотрим ниже.

[General]
type = wiki
tags = html, софт
order = 0
datetime = 2014-04-12 12:46:55.170000
cursorposition = 121
uid = __a07bd7a7-2be3-41f7-a17d-1ec3997ee988
alias = Отображаемое имя страницы

[Tree]
expand = True

[wiki]
md5_hash = cef7664a01cb932d419a203b2e63b568

[Misc]
pageindex = 0

В данном примере содержатся три раздела параметров: General, Tree, wiki и Misc. Количество разделов и настроек внутри них зависит от формата страницы, в этом примере приведены параметры для викистраницы.

Параметры, общие для всех видов страниц

Для начала разберем параметры, общие для всех типов страниц. Начнем с раздела [General].

  • type. Это единственный обязательный параметр среди всех параметров. Именно он определяет тип страницы. На данный момент существуют 4 типа страниц со следующими типами:

    • text - простая текстовая страница.
    • html - страница в формате HTML.
    • wiki - викистраница.
    • search - страница глобального поиска.
  • tags. Этот параметр хранит список меток, которые были применены к странице. Метки перечисляются через запятую (после запятой можно ставить пробел).

  • order. Задает положение заметки в дереве по сравнению с заметками того же уровня. Чем это значение меньше, тем выше располагается заметка в ветви. Если заметки имеют одинаковое значение параметра order или оно отсутствует, то такие заметки сортируются по алфавиту.

  • datetime. Дата и время последнего изменения страницы. Дата и время записывается в формате вида “%Y-%m-%d %H:%M:%S.%f”. За расшифровкой этих символов можете обратиться к документации Python.

  • cursorposition. Положение курсора, которое было перед закрытием страницы. Это значение используется для того, чтобы при повторном открытии страницы курсор стоял на том же самом месте, как и в тот момент, когда страница закрывалась.

  • uid. Уникальынй идентификатор страницы, который используется для ссылок. В приведенном выше примере идентификатор равен __a07bd7a7-2be3-41f7-a17d-1ec3997ee988, это значит, что ссылка на эту страницу будет выглядить как page://__a07bd7a7-2be3-41f7-a17d-1ec3997ee988. При создании заметки странице не присваивается никакой идентификатор, и этот параметр отсутствует, он появляется, когда идентификатор впервые запрашивается, например, при копировании ссылки на страницу в буфер обмена с помощью пункта меню Инструменты ‣ Копировать ссылку на страницу или одноименного пункта контекстного меню.

  • alias. Псевдоним страницы или отображаемое имя. Если данный параметр не задан, то в программе OutWiker имя заметки отображается по имени папки, которая содержит данную заметку. Однако, как было написано выше, это накладывает некоторые ограничения на имена заметок. С помощью псевдонима можно обойти эти ограничения. Псевдоним - это строка, содержащая любые символы. Если для страницы установлен псевдоним, то псевдоним будет отображаться везде вместо имени заметки. Таким образом, для имени папки сохраняются прежние ограничения, а отобржаемое имя заметки может быть произвольным. В основном интерфейсе программы OutWiker нет указаний на возможность установки псевдонимов, чтобы не запутать пользователей. Однако, если вы уверенный пользователь, то можете воспользоваться плагином HackPage, который среди прочего позволяет устанавливать псевдонимы для страниц.

  • expand из раздела [Tree]. Этот параметр имеет булевый тип и может принимать значения True или False. Этот параметр обозначает, должна ли быть развернута ветвь дерева, начинающаяся с этого узла (заметки). Этот параметр используется для того, чтобы при следующем открытии дерева сохранялась “развернутость” всех его узлов.

Хранение значка страницы

Каждая страница может иметь свой значок, который отображается в дереве заметок рядом с заголовком страницы. Пользователь может устанавливать либо один из стандартных значков, который прилагается к программе, либо свои значки. Пользовательские значки добаляются в диалоге настроек в разделе “Значки пользователя”, такие значки хранятся в папке iconset профиля программы (см. Где находится папка профиля программы?).

Все стандартные значки расположены в папке iconset в папке программы, а их имена начинаются с префикса __std_.

Если для страницы устновлен один из стандартных значков, то в файл __page.opt в раздел [General] добавляется параметр icon, значение которого равно относительному пути до файла значка, начиная из папки iconset. Например, если для страницы установлен значок __std_envelope.png, которая расположена непосредственно в папке iconset, то в файле __page.opt будет такая строка:

[General]
icon = __std_envelope.png

Если для страницы установлен значок __std_batman.png из группы “people”, то в файле __page.opt будет такая строка:

[General]
icon = people/__std_batman.png

Если для страницы установлен пользовательский значок, то из файла __page.opt удаляется параметр icon, а в папку заметки будет скопирован пользовательский значок с именем __icon.*, расширение которого совпадает с расширением пользовательского значка. То есть, если исходный пользовательский значок имеет имя myicon.png, то в папке заметки будет создан файл __icon.png.

Такой способ хранения заметок сделан для того, чтобы программа могла бы отображать как стандартные значки, так и пользовательские, которые могут быть не установлены на том компьютере, где открывается дерево заметок.

Хранение вложенных файлов

Как уже было сказано выше, прикрепленные к заметке файлы хранятся в папке __attach, поэтому для добавления новых файлов вы можете не только использовать интерфейс программы, но и копировать файлы в эту папку, используя любой файловый менеджер. Если вы добавляете файл внешними средствами в выбранную в данный момент заметку, не забудьте нажать кнопку “Обновить” в окне “Прикрепленные файлы”, чтобы новые файлы появились в окне программы.

Когда новая заметка только была создана, она не имеет папки __attach, она будет создана только при первой необходимости - когда вы прикрепите какой-нибудь файл, нажмете кнопку “Открыть папку с прикрепленными файлами” в окне “Прикрепленные файлы” или выберете пункт меню :menuselection:”Инструменты –> Копировать путь до прикрепленных файлов”.

Внутри папки __attach могут находиться и вложенные папки, они даже будут показаны в окне “Прикрепленные файлы” но эта особенность программы OutWiker не особо афишируется, поскольку интерфейс для работы с прикрепленными папками пока не очень развит (надо добавить возможность заходить внутрь прикрепленных папок и некоторые другие функции). Но здесь есть одно ограничение - прикрепленные папки не могут начинаться с символов __ (два подчеркивания), поскольку такие папки считаются служебными и не показываются в списке прикрепленных файлов.

Одно из применений таких служебных папок описывается в следующем разделе.

Хранение миниатюр

На викистраницах есть возможность создавать уменьшенные копии изображений (миниатюры) с помощью команды %thumb% ... %%. При использовании этой команды могут быть заданы размеры создаваемых миниатюр. Поскольку миниатюры иногда могут оказаться полезными сами по себе, то они отображаются не просто с помощью тега <img> со ссылкой на оригинальный файл и с атрибутами width и height, задающими размер, а миниатюра создается в виде отдельного файла.

Поскольку в большинстве случаев пользователю незачем видеть созданные миниатюры в списке прикрепленных файлов, а хранить эти файлы где-то надо, для этого в папке __attach создается вложенная папка __thumb. Так как ее имя начинается символов __, она не отображается в списке прикрепленных файлов.

Сами миниатюры хранятся в этой папке и имена их файлов однозначно идентифицируют файл картинки, из которого они были созданы, а также размер миниатюры.

Например, если к викистранице прикреплен файл image.png, а на самой странице содержится текст:

%thumb width=200%Attach:image.png%%

%thumb width=400%Attach:image.png%%

%thumb height=200%Attach:image.png%%

%thumb maxsize=200%Attach:image.png%%

то в папке attach/__thumb/ будут созданы следующий файлы:

  • th_width_200_image.png
  • th_width_400_image.png
  • th_height_200_image.png
  • th_maxsize_200_image.png

Таким же образом создаются миниатюры для каждого размера, и в то же время если в тесте страницы встретится еще одно упоминание миниатюры с тем же размером, то оно не будет создано повторно. К тому же имена миниатюр остаются читабельными, можно легко найти нужную миниатюру и скопировать ее с помощью файлового менеджера в другую папку, если этот файл миниатюр понадобится для других целей.

Формат простых текстовых заметок

Формат файла __page.opt для простых текстовых заметок не имеет каких-то специфических параметров. При этом параметр type в разделе [General] должен иметь значение text.

Текст заметки хранится в файле __page.text в том виде, в котором он отображается в окне редактирования.

Классы, предназначенные для работы с текстовой страницей расположены в папке src/outwiker/pages/text/.

Формат страниц в формате HTML

Страница для заметок в формате HTML должна иметь значение параметра type равным html.

Кроме того, этот тип страниц в разделе [General] имеет дополнительный параметр linewrap булевого типа. Если этот параметр имеет значение True, то для данной заметки будет включен режим “Автоматический перенос строк”, и для каждого введенного в окне редактора переноса строк будет добавлен тег <br>.

Если этот параметр имеет значение False, тогда теги <br> добавляться не будут, и пользователь сам должен будет писать теги <br> или <p> для оформления абзацев. В этом случае введенный код HTML будет интерпретироваться точно так, как он введен. Этот режим может быть удобен, например, для подготовки текста для сайта.

Кроме того, у HTML- и викистраниц есть дополнительный параметр pageindex в разделе [Misc], он определяет, какую вкладку на данной странице в последний раз открывал пользователь. Если пользователь завершил работу со страницей на вкладке “HTML”, это значение будет равно 0, если на вкладке “Просмотр”, то - 1.

При работе с OutWiker пользователь вводит только тело HTML, а именно то, что обычно включается в теги <body>...</body>, после чего программа создает полноценный файл .html, причем есть возможность посмотреть, что же получается в конечном итоге. Результат полного оформления HTML-страницы OutWiker сохраняет в файл __content.html в папке страницы. Этот файл содержит полностью завершенную HTML-страницу со всеми стилями оформления, добавленными переносами строк <br> (если включен режим “Автоматический перенос строк”) и т.д.

Например, для HTML-страницы, содержащей фразу “Hello World”, и использующей стиль страницы по умолчанию, файл __content.html будет выглядеть следующим образом:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv='X-UA-Compatible' content='IE=edge' />
    <meta http-equiv='content-type' content='text/html; charset=utf-8'/>

    <style type='text/css'>
        body, div, p, table {
            font-size:10pt;
            font-family:Verdana;
        }

        img{border:none}

    </style>

</head>

<body>
Hello world!
</body>
</html>

Классы, предназначенные для работы с HTML-страницей расположены в папке src/outwiker/pages/html/.

Формат викистраниц

Формат хранения викистраниц во многом напоминает страницы в формате HTML, поскольку в конечном итоге викинотация преобразуется HTML-код, который также сохраняется в файл __content.html.

Страница, использующая викинотацию, должна иметь значение параметра type равным wiki. Все выше сказанное относительно файла __content.html относится и к викистраницам с учетом того, что от викинотации к HTML-странице текст проходит более сложный путь, и перенос строк на викистраницах работает по своим правилам (нет режима “Автоматический перенос строк”).

Кроме того, HTML-код викистраниц проходит дополнительную стадию обработки, чтобы сделать полученный HTML-код более читабельным, расставляя дополнительные переносы строк (не путать с тегом <br>) после некоторых тегов (за этот процесс отвечает класс HtmlImprover из файла src/outwiker/core/htmlimprover.py).

Для примера, если викистраница имеет содержимое:

*Hello World!*

||border=1
|| Ячейка таблицы 1 || Ячейка таблицы 2 ||
|| Ячейка таблицы 3 || Ячейка таблицы 4 ||

полученный в итоге код HTML будет выглядеть следующим образом:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv='X-UA-Compatible' content='IE=edge' />
    <meta http-equiv='content-type' content='text/html; charset=utf-8'/>

    <style type='text/css'>
        body, div, p, table {
            font-size:10pt;
            font-family:Verdana;
        }

        img{border:none}

    </style>

</head>

<body>
<b>Hello World!</b><br>
<br>
<table border=1>
<tr>
<td align="center">Ячейка таблицы 1</td>
<td align="center">Ячейка таблицы 2</td>
</tr>
<tr>
<td align="center">Ячейка таблицы 3</td>
<td align="center">Ячейка таблицы 4</td>
</tr>
</table>
</body>
</html>

Плагины, такие как, например, Source или TeXEquation, могут добавлять свои теги между тегами <head> ... </head>, а также перед закрывающимся тегом </body>.

Поскольку для очень длинных текстов с викинотацией преобразование в формат HTML может быть сравнительно тяжелой операцией, занимающие единицы секунд, викистраница старается кэшировать полученный результат и не создавать код HTML заново при каждом переключении из вкладки Вики на вкладку Просмотр или “HTML”, как это происходит со страницами в формате HTML.

Для того, чтобы определить, изменилась ли страница, OutWiker рассчитывает контрольную сумму по алгоритму MD5 от строки, полученной склеиванием следующих элементов:

  • Заголовка страницы.
  • Текста страницы.
  • Текущего списка установленных плагинов.
  • Стиля страницы.
  • Списка прикрепленных файлов.
  • Списка дочерних страниц.
  • Некоторых настроек программы, влияющих на сгенерированный код HTML.

Полученный MD5-хэш записывается в параметр md5_hash в разделе [wiki]. Он может выглядеть, например, следующим образом:

[wiki]
md5_hash = dd03106a9e3705caeba5ac75a83ce518

Этот параметр не является обязательным, в случае его отсутствия или, если в нем записана неверная строка, ничего страшного не произойдет, просто данная страница при следующем открытии вкладки “Просмотр” или “HTML” заново создаст файл __content.html, после чего в данный параметр будет записана новая контрольная сумма MD5.

Как и у HTML-страниц, у викистраниц существует параметр pageindex в разделе [Misc], он также определяет, какую вкладку на данной странице в последний раз открывал пользователь. Если пользователь завершил работу со страницей на вкладке “Вики”, это значение будет равно 0, если на вкладке “Просмотр”, то - 1, если на вкладке “HTML”, то - 2.

Классы, предназначенные для работы с викистраницей расположены в папке src/outwiker/pages/wiki/.

Заключение

Подводя итоги всего вышесказанного, содержимое папки заметки может выглядеть следующим образом:

../../_images/files.png

Для страницы со стилем по умолчанию и без прикрепленных файлов папка с заметкой будет выглядеть вот так:

../../_images/files_02.png