Pull to refresh

Comments 33

Например, в XML текст не должен содержать знаков "<" и ">" — они должны быть заменены на "<" и ">" соответственно.

Вы про CDATA не слышали?

level_2+
  for_level_1+ &
    a+
      : 1
      : 2
    ^
    b+
      : 3
      : 4
    ^    
  &
^


Почему парсер не прекращает чтение level2 на первом ^, а дочитывает до конца?

А вообще, для задачи «вставить любые данные без редактирования» давно есть известное решение, и оно называется «length-prefixed». Любое другое (известное мне) имеет ограничения.
Вы про CDATA не слышали?

CDATA — хорошее решение, но все же, если текст будет содержать в себе закрывающую комбинацию, то придется сделать, как в этом примере из википедии:
<![CDATA[]]]]><![CDATA[>]]>

то есть, придется как-то менять (в данном случае — дробить) исходный текст.

А идея использования завершающих строк как раз в том, чтобы можно было подобрать такую завершающую строку, которая в тексте не встретится, например «abc end zzz ///». А если встретится, то назначить другую для этого поля.
CDATA — хорошее решение, но все же, если текст будет содержать в себе закрывающую комбинацию

Какова вероятность этого для обычного человеко-читаемого текста?

А идея использования завершающих строк как раз в том, чтобы можно было подобрать такую завершающую строку, которая в тексте не встретится, например «abc end zzz ///». А если встретится, то назначить другую для этого поля.

И как вы предлагаете это проверять?

В структуре (блоке данных) «level_2» указано только одно поле — «for_level_1», [...] Все, что находится между «for_level_1+ &» и "&"

Как парсер понимает, что внутри level_2 — поле, но внутри for_level_1 — текст?

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

А человеку обычно и не надо руками запихивать в поле человекочитаемого документа существенный кусок документа на другом (или том же) языке. У вас явно смешаны две разных задачи.
100%, если это текст комментария с обсуждением CDATA :-)
Посмотрите на свой (или мой) комментарий, обсуждающий CDATA, и убедитесь, что это не так.
[Да]
[Сарказм] [Нет]
[Что?]
Отвечу сразу на два вопроса
Какова вероятность этого для обычного человеко-читаемого текста?

и
А человеку обычно и не надо руками запихивать в поле человекочитаемого документа существенный кусок документа на другом (или том же) языке


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

Для формата HV (который описывается в этой статье) — пример уже есть — как раз «for_level_1». Здесь все решается переопределением завершающей строки. Исходный текст не меняется.

Для подавляющего большинства известных форматов, например, того же XML.CDATA — придется вносить изменения в исходный текст.
Первое, что пришло в голову — человек хочет написать пример использования формата FORMAT и поместить этот пример в текстовое поле в том же самом формате FORMAT. Он использует обычный текстовый редактор, чтобы редактировать все это.

Картинку про буханку знаете? Так вот, зачем?

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

Задачи бывают разные. И такие тоже встречаются.

Для разных задач удобнее разные инструменты.

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

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


Не символа, а целой строки (не подстроки!), которая не встречается в исходном тексте. То есть простые вхождения завершающих строк в качестве подстрок в более длинные строки не считаются концом текста.

1) В тексте несложно найти строки, которые целиком равны завершающей.

2) Можно переопределять завершающие строки. В особо сложных случаях можно ввести случайный набор символов.
В тексте несложно найти строки, которые целиком равны завершающей.

Нашли, что дальше?
У вас явно смешаны две разных задачи.

Задачи бывают разные. И такие тоже встречаются.
Я предложил вариант решения подобных задач с полным сохранением исходного текста.
Как парсер понимает, что внутри level_2 — поле, но внутри for_level_1 — текст?


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


То есть, все поля, которые ожидаются в той или иной структуре (блоке данных), заранее «регистрируются» в приложении. На поле с незнакомым именем выдастся ошибка.
Эээ, то есть у вас еще есть и предопределенная схема? А в каком формате она задается? А как пользователю, работаюшему с файлом, быть уверенным, что документ соответствует схеме?
Как парсер понимает, что внутри level_2 — поле, но внутри for_level_1 — текст?

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


Да.
Я этому ньюансу уделил мало внимания в статье. После Вашего комментария добавил упоминание об этом в статью.
Зачем для структуры вообще завершающий символ?
Чтобы парсер понял, что структура закончилась и считана полностью.

Иначе следующее поле будет считаться частью этой структуры. Это будет путаница и для парсера, и для человека.

Любое многстрочное поле (которым является структура в данном синтаксисе) начинается с имени, а заканчивается завершающей строкой.
Чтобы парсер понял, что структура закончилась и считана полностью. Иначе следующее поле будет считаться частью этой структуры.

А как же схема?
Почему парсер не прекращает чтение level2 на первом ^, а дочитывает до конца?

В структуре (блоке данных) «level_2» указано только одно поле — «for_level_1», для которого переопределена завершающая строка. Теперь для поля «for_level_1» завершающая строка равна "&"

Парсер считывает поля и строки последовательно, поэтому он начинает искать строку "&", чтобы завершить чтение поля «for_level_1»

Все, что находится между «for_level_1+ &» и "&", считывается в качестве текста, поэтому символы "^", которые внутри этого могут встретиться, никак не влияют на парсер.

После этого он ищет либо новое поле в структуре «level_2», либо завершающую строку для «level_2», которая для равна "^".

В итоге все парсится без ошибок
и оно называется «length-prefixed»

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

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

1. Много вариантов записи многострочного текста и каждый со своими ограничениями.
2. Нужно внимательно следить, чтобы в многострочном тексте не было завершающей конструкции.
3. Возможность записи без отступов — скорее вредная (человеку сложно воспринимать), чем полезная (экономия на спичках).

Как насчёт такого варианта? http://habrahabr.ru/post/248147/

1. Управляющих символов всего 2.
2. Однозначно указывается какие отступы попадают в значение, а какие нет.
3. Есть только одна форма записи и её невозможно превратить в нечитаемую лапшу.
Много вариантов записи многострочного текста и каждый со своими ограничениями

Я бы назвал не ограничениями, а особенностями.

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

Формат HV задумывался, как предоставляющий некоторый выбор — это касается как учета отступов в тексте, так и определения завершающих строк. Например, если кому-то нагляднее видеть "!!!THIS IS END!!!" в конце текстового поля — и он смог бы указать использовать именно эту комбинацию.
Нужно внимательно следить, чтобы в многострочном тексте не было завершающей конструкции.

Символ "^" выбран не случайно — мало в каком тексте он встретится в качестве одиночной строки. Но если есть опасения, что в тексте он встретится, то можно переопределить завершающую строку.

На крайний случай, ничто не мешает для отдельно взятого поля определить в качестве завершающей строки, например, "//////////" или даже "!@#$%^^!%@%#&#)($&*#^&*#(#&$^$*$&#^#*$*$&$" — с каждым новым символом шанс совпадения в каком-либо тексте стремится к нулю
Возможность записи без отступов — скорее вредная (человеку сложно воспринимать), чем полезная (экономия на спичках)

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

Но я не спорю, что это может быть использовано не в меру, а значит во вред удобочитаемости. Все зависит от пользователя.

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

Почему вы даёте пользователю выбор как завершить текстовое поле, но не даёте выбор как завершать конец строки? И почему вы не даёте мне выбор называть чёрное белым, а белое чёрным? Я требую, чтобы вы добавили эту несомненно необходимую гибкость в формат! :-) А если серьёзно, то я не хочу каждый раз размышлять о том, чем закончить текстовое поле.

Не представляю, как удаление отступов может уменьшить читабельность. Вы сейчас высасываете из пальца аргументы для защиты своего детища, вместо того, чтобы улучшить его, своровав идеи у конкурента или же отказаться от велосипеда, если конкурент лучше решает проблемы, поставленные в начале вашей статьи. Вы способны объективно сравнить два решения указанных проблем?
Как мне кажется, в целом выглядит получше, чем форматы, описанные в других аналогичных статьях на хабре. Возможно, кому-то и пригодится.
Навскидку вопросы такие:
Если надо сохранить в поле весь текст этой статьи с комментариями, какой разделитель выбрать? Получается, нужен какой-то редактор, который будет назначать разделители или хотя бы просто проверять валидность разметки.
Если надо в одном поле сохранить завершающий перевод строки, а в другом нет, какая у них должна быть разметка?
Если надо сохранить в поле весь текст этой статьи с комментариями, какой разделитель выбрать? Получается, нужен какой-то редактор, который будет назначать разделители или хотя бы просто проверять валидность разметки.


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

Из внешних инструментов может подойти любой внешний генератор уникальных последовательностей, например UUID или vaomark.com

Да, способ в этом плане для большого и разнообразного текста не дает 100% гарантии, что без использования методов поиска и/или генерации можно будет подобрать подходящую завершающую строку. Согласен, что это усложняет задачу.

Но зато исходный текст останется без каких-либо правок. И на мой взгляд, в данном случае, это удобнее, чем если бы пришлось отсчитывать строгое количество отступов (как, например, в YAML) или подменять какие-либо символы.
Если надо в одном поле сохранить завершающий перевод строки, а в другом нет, какая у них должна быть разметка?


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

Например:

text%
  .string 1
  .string 2
  .
^


В следующей версии обязательно рассмотрю возможность более удобно это реализовать. Кончено же, с обратной совместимостью.
В целом выглядит интересно, правда не очень понял, в чём смысл этого:
Вариант Б. Начинать учитывать отступы от первого непробельного символа в каждой строке, причем сам этот первый символ учитываться не будет:

Это чтобы часть пробелов не учитывать, а часть учитывать? В каком сценарии такое может быть нужно?
Это чтобы часть пробелов не учитывать, а часть учитывать? В каком сценарии такое может быть нужно?


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

Например:

level1+
  level2+
    level3+
      level4+
        text%
          >  Это красная строка.
          >А это обычная строка.
          >  Это еще одна красная строка.
          >     Это цитата, которая имеет свое количество отступов.
          >     И эти отступы легче посчитать от первого символа, чем от левого края.
        ^
      ^
    ^
  ^
^


«часть пробелов не учитывать, а часть учитывать» — это вытекающий эффект из вышесказанного функционала.
Ну я кажется понял. Более простым языком выражаясь — чтобы вложенность (визуально) сохранить.
Sign up to leave a comment.

Articles

Change theme settings