Как парсер понимает, что внутри level_2 — поле, но внутри for_level_1 — текст?
Ответ есть в статье:
Типизация и все проверки на соответствие осуществляются в обработчике HV — ему известно заранее, какие имена полей могут встретится и значения какого типа и формата они должны содержать.
То есть, все поля, которые ожидаются в той или иной структуре (блоке данных), заранее «регистрируются» в приложении. На поле с незнакомым именем выдастся ошибка.
Какова вероятность этого для обычного человеко-читаемого текста?
и
А человеку обычно и не надо руками запихивать в поле человекочитаемого документа существенный кусок документа на другом (или том же) языке
Первое, что пришло в голову — человек хочет написать пример использования формата FORMAT и поместить этот пример в текстовое поле в том же самом формате FORMAT. Он использует обычный текстовый редактор, чтобы редактировать все это.
Для формата HV (который описывается в этой статье) — пример уже есть — как раз «for_level_1». Здесь все решается переопределением завершающей строки. Исходный текст не меняется.
Для подавляющего большинства известных форматов, например, того же XML.CDATA — придется вносить изменения в исходный текст.
Возможность записи без отступов — скорее вредная (человеку сложно воспринимать), чем полезная (экономия на спичках)
Это тоже на выбор пользователя. Рассчет был на гибкость. Я считаю, что у каждого свои представления о наглядности, и кому-то может пригодится такая свобода в отступах для улучшения этой самой наглядности.
Но я не спорю, что это может быть использовано не в меру, а значит во вред удобочитаемости. Все зависит от пользователя.
Ну и еще, например, можно значительно сократить количество отступов для очень глубоко вложенных данных, а то они могут пропасть за правым краем монитора.
Нужно внимательно следить, чтобы в многострочном тексте не было завершающей конструкции.
Символ "^" выбран не случайно — мало в каком тексте он встретится в качестве одиночной строки. Но если есть опасения, что в тексте он встретится, то можно переопределить завершающую строку.
На крайний случай, ничто не мешает для отдельно взятого поля определить в качестве завершающей строки, например, "//////////" или даже "!@#$%^^!%@%#&#)($&*#^&*#(#&$^$*$&#^#*$*$&$" — с каждым новым символом шанс совпадения в каком-либо тексте стремится к нулю
Много вариантов записи многострочного текста и каждый со своими ограничениями
Я бы назвал не ограничениями, а особенностями.
Основным символом для обозначения текста все же является "+", т.е. где при парсинге отступы не учитываются. А из двух оставшихся вариантов, я думаю, каждый просто сделал бы для себя выбор, какой из них использовать — либо с отступами от начала строки, либо с отступами от первого символа.
Формат HV задумывался, как предоставляющий некоторый выбор — это касается как учета отступов в тексте, так и определения завершающих строк. Например, если кому-то нагляднее видеть "!!!THIS IS END!!!" в конце текстового поля — и он смог бы указать использовать именно эту комбинацию.
На мой взгляд, человеку будет неудобно каждый раз подсчитывать длину исходного текста и/или подгонять в рамки размера блока, особенно при частом редактировании.
То есть, любые манипуляции с величиной, затрагивающей длину текста, для обработки человеком, требуют дополнительных инструментов, помимо «блокнота».
Почему парсер не прекращает чтение level2 на первом ^, а дочитывает до конца?
В структуре (блоке данных) «level_2» указано только одно поле — «for_level_1», для которого переопределена завершающая строка. Теперь для поля «for_level_1» завершающая строка равна "&"
Парсер считывает поля и строки последовательно, поэтому он начинает искать строку "&", чтобы завершить чтение поля «for_level_1»
Все, что находится между «for_level_1+ &» и "&", считывается в качестве текста, поэтому символы "^", которые внутри этого могут встретиться, никак не влияют на парсер.
После этого он ищет либо новое поле в структуре «level_2», либо завершающую строку для «level_2», которая для равна "^".
CDATA — хорошее решение, но все же, если текст будет содержать в себе закрывающую комбинацию, то придется сделать, как в этом примере из википедии:
<![CDATA[]]]]><![CDATA[>]]>
то есть, придется как-то менять (в данном случае — дробить) исходный текст.
А идея использования завершающих строк как раз в том, чтобы можно было подобрать такую завершающую строку, которая в тексте не встретится, например «abc end zzz ///». А если встретится, то назначить другую для этого поля.
Ответ есть в статье:
То есть, все поля, которые ожидаются в той или иной структуре (блоке данных), заранее «регистрируются» в приложении. На поле с незнакомым именем выдастся ошибка.
Задачи бывают разные. И такие тоже встречаются.
Я предложил вариант решения подобных задач с полным сохранением исходного текста.
и
Первое, что пришло в голову — человек хочет написать пример использования формата FORMAT и поместить этот пример в текстовое поле в том же самом формате FORMAT. Он использует обычный текстовый редактор, чтобы редактировать все это.
Для формата HV (который описывается в этой статье) — пример уже есть — как раз «for_level_1». Здесь все решается переопределением завершающей строки. Исходный текст не меняется.
Для подавляющего большинства известных форматов, например, того же XML.CDATA — придется вносить изменения в исходный текст.
Это тоже на выбор пользователя. Рассчет был на гибкость. Я считаю, что у каждого свои представления о наглядности, и кому-то может пригодится такая свобода в отступах для улучшения этой самой наглядности.
Но я не спорю, что это может быть использовано не в меру, а значит во вред удобочитаемости. Все зависит от пользователя.
Ну и еще, например, можно значительно сократить количество отступов для очень глубоко вложенных данных, а то они могут пропасть за правым краем монитора.
Символ "^" выбран не случайно — мало в каком тексте он встретится в качестве одиночной строки. Но если есть опасения, что в тексте он встретится, то можно переопределить завершающую строку.
На крайний случай, ничто не мешает для отдельно взятого поля определить в качестве завершающей строки, например, "//////////" или даже "!@#$%^^!%@%#&#)($&*#^&*#(#&$^$*$&#^#*$*$&$" — с каждым новым символом шанс совпадения в каком-либо тексте стремится к нулю
Я бы назвал не ограничениями, а особенностями.
Основным символом для обозначения текста все же является "+", т.е. где при парсинге отступы не учитываются. А из двух оставшихся вариантов, я думаю, каждый просто сделал бы для себя выбор, какой из них использовать — либо с отступами от начала строки, либо с отступами от первого символа.
Формат HV задумывался, как предоставляющий некоторый выбор — это касается как учета отступов в тексте, так и определения завершающих строк. Например, если кому-то нагляднее видеть "!!!THIS IS END!!!" в конце текстового поля — и он смог бы указать использовать именно эту комбинацию.
На мой взгляд, человеку будет неудобно каждый раз подсчитывать длину исходного текста и/или подгонять в рамки размера блока, особенно при частом редактировании.
То есть, любые манипуляции с величиной, затрагивающей длину текста, для обработки человеком, требуют дополнительных инструментов, помимо «блокнота».
В структуре (блоке данных) «level_2» указано только одно поле — «for_level_1», для которого переопределена завершающая строка. Теперь для поля «for_level_1» завершающая строка равна "&"
Парсер считывает поля и строки последовательно, поэтому он начинает искать строку "&", чтобы завершить чтение поля «for_level_1»
Все, что находится между «for_level_1+ &» и "&", считывается в качестве текста, поэтому символы "^", которые внутри этого могут встретиться, никак не влияют на парсер.
После этого он ищет либо новое поле в структуре «level_2», либо завершающую строку для «level_2», которая для равна "^".
В итоге все парсится без ошибок
CDATA — хорошее решение, но все же, если текст будет содержать в себе закрывающую комбинацию, то придется сделать, как в этом примере из википедии:
то есть, придется как-то менять (в данном случае — дробить) исходный текст.
А идея использования завершающих строк как раз в том, чтобы можно было подобрать такую завершающую строку, которая в тексте не встретится, например «abc end zzz ///». А если встретится, то назначить другую для этого поля.