Я разработал удобный способ представления и редактирования JSON в электронных таблицах, которым я очень доволен и хотел бы поделиться!

[Эта работа еще не завершена, но сейчас я публикую ее, чтобы получить отзывы!]

Я успешно объединил JSON с электронными таблицами и разработал универсальный подход и пример реализации, которыми я хотел бы поделиться. Поэтому я кратко опишу, как это работает (и поделюсь кодом и примерами), в надежде получить отзывы и критику.

Вот вопрос, на который я пытаюсь ответить:

Как можно удобно и компактно представлять, просматривать и редактировать JSON в электронных таблицах, используя сетку вместо множества знаков препинания?

Моя цель - иметь возможность легко редактировать данные JSON в любой электронной таблице, удобно копировать и вставлять сетки JSON в виде файлов TSV (формат, который Google Sheets помещает в ваш буфер обмена), а также эффективно экспортировать и импортировать эти таблицы как JSON.

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

Он особенно эффективен с Google Таблицами, поскольку может запускать код JavaScript для экспорта, импорта и проверки JSON, обеспечивать цветную подсветку синтаксиса, отзыв об ошибках, интерактивные диалоговые окна мастера и интеграцию с другими службами. Затем другие приложения и службы могут легко получить эти живые электронные таблицы в виде файлов TSV, которые очень легко преобразовать в двухмерные массивы строк для преобразования в JSON.

Это новая реализация некоторых старых идей, которые я успешно использовал в течение многих лет с файлами CSV и Python в течение многих лет, а также некоторые новые идеи, ориентированные на JSON, JavaScript и Google Таблицы. Теперь это универсальное приложение, ориентированное на JSON, написанное на JavaScript, интегрированное с Google Sheets, а также с Unity3D, и я выпускаю простую библиотеку, которая работает в браузерах, Google Sheets и node.js как бесплатное программное обеспечение.

Вот пример электронной таблицы, которая включает несколько листов с разной структурой и скрипт для преобразования электронной таблицы в JSON. Примеры предназначены для настройки приложения UnityJS, моста сценариев JavaScript ‹= JSON =› C #, который я разрабатываю для Unity3D, но идея редактирования JSON в электронных таблицах является независимой и полезной сама по себе, особенно синергетическая с Google Таблицами.



Первый лист с именем «world» - это объект верхнего уровня, который настраивает приложение Unity3D, написанное на JavaScript (это UnityJS, другая история, но просто подумайте об этом JSON как о произвольном, но нетривиальном примере). Итак, мир представляет собой большую причудливую структуру JSON, используемую кодом JavaScript для создания и настройки множества сборных элементов.

Как вы, очевидно, видите, вы просто пишете свои JSON-выражения в виде контура с отступом с именами типов перед значениями, помещая ключи, типы и значения в отдельные ячейки с отступом.

object
    tileRows        number  10
    tileColumns     number  10
    materialTiling  object
                    x       number  4
                    y       number  4
    materialOffset  object
                    x       number  0.5
                    y       number  0.5
    …

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

    …
    texturePaths        sheet  texturePaths
    prefabMap           sheet  prefabMap
    bowConfigs_outline  sheet  bowConfigs_outline
    bowConfigs          sheet  bowConfigs_table
    …

Есть еще один лист с именем texturePaths, который содержит массив строк:

array
    string Joao Paulo/Textures/Abstract_001/Abstract_001
    string Joao Paulo/Textures/Abstract_001/Abstract_002
    string Joao Paulo/Textures/Abstract_001/Abstract_003
    …

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

Есть также несколько удобных способов компактного представления повторяющихся структурированных данных. Один из распространенных типов - это 2-мерный массив элементов одного типа, который можно создать с помощью псевдотипа «сетка»:

…
    tileName  grid           string     10         10
              Hex_Sand       Hex_Sand   Hex_Magma  Hex_Sand  …
              Hex_Grass_Dry  Hex_Magma  Hex_Sand   Hex_Sea   …
              …              …          …          …         …

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

Но вы можете создать сетку псевдотипа «лист» с сеткой имен листов, каждый из которых содержит любой тип или псевдотип объекта.

Он также поддерживает псевдотип «json», который позволяет помещать произвольное выражение JSON в одну ячейку.

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

=INDEX(prefabMap!$E$5:$E$26,
       RANDBETWEEN(1, COUNTA(prefabMap!$E$5:$E$26)))

Более того, вы можете использовать именованные диапазоны для разметки строк, столбцов и сеток ячеек в электронной таблице для использования в таких выражениях, как:

=INDEX(roads, RANDBETWEEN(1, COUNTA(roads))

Еще один отличный способ компактного представления повторяющихся структур JSON в электронной таблице - использовать таблицу, заголовки которой определяют структуру, имена ключей и типы массивов и объектов JSON.

По сути, это то, что Console.table делает с массивом объектов, но с обменом строк и столбцов и поддержкой произвольно вложенных массивов и объектов.

На листе «bowConfigs_outline» есть стандартный массив с форматированием контура, состоящий из двух объектов JSON (конфигурации радужного лука), которые имеют одинаковую структуру. Это 175 строк и 9 столбцов (1575 ячеек, многие из которых пусты, со многими повторяющимися типами и именами ключей).

array 
 object 
 bowStart number 0 
 bowEnd number 0.8 
 bowHeight number 30 
 startWidth number 1 
 endWidth number 0 
 widthMultiplier number 5 
 fromLocalOffset object 
 x number 6
 toLocalOffset object 
 x number -6
 …

На листе «bowConfigs_table_compact» показано компактное табличное представление той же самой структуры с заголовками, которые неявно описывают форму структуры, так что есть одно значение для каждого столбца, без строк или столбцов бесполезного пространства. Это всего 4 строки (строка с типом «таблица», строка с заголовками плюс одна строка для каждой структуры) и 58 столбцов (232 ячейки, несколько пустых, без излишне повторяющихся типов или имен ключей). < br /> Выравнивание всех значений с одним и тем же именем и типа в вертикальных столбцах позволяет очень легко просматривать и редактировать значения, а также применять формулы электронной таблицы для их динамического вычисления! Было бы намного сложнее отследить и применить формулу к каждому свойству «bowEnd» в формате структуры.

(Показано здесь как значения, разделенные запятыми, поскольку заголовки содержат пробелы, и это может сбивать с толку.)

Верхняя строка представляет собой серию столбцов токенов, включая [и] для массивов, {и} для объектов, а также ключи и типы для объектов и элементов массива. Это похоже на простую горизонтальную схему, которая определяет структуру JSON, имена ключей, типы и столбцы, так что ничего не нужно повторять и не тратить лишнее пространство.

table
 ,{ bowStart number,bowEnd number,bowHeight number,startWidth number,endWidth number,widthMultiplier number,fromLocalOffset { x number },toLocalOffset { x number },lineRenderer/startColor { r number,g number,b number },lineRenderer/endColor { r number,g number,b number },lineRenderer/alignment string,lineRenderer/widthCurve { animationCurveType string,keys [ { time number,value number }, …
 ,0,0.8,30,1,0,5,6,-6,0.8782983063,0.7984165253,0.0370873959,0.7169641118,0.7843719274,0.3921475355,View,Keys,0,1,0.25,0.2,0.5,0.5,0.75,1,1,0,Blend,0,1,0.25,0.5,0.5,1,0.75,0.5,1,1,0,0.9368487271,0.6433703118,0.198860128,0.25,0.4861432977,0.5704963395,0.6107422953,0.5,0.9640410996,0.08846161285,0.05927839517,0.75,0.1199717053,0.2262674866,0.7876422776,1,0.6955264667,0.01858220912,0.7418451801
 …

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

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

Некоторые люди смеются надо мной, когда я говорю, что предпочитаю электронные таблицы планировщикам или даже текстовым редакторам. Мне бы очень понравилось, если бы существовал приличный редактор JSON с древовидной структурой, такой же мощный и вездесущий, как Google Таблицы, но я никогда о нем не слышал. Скажите, если есть, пожалуйста!

Userland Frontier (позже Radio Userland) приблизился к этому идеалу, предшествовав, а затем адаптировавшись как к XML, так и к JSON, но никогда не достигал точки того, что вы можете легко сделать с электронной таблицей.

Философия

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

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

Я попробовал применить к дизайну Дзен Python:

Красивое лучше, чем уродливое.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложное лучше, чем сложное.
Плоское лучше, чем вложенное.
Разреженное лучше, чем плотное.
Важна удобочитаемость.
Особых случаев недостаточно, чтобы нарушать правила.
Хотя практичность важнее чистоты.
Ошибки никогда не должны проходить незаметно.
Если явно не заставить замолчать.
Перед лицом двусмысленности не поддавайтесь искушению угадать.
Должен быть один - а желательно только один - очевидный способ сделать это.
Хотя такой способ может быть сначала не будет очевидным, если вы не голландец.
Сейчас лучше, чем никогда.
Хотя никогда не бывает лучше, чем * прямо * сейчас.
Если реализацию трудно объяснить, это плохая идея.
Если реализацию легко объяснить, это может быть хорошей идеей.
Пространства имен - отличная идея - давайте сделаем их больше!

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

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

И есть также общая проблема, состоящая в том, что таблицы CSV и TSV почти, но не совсем несовместимы.

Я думаю, что есть некоторая ценность в определении минимального набора «тегов» и разрешении тегов расширения (даже макроязыка, который позволяет вам определять свои собственные теги расширения, почти так же, как OpenLaszlo позволяет вам определять классы, которые вы можете использовать в качестве тегов xml. ).

Я очень придерживался номенклатуры JavaScript («число», «объект», «логическое значение» и т. Д.). Но не полностью устоял перед соблазном определять синонимы («float» является синонимом «числа», но есть также «целое число» (но не синоним «int») только потому, что они на самом деле выполняют преобразования разных типов (parseFloat -vs- parseInt). Но нет никаких неуместных синонимов для сокращений, таких как «bool» для «логического», «dict» для «объекта» и т. д.

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

В конце концов я хотел бы развить его в механизм создания макросов для JSON (или структур более высокого уровня, которые могут быть представлены как JSON). Вроде как Genshi (система шаблонов XML / Python, которую я много использовал и люблю за ее простоту).



Предшественником Genshi была система шаблонов XML под названием Kid, и они более или менее совместимы. Genshi и Kid похожи, но намного проще и лучше, чем почтенные шаблоны страниц Zope с их макросами TAL (язык атрибутов шаблонов) и METAL. Их всех объединяет то, что они использовали пространства имен XML с атрибутами и тегами для разметки XML-шаблонов, со специальными атрибутами и тегами для циклов, условных выражений, определений функций и шаблонов и т. Д.

Но обычный JSON не дает возможности разметить структуры JSON с помощью «внеполосной» информации, как это делает XML, от которого зависит Генши.

Однако, представляя JSON в электронной таблице, становится возможным представлять метаданные и внеполосную разметку, например управляющие структуры, с помощью соседних ячеек слева или справа или даже целых строк!

Таким образом, вы можете заключать условные и повторяющиеся строки в конструкции «if» и «loop», которые динамически оцениваются на лету для создания JSON! И, конечно, вы можете определять и вызывать именованные шаблоны с параметрами.

Задача состоит в том, чтобы придумать простой и удобный синтаксис для представления шаблонов JSON в электронных таблицах, который был бы гладким и прозрачным, как Genshi, но не громоздким и громоздким, как шаблоны страниц Zope.