PTTJS — формат текстового хранения комплексных таблиц

от автора

PTTJS — plain text table javascript, формат разработанный из личной необходимости и острой нужды.

Публикую в народ, потому что уверен, что не меня одного волнуют ограничения и проблемы текущих форматов для табличных данных.

Уже написаны JS библиотека с парсером и сериализатором, а также Obsidian плагин.

Цель

Главная цель формата PTTJS — получить текстовый формат таблиц, который позволяет хранить более сложные таблицы, нежели существующие форматы (CSV, MD), но при этом сохранять читаемость и текстовую основу.

Мотивация

Мотивация для разработки копилась в течении долгого времени, ведь Я как и все нормальные люди готов мириться с некоторыми неудобствами. Но недавно терпение кончилось и пришлось взяться за проработку и разработку.

Решающими стали факторы:

  1. Необходимость передавать в LLM более сложные таблицы нежели обычные CSV или MD форматы. Очень часто в документах встречаются сложносоставные таблицы, которые невозможно перевести в текстовый формат. Из-за чего приходится использовать более сложные и тяжелые мультимодальные модели.

  2. Необходимость распознавать сложносоставные таблицы с помощью CV возвращая простой текст, а ни какой-нибудь многовложенный JSON, который ещё нормально не перепроверишь, пока не отрендеришь.

  3. Необходимость обучать LLM работе целиком с таблицей, а не через костыли внутри Google Shets или Microsoft Excel. Дать возможность LLM-ке самой крутить стобцы, строки, формулы, как ей понадобится.

  4. Невозможность открыть большинство, даже простых таблиц, которые, за неимением аналогов, все хранят в XLS(X) или ODT, без специального ПО.

  5. Желание работать с более сложными таблицами в текстовых редакторах и ПО по типу Obsidian.

  6. Личная неприязнь к Google Shets и Microsoft Excel (надеюсь Я не один такой).

проблема указанная в 1 и 2 пунктах, попробуйте нормально распознать и вставить в текст

проблема указанная в 1 и 2 пунктах, попробуйте нормально распознать и вставить в текст

Описание формата

Первая строка всегда отдана под аннотацию:
|PTTJS 1.0|encoding=UTF‑8|\n

Страницы

Каждая таблица лежит на странице:

|(@P1|Название страницы){\n — начало страницы, в скобках: id страницы начинается с символа «@» и название страницы.

}|\n — конец страницы.

Обозначения страницы опциональны, если их нет, вся таблица на одной странице.

Ячейки

Вся таблица состоит из ячеек и обозначения конца строки:

|H([1|1]1|1|@C1)> — начало ячейки, H — пометка, что это заголовок, в круглых скобках: индекс ячейки по X и Y в квадратных скобках, масштаб (scale) ячейки по X и Y и id ячейки (начинается с символа «@»).

<|\n — конец строки.

H — опциональная пометка, что ячейка — это заголовок.

Индекс ячейки по X и Y — опционален, при обработке просто заполняется итеративно по ячейкам и строкам, начиная с [0|0]. Можно выгрузить при необходимости не визуальной обработки (в скрипте или c помощью AI).

Масштаб (scale) ячейки по X и Y — опционален и по умолчанию равен 1|1.
Масштаб всегда указывается в верхней левой ячейке.

Id ячейки — опционален, нужен для ссылок и направленных формул.

Даже если в строке нет значений, но после неё есть строки, надо указать в строке хотя бы одну пустую ячейку |><|.

Данные внутри ячеек не должны содержать символов ответственных за указание новой ячейки, конца строки, фигурных скобочек и переноса строки («\n«, «|«, «>«, «<«, «{«, «}«).

Все эти символы должны быть заменены на URL Encode аналоги:

Новая строка (\n) -> %5Cn
Вертикальная черта (|) -> %7C
> -> %3E,
< -> %3C,
{ -> %7B,
} -> %7D,

чтобы парсер валидно воспринимал данные.

В библиотеке в serializer.js есть функция escapeValue, которая может заменить символы на URL Encode вариант.

В библиотеке в parser.js есть функция unescapeValue, которая может заменить символы обратно из URL Encode варианта в обычный вид.

Скрипты

>>>SCRIPT\n — начало блока скриптов

<<<SCRIPT\n — конец блока скриптов

Блок скриптов всегда находится после всех данных и может работать с данными на разных листах.

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

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

Можно определять свои функции в редакторе.

Стили присваиваются с помощью символа «<=» и описываются в CSS подобном формате (тут также будут срабатывать JS функции для стилизации).

Форматы ячеек присваиваются символом «=>» и указывают на формат данных в ячейках (это тоже JS функции).
Например NUMBER(2,’ ‘), первый параметр это decimals — количество цифр после запятой, а второй — разделитель тысяч, в нашем случае пробел ‘ ‘.

Можно добавлять скрипты для всей строки или столбца или вообще всего диапазона с помощью двойного указания индекса через двоеточие «:», например вся первая строка (0:0|0), или весь первый столбец (0|0:0) и т.д.

Скрипты это опциональный блок.

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

При выгрузке — скрипты можно сохранять отдельным файлом, например с суффиксом «.script».

Примеры

Пример простой таблицы, например для хранения данных о машинах:

|PTTJS 1.0| |H>Номер машины|H>Год выпуска|H>Марка модель<| |>080XXX02|>2005|>LEXUS RX 350<| |>787XXX16|>2015|>GEELY GC7<| |>871XXX05|>1997|>TOYOTA IPSUM<| |>A602XXX|>1996|>MITSUBISHI PAJERO<| |>890XXX02|>1997|>TOYOTA LAND CRUISER PRADO<| |>216XXX13|>2007|>DAEWOO NEXIA<|

Пример простой таблицы, c индексами:

|PTTJS 1.0|encoding=UTF‑8| |H([0|0])>Номер машины|H([1|0])>Год выпуска|H([2|0])>Марка модель<| |([0|1])>080XXX02|([1|1])>2007|([2|1])>LEXUS RX 350<| |([0|2])>787XXX16|([1|2])>2015|([2|2])>GEELY GC7<| |([0|3])>871XXX05|([1|3])>1997|([2|3])>TOYOTA IPSUM<| |([0|4])>A602XXX|([1|4])>1996|([2|4])>MITSUBISHI PAJERO<| |([0|5])>890XXX02|([1|5])>1997|([2|5])>TOYOTA LAND CRUISER PRADO<| |([0|6])>216XXX13|([1|6])>2007|([2|6])>DAEWOO NEXIA<|

Пример таблицы cо «сложным» заголовком:

|PTTJS 1.0|encoding=UTF‑8| |H(1|2)>Номер машины|H(2|1)>Данные о машине|H><| |H>|H>Год выпуска|H>Марка модель<| |>080XXX02|>2007|>LEXUS RX 350<| |>787XXX16|>2015|>GEELY GC7<| |>871XXX05|>1997|>TOYOTA IPSUM<| |>A602XXX|>1996|>MITSUBISHI PAJERO<| |>890XXX02|>1997|>TOYOTA LAND CRUISER PRADO<| |>216XXX13|>2007|>DAEWOO NEXIA<|
визуализация из Obsidian

визуализация из Obsidian

В этом примере объединены первые ячейки первых двух строк, с заголовком «номер машины» и объединены вторая и третья ячейки первой строки с заголовком «Данные о машине».

Объединенные ячейки остаются. Это нужно чтобы не потерять позиционную информацию.

Пример простой таблицы, c индексами и скриптами:

|PTTJS 1.0|encoding=UTF‑8| |H([0|0])>Номер машины|H([1|0])>Год выпуска|H([2|0])>Марка модель<| |([0|1])>080XXX02|([1|1])>2007|([2|1])>LEXUS RX 350<| |([0|2])>787XXX16|([1|2])>2015|([2|2])>GEELY GC7<| |([0|3])>871XXX05|([1|3])>1997|([2|3])>TOYOTA IPSUM<| |([0|4])>A602XXX|([1|4])>1996|([2|4])>MITSUBISHI PAJERO<| |([0|5])>890XXX02|([1|5])>1997|([2|5])>TOYOTA LAND CRUISER PRADO<| |([0|6])>216XXX13|([1|6])>2007|([2|6])>DAEWOO NEXIA<| |([0|7])><| |([0|8])>Средний год выпуска|([1|8])>2003<|  >>>SCRIPT (1|1,1|6)=>NUMBER(2,' ') (1|8)=DIV(SUM(1|1,1|6),COUNT(1|1,1|6)) (0|8:8)<=BORDER(each,2,solid,#000) <<<SCRIPT

В этом примере у нас есть девятая строка, во второй ячейке которой лежит формула среднего значения диапазона ячеек.

Ещё указаны форматы ячеек во втором столбце со 2 по 7 строках, это числовой формат.

Также мы присвоили CSS стили диапазону ячеек, а именно обводку каждой ячейки черного цвета и толщиной 2.

Планы

  1. Предстоит доделать срабатывание функций из блока скриптов на объекте Store, который получается после парсинга.

  2. Добавить функции преобразования форматов (XSL(S), ODT, CSV, MD <-> PTTJS)

  3. Добавить библиотеки для других языков.

  4. Сделать легкий веб интерфейс для работы с PTTJS.

Сотрудничество (контрибьютинг)

GitHub репозиторий открыт, можете предлагать изменения.

Заключение

На этом всё, спасибо что уделили время, надеюсь смог помочь решить чьи-то аналогичные проблемы.


ссылка на оригинал статьи https://habr.com/ru/articles/908394/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *