3.2. Элементы, метки и атрибуты

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

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

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

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

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

Конечно, у нас нет цветной электронной ручки, так что нам нужен какой-то другой способ выделения того, к какому элементу принадлежит каждая часть содержимого. В языках, написанных на SGML (например, HTML и DocBook) это делается в терминах меток.

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

Для элемента с именем element-name начальная метка обычно будет выглядеть как <element-name>. Соответствующей закрывающей меткой для этого элемента будет </element-name>.

Пример 3-1. Использование элемента (начальная и конечная метки)

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

<p>Это параграф.  Он начинается с начальной
  метки для элемента 'p' и заканчивается конечной меткой для элемента
  'p'.</p>

<p>Это другой параграф.  Но он гораздо короче.</p>

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

Пример 3-2. Использование элемента (только начальная метка)

В HTML имеется элемент для горизонтальной линии, который называется hr. Этот элемент не окружает содержимое, так что имеет только начальную метку.

<p>Это параграф.</p>

<hr>

<p>Это другой параграф.  Горизонтальная линия отделяет его от предыдущего
  параграфа.</p>

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

Пример 3-3. Элементы внутри элементов; <em>

<p>Это простой <em>параграф</em>, в котором
  некоторые <em>слова</em> были <em>выделены</em>.</p>

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

Важно: Многие часто путают понятия меток и элементов, и используют эти термины, как если бы они были синонимами. Это не так.

Элемент является концептуальной частью вашего документа. Элемент имеет определенное начало и конец. Метки отмечают, где элемент начинается и где он кончается.

Когда документ (или кто-то, знающие о SGML) ссылается на ''метку <p>'', то имеется в виду текст, состоящий из трех символов <, p и >. Но фраза ''элемент <p>'' обозначает весь элемент.

Это тонкое отличие. Но имейте его в виду.

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

Атрибуты элемента пишутся внутри начальной метки этого элемента и принимают форму название-атрибута="значение атрибута".

В последних версиях HTML элемент <p> имеет атрибут, под названием align, который задает выравнивание (по отношению к границам) для параграфа программе вывода HTML.

Атрибут align может принимать одно из четырех предопределенных значений, left, center, right и justify. Если атрибут не указан, то по умолчанию используется left.

Пример 3-4. Использование элемента с атрибутом

<p align="left">Включение атрибута
  выравнивания для этого параграфа было излишним, так как по умолчанию
  используется выравнивание по левой границе.</p>

<p align="center">Это может появиться по центру.</p>

Некоторые атрибуты будут воспринимать только конкретные значения, такие, как left или justify. Другие позволят вам задать все, что угодно. Если вам нужно включить двойные кавычки (") в атрибут, то заключите значение атрибута в одинарные кавычки.

Пример 3-5. Атрибуты в одинарных кавычках

<p align='right'>Я справа!</p>

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

Информация об аттрибутах, элементах, и тэгах хранится в SGML каталогах. Различные инструменты Проекта используют эти каталоги для проверки Вашей работы. Утилиты из порта textproc/docproj включают множество различных SGML каталогов. Проект Документирования FreeBSD также имеет свой набор каталогов. И ваши утилиты должны знать об обоих видах SGML каталогов.

3.2.1. Упражнения...

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

  1. Сгрузите и установите textproc/docproj из системы портов FreeBSD. Это мета-порт, который должен сгрузить и установить все программы и сопутствующие файлы, которые используются в Проекте Документирования.

  2. Добавьте команды для установки значения переменной SGML_CATALOG_FILES в ваши файлы запуска командного процессора. (Если Вы не работаете над английской версией документации, то Вы вероятнее всего захотите указать правильный путь к каталогу для Вашего языка.)

    Пример 3-6. .profile для пользователей sh(1) и bash(1)

    SGML_ROOT=/usr/local/share/sgml    
    SGML_CATALOG_FILES=${SGML_ROOT}/jade/catalog
    SGML_CATALOG_FILES=${SGML_ROOT}/iso8879/catalog:$SGML_CATALOG_FILES
    SGML_CATALOG_FILES=${SGML_ROOT}/html/catalog:$SGML_CATALOG_FILES
    SGML_CATALOG_FILES=${SGML_ROOT}/docbook/4.1/catalog:$SGML_CATALOG_FILES
    SGML_CATALOG_FILES=/usr/doc/share/sgml/catalog:$SGML_CATALOG_FILES
    SGML_CATALOG_FILES=/usr/doc/en_US.ISO8859-1/share/sgml/catalog:$SGML_CATALOG_FILES
    export SGML_CATALOG_FILES
    

    Пример 3-7. .cshrc, для пользователей csh(1) и tcsh(1)

    setenv SGML_ROOT /usr/local/share/sgml
    setenv SGML_CATALOG_FILES ${SGML_ROOT}/jade/catalog
    setenv SGML_CATALOG_FILES ${SGML_ROOT}/iso8879/catalog:$SGML_CATALOG_FILES
    setenv SGML_CATALOG_FILES ${SGML_ROOT}/html/catalog:$SGML_CATALOG_FILES
    setenv SGML_CATALOG_FILES ${SGML_ROOT}/docbook/4.1/catalog:$SGML_CATALOG_FILES
    setenv SGML_CATALOG_FILES /usr/doc/share/sgml/catalog:$SGML_CATALOG_FILES
    setenv SGML_CATALOG_FILES /usr/doc/en_US.ISO8859-1/share/sgml/catalog:$SGML_CATALOG_FILES
    

    Затем либо выйдите из системы, а затем войдите снова, либо запустите эти команды из командной строки для установки значений переменных.

  1. Создайте example.sgml и введите следующий текст;

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    
    <html>
      <head>    
        <title>Пример файла HTML</title>
      </head>
    
      <body>    
        <p>Это параграф, содержащий некоторый текст.</p>
    
        <p>В этом параграфе содержится дополнительный текст.</p>
    
        <p align="right">Этот параграф может быть выровнен по правому краю.</p>
      </body>
    </html>
    
  2. Попробуйте выполнить проверку файла при помощи лексического анализатора SGML.

    Частью textproc/docproj является проверяющий лексический анализатор nsgmls. Обычно nsgmls считывает документ, размеченный в соответствии с SGML DTD и возвращает копию Набора Информации о Структуре Элементов документа (ESIS - Element Structure Information Set), но это на данный момент не важно.

    Однако когда nsgmls передается параметр -s, то обычный вывод nsgmls подавляется и печатаются только сообщения об ошибках. Это делает его полезным для проверки правильности вашего документа.

    Воспользуйтесь nsgmls для проверки правильности вашего документа;

    % nsgmls -s example.sgml
    

    Как вы увидите, nsgmls отработает без вывода какой-либо диагностики. Это значит, что ваш документ успешно проверен.

  3. Посмотрите, что случится, если пропущены требуемые элементы. Попробуйте удалить метки <title> и </title>, а затем выполнить проверку повторно.

    % nsgmls -s example.sgml
    nsgmls:example.sgml:5:4:E: character data is not allowed here
    nsgmls:example.sgml:6:8:E: end tag for "HEAD" which is not finished
    

    Вывод с сообщениями об ошибках в nsgmls организован в группы, разделенные двоеточиями, или столбцы.

    Столбец Значение
    1 Название программы, обнаружившей ошибку. Это всегда будет nsgmls.
    2 Имя файла, содержащего ошибку.
    3 Номер строки, в которой появилась ошибка.
    4 Номер колонки, в которой появилась ошибка.
    5 Однобуквенный код, обозначающий природу сообщения. I обозначает информационное сообщение, W для предупреждений и E для ошибок [a] и X для перекрестных ссылок. Как видите, это сообщения об ошибках.
    6 Текст диагностического сообщения.
    Примечания:
    a. Пятая колонка выводится не всегда. nsgmls -sv выдает nsgmls:I: SP version "1.3" (это зависит от установленной версии). Как вы можете видеть, это информационное сообщение.

    Просто опускание меток <title> приведет к генерации 2 разных ошибок.

    Первая ошибка указывает на то, что содержимое (в этом случае символы, а не начальная метка элемента) появилось в том мест, где лексический анализатор ожидал нечто другое. В этом случае анализатор ожидал увидеть начальную метку для одного из элементов, уместных внутри <head> (такую, как <title>).

    Вторая ошибка возникла, потому что элементы <head> должны содержать элемент <title>. Так как его нет, то nsgmls полагает, что элемент не был нормально завершен. Однако закрывающая метка указывает, что элемент был закрыт до того, как был завершен.

  4. Верните элемент title обратно.

Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.