Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Pol_Grem_-_ANSI_Common_Lisp_High_tech_-_2012.pdf
Скачиваний:
28
Добавлен:
12.03.2016
Размер:
4.85 Mб
Скачать

16

Пример: генерация HTML

В этой главе­ мы напи­шем­ неболь­шой­ HTML-гене­ра­тор ­– програм­му,­ ав­ тома­ти­че­ски­ произ­во­дя­щую­ набор­ связан­ных­ веб-страниц­. Она не толь­ ко демон­ст­ри­ру­ет­ различ­ные­ концеп­ции­ Лиспа,­ но и явля­ет­ся­ хоро­шим­ приме­ром­ разра­бот­ки­ «снизу­-вверх». Мы начнем­ с созда­ния­ HTML-ути­ лит обще­го­ назна­че­ния,­ кото­рые­ затем­ будем­ рассмат­ри­вать­ как язык, на кото­ром­ и будем­ писать­ собст­вен­­но гене­ра­тор­.

16.1. HTML

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

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

На рис. 16.1 приве­ден­ при­мер просто­го­ HTML-файла,­ а на рис. 16.2 по­ каза­но,­ как он будет­ отобра­жать­ся­ в браузе­ре­. Обра­ти­те­ внима­ние,­ что текст между­ угло­вы­ми­ скобка­ми­ не отобра­жа­ет­ся­. Это и есть размет­ка­. HTML имеет­ два вида­ меток­. Одни­ исполь­зу­ют­ся­ попар­но:­

<метка>­ ... </метка>­

Первая­ метка­ обозна­ча­ет­ нача­ло­ неко­то­ро­го­ окру­же­ния,­ вторая­ поме­ча­­ ет его оконча­ние­. Одной­ из меток­ тако­го­ рода­ явля­ет­ся­ <h2>. Весь текст, нахо­дя­щий­ся­ между­ <h2> и </h2>, отобра­жа­ет­ся­ увели­чен­ным­ шрифтом­. (Наиболь­ший­ шрифт зада­ет­ся­ <h1>.)

264

Глава 16. Пример: генерация HTML

<center>

<h2>Your Fortune</h2> </center>

<br><br>

Welcome to the home page of the Fortune Cookie Institute. FCI is a non-profit institution dedicated to the development of more realistic fortunes. Here are some examples of fortunes that fall within our guidelines:

<ol>

<li>Your nostril hairs will grow longer. <li>You will never learn how to dress properly. <li>Your car will be stolen.

<li>You will gain weight. </ol>

Click <a href="research.html">here</a> to learn more about our ongoing research projects.

Рис. 16.1. HTML-файл

Your Fortune

Welcome to the home page of the Fortune Cookie Institute. FCI is a nonprofit institution dedicated to the development of more realistic fortunes. Here are some examples of fortunes that fall within our guidelines:

1.Your nostril hairs will grow longer.

2.You will never learn how to dress properly.

3.Your car will be stolen.

4.You will gain weight.

Click here to learn more about our ongoing research projects.

Рис. 16.2. Внешний­ вид веб-страни­цы­

Другие­ парные­ метки:­ <ol> («ordered list», упоря­до­чен­­ный список)­ для созда­ния­ нуме­ро­ван­но­го­ списка;­ <center> для центри­ро­ва­ния­ текста;­ <a...> («anchor», якорь) для созда­ния­ ссылки­.

Имен­но ссылки­ превра­ща­ют­ текст в гипер­текст­. Текст, нахо­дя­щий­ся­ между­ <a...> и </a>, отобра­жа­ет­ся­ браузе­ра­ми­ особым­ обра­зом,­ как пра­ вило,­ с подчер­ки­ва­ни­ем­. При нажа­тии­ на ссылку­ осуще­ст­в­ля­ет­ся­ пере­­ ход на другую­ страни­цу,­ адрес­ кото­рой­ содер­жит­ся­ внутри­ метки­. Сле­ дующая­ метка­

16.2. Утилиты HTML

265

<a href="foo.html">

озна­ча­ет­ ссылку­ на другой­ HTML-файл, нахо­дя­щий­ся­ в том же ката­ло­­ ге. Таким­ обра­зом,­ при нажа­тии­ на ссылку­ на рис. 16.2 браузер­ загру­­ зит и отобра­зит­ файл "research.html".

Ссылки­ не обяза­ны­ указы­­вать на файлы­ в одном­ и том же ката­ло­ге,­ но могут­ указы­­вать и на любой­ адрес­ в Интер­не­те­ (хотя­ в нашем­ при­мере­ это не исполь­зу­ет­ся)­ .

Другая­ разно­вид­ность­ меток­ не имеет­ марке­ра­ оконча­ния­. В нашем­ приме­ре­ (см. рис. 16.1) исполь­зу­ют­ся­ метки­ <br> («break», разрыв)­ для пере­хо­да­ на новую­ строку­ и <li> («list item», элемент­ списка)­ для обозна­­ чения­ элемен­та­ внутри­ окру­же­ния­ списка­. Разу­ме­ет­ся,­ HTML содер­­ жит и другие­ метки,­ но в этой главе­ нам пона­до­бят­ся­ лишь те, кото­рые­ упомя­ну­ты­ на рис. 16.1.

16.2.Утилиты HTML

Вэтом разде­ле­ мы опре­де­лим­ неко­то­рые­ утили­ты­ для гене­ра­ции­ HTML. На рис. 16.3 пока­за­ны­ базо­вые­ утили­ты­ для гене­ра­ции­ размет­ки­. Все они направ­ля­ют­ вывод­ в *standard-output*, но мы всегда­ сможем­ пере­на­­ править­ его, пере­на­зна­чив­ эту пере­мен­ную­.

(defmacro as (tag content) ‘(format t "<~(~A~)>~A</~(~A~)>"

’,tag ,content ’,tag))

(defmacro with (tag &rest body) ‘(progn

(format t "~&<~(~A~)>~%" ’,tag) ,@body

(format t "~&<~(~A~)>~%" ’,tag)))

(defun brs (&optional (n 1)) (fresh-line)

(dotimes (i n) (princ "<br>"))

(terpri))

Рис. 16.3. Утили­ты­ для гене­ра­ции­ размет­ки­

Макро­сы­ as и with предна­зна­че­ны­ для гене­ра­ции­ выра­же­ний,­ окру­жен­­ ных парой­ меток­. Первый­ прини­ма­ет­ строку­ и печа­та­ет­ ее между­ мет­ ками:­

> (as center "The Missing Lambda") <center>The Missing Lambda</center> NIL

266 Глава 16. Пример: генерация HTML

Второй­ прини­ма­ет­ тело­ кода­ и выво­дит­ резуль­тат­ его вы­полне­ния­ меж­ ду метка­ми:­

> (with center

(princ "The Unbalanced Parenthesis")) <center>

The Unbalanced Parenthesis </center>

NIL

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

В то время­ как макрос­ as пыта­ет­ся­ размес­тить­ весь вывод­ на одной­ стро­ ке, макрос­ with распо­ла­га­ет­ метки­ на отдель­ных­ строках­. (Дирек­ти­ва­ ~& обеспе­чи­ва­ет­ нача­ло­ выво­да­ с новой­ строки­.) Это дела­ет­ся­ лишь для то­ го, чтобы­ HTML-файлы­ лучше­ чита­лись­. При отобра­же­нии­ страниц­ пробель­ные­ симво­лы­ вокруг­ меток­ не пока­зы­­вают­ся­.

Послед­няя­ утили­та­ на рис. 16.3, brs, гене­ри­ру­ет­ множе­ст­вен­­ные разры­­ вы строк. Во многих­ браузе­рах­ они могут­ исполь­зо­вать­ся­ для управле­­ ния верти­каль­ны­ми­ отсту­па­ми­.

Рисунок 16.4 содер­жит­ утили­ты­ для непо­сред­ст­вен­ной­ гене­ра­ции­ HTML. Первая­ возвра­ща­ет­ имя файла­ по задан­но­му­ симво­лу­. В реаль­ном­ при­ ложе­нии­ она могла­ бы вернуть­ полный­ путь к файлу­ в указан­ном­ ката­­ логе­. Здесь же она просто­ присо­еди­ня­ет­ к имени­ расши­ре­ние­ ".html".

Макрос­ page служит­ для гене­ра­ции­ всей страни­цы­. Он схож с with-open- file, на осно­ве­ кото­ро­го­ постро­ен­. Выра­же­ния­ в его теле­ будут­ выпол­не­­ ны с привяз­кой­ *standard-output* к пото­ку,­ создан­но­му­ при откры­тии­ файла,­ соот­вет­ст­вую­ще­го­ симво­лу­ name.

(defun html-file (base)

(format nil "~(~A~).html" base))

(defmacro page (name title &rest body) (let ((ti (gensym)))

‘(with-open-file (*standard-output* (html-file ,name) :direction :output :if-exists :supersede)

(let ((,ti ,title)) (as title ,ti) (with center

(as h2 (string-upcase ,ti))) (brs 3)

,@body))))

Рис. 16.4. Утили­ты­ созда­ния­ файлов­

16.2. Утилиты HTML

267

В разделе 6.7 было­ пока­за­но,­ как присваи­вать­ времен­ные­ значе­ния­ спе­ циаль­ным­ пере­мен­ным­. В приме­ре­ на стр. 124 мы уста­нав­ли­ва­ли­ значе­­ ние *print-base* в 16 в теле­ let. Раскры­тие­ page похо­жим­ обра­зом­ связы­­ вает­ *standard-output* с пото­ком,­ указы­­вающим­ на HTML-файл. Если­ мы вызо­вем­ as или princ в теле­ page, то вывод­ будет­ пере­на­прав­лен­ в со­ ответ­ст­вую­щий­ файл.

Заго­ло­вок­ title будет­ напе­ча­тан­ в самом­ верху­ страни­цы­. За ним следу­­ ет весь осталь­ной­ вы­вод. Таким­ обра­зом,­ вызов:­

(page ’paren "The Unbalanced Parenthesis"

(princ "Something in his expression told her..."))

приве­дет­ к тому,­ что файл "paren.html" будет­ иметь (посколь­ку­ html-file уже опре­де­лен)­ следую­щее­ содер­жа­ние:­

<title>The Unbalanced Parenthesis</title> <center>

<h2>THE UNBALANCED PARENTHESIS</h2> </center>

<br><br><br>

Something in his expression told her...

Здесь нам знако­мы­ все мет­ки, кроме­ <title>. Текст, заклю­чен­­ный в мет­ ку <title>, не будет­ появ­лять­ся­ нигде­ на страни­це,­ но зато­ он будет­ ото­ бражать­ся­ браузе­ром­ в заго­лов­ке­ окна­.

(defmacro with-link (dest &rest body) ‘(progn

(format t "<a href=\"~A\">" (html-file ,dest)) ,@body

(princ "</a>")))

(defun link-item (dest text) (princ "<li>")

(with-link dest (princ text)))

(defun button (dest text) (princ "[ ") (with-link dest

(princ text)) (format t " ]~%"))

Рис. 16.5. Утили­ты­ для гене­ра­ции­ ссылок­

На рис. 16.5 представ­ле­ны­ утили­ты­ для гене­ра­ции­ ссылок­. Макрос­ with-link похож­ на with. Он прини­ма­ет­ тело­ кода­ и вычис­ля­ет­ его между­ выра­же­ния­ми,­ кото­рые­ гене­ри­ру­ют­ ссылку­ на HTML-файл, имя кото­­ рого­ было­ пере­да­но­ вторым­ аргу­мен­том:­

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]