Script-based Website Maintenance



Mark-up

These macros conveniently produce often-used fragments of HTML. Some you would put in include/html-common.m4 in your global directory, and others in etc/site.html-common.m4 in your site directory. HTML- or XHTML-specific definitions should go in the files for those specific types: include/html.m4, include/xhtml.m4, etc/site.html.m4 and etc/site.xhtml.m4.

There are also macros to handle links.

Syntactic context

You can use this macro to indicate that the second argument is content to be expanded in the context identified by the first:

define(`INCTXT',`pushdef(`CONTEXT',`$1')`'$2`'popdef(`CONTEXT')')dnl

Macros within the content can test the value of CONTEXT to decide how to expand.

We will use CONTEXT in HTML to hold the values LINK to indicate content within a link (so further links are not possible) and PCDATA for content where mark-up is forbidden.

Basic HTML elements

We can define macros to generate HTML elements, so we don't have to handle subtle differences between HTML and XHTML, and we may even be able to crudely handle plain text. Here's a macro to generate elements with content:

define(`HTML_element', ``<'$1`'HTML_coreattrs(select(2,4,
$@))`'HTML_i18nattrs(select(6,2, $@))`'HTML_attr(``align'',
`$9')`'HTML_eventattrs(select(10,10,
$@))`'HTML_extras(`$10')`>'INLANG_COND(`$7', `$2')`</'$1`>'')dnl

Here are the supporting macros that define attributes:

define(`HTML_extras', `ifelse($1,,, `` '$1')')dnl



define(`HTML_coreattrs', `HTML_attr(``class'',
`$1')`'HTML_attr(``title'', `$2')`'HTML_attr(``style'',
`$3')`'HTML_attr(``id'', `$4')')dnl

define(`HTML_i18nattrs', `HTML_attr(``lang'',
`$1')`'HTML_attr(``dir'', `$2')')dnl

define(`HTML_eventattrs', `HTML_attr(``onclick'',
`$1')`'HTML_attr(``ondblclick'', `$2')`'HTML_attr(``onmousedown'',
`$3')`'HTML_attr(``onmouseup'', `$4')`'HTML_attr(``onmouseover'',
`$5')`'HTML_attr(``onmousemove'', `$6')`'HTML_attr(``onmouseout'',
`$7')`'HTML_attr(``onkeypress'', `$8')`'HTML_attr(``onkeydown'',
`$9')`'HTML_attr(``onkeyup'', `$10')')dnl

.

Basic attributes

.

define(`HTML_requiredattr', `` '$1`="'INCTXT(``PCDATA'', `$2')`"'')dnl

define(`HTML_attr', `ifelse($2,,, `HTML_requiredattr(`$1', `$2')')')dnl

Note:

Should I add the ability to automatically escape quotes, ampersands and ‘angle brackets’ inside attribute values?

:Note ends


Flag attributes

Here's all we need for HTML:

define(`HTML_flag', `` '$1')dnl

For XHTML, we need the attribute name repeated as the value:

define(`HTML_flag', `` '$1`="'$1`"'')dnl

The XHTML version is also suitable for the HTML version.

.

define(`HTML_flagif', `ifelse($2,,,`HTML_flag(`$1')')')dnl

Empty elements in HTML and XHTML

Empty XHTML elements must terminate with a /, while in HTML they do not [Note: should not?]. In include/xhtml.m4, you could define:

define(`ELEMEND',`` /'')dnl

…while in include/html.m4, you could define:

define(`ELEMEND',``'')dnl

…and use it at the end of empty elements:

<br'ELEMEND`>

That will then expand correctly whether it appears in HTML or XHTML.


Note:

This is probably not too important. Many HTML-reading programs will accept the superfluous / without any problem.

:Note ends


Class, language and text direction

The span HTML element allows you to set the class, language and text direction [Note: More, probably!] of in-line content. This macro builds such an element with argument 1 as its content, 2 as the class, 3 as the language, and 4 as the direction:

define(`SPAN', `ifelse(CONTEXT,`PCDATA',`$1',
`ifelse($2`'$3`'$4,,`$1',
``<span'ifelse($2,,,
`` class="'$2`"'')`'ifelse($3,,,
`` lang="'$3`"'')`'ifelse($4,,,
`` dir="'$4`"'')`>'ifelse($3,,`$1',
`INLANG(`$3',`$1')')`</span>'')')')

Quotation marks

You could override the macro Qx so that the quote marks could optionally be placed in SPAN blocks so you can apply particular styles to them:

define(`Qx',`SPAN(`$2',`$4')`'$1`'SPAN(`$3',`$4')')

Editorial notes

Sometimes you may wish to leave editorial notes to yourself in a page, for you to fix later. This macro can be used for in-line comments:

define(`E', `SPAN(``['LANG(``en'',
``Note'', ``Noto'')`: '$1`]'', ``EDIT'')')dnl

This macro is for block comments:

define(`EDIT',
``<div class=EDIT><hr class=NOSTYLE>
<p class=START align=LEFT><strong>'LANG(``en'',
``Note'', ``Notu'')`:</strong></p>

'$1`

<p class=END align=RIGHT><strong>:'LANG(``en'',
``Note ends'', ``Noto finas'')`</strong></p>
<hr class=NOSTYLE></div>'')

Headings

The first argument of this macro is the heading level (1-6), the second is the heading text, the third is an optional anchor name, the fourth the class, the fifth the language, and the sixth the text direction:

define(`Hn',
``<h'$1`'ifelse($3,,,
`` id="'$3`"'')`'ifelse($4,,,
`` class="'$4`"'')`'ifelse($5,,,
`` lang="'$5`"'')`'ifelse($6,,,
`` dir="'$6`"'')`>'`'ifelse($5,,`$2',
`INLANG(`$5',`$2')')`'`</h'$1`>'')

Because your website may use some same headings on all pages, you might prefer that the unique content of each page starts at a lower level:

define(`H1',`Hn(``3'',$@)')dnl
define(`H2',`Hn(``4'',$@)')dnl
define(`H3',`Hn(``5'',$@)')dnl
define(`H4',`Hn(``6'',$@)')dnl

Computer text

Here are some macros for enclosing computer text (programs, scripts, spools, etc):

define(`SAMP',`ifelse(CONTEXT,`PCDATA',`Q(`$1')',
``<samp'ifelse($2,,,`` class="'$2`"'')`>'$1`</samp>'')')
define(`CODE',`ifelse(CONTEXT,`PCDATA',`Q(`$1')',
``<code'ifelse($2,,,`` class="'$2`"'')`>'$1`</code>'')')
define(`PRE',``<pre'ifelse($2,,,`` class="'$2`"'')`
width="'ifelse($3,,``80'',`$3')`">'$1`</pre>'')

Now you can roll your own…

define(`C',`CODE(`$1',``C'',shift($@))')
define(`JAVA',`CODE(`$1',``JAVA'',shift($@))')
define(`CBLOCK',`PRE(`$1',``C'',shift($@))')
define(`JAVABLOCK',`PRE(`$1',``JAVA'',shift($@))')

You will need to modify raw text so that characters special to HTML and m4 are escaped. Here is a sed script to escape HTML/XML:

# escape-xml.sed
s/\&/\&amp;/g
s/</\&lt;/g
s/>/\&gt;/g

Here is a sed script to record tabs in preformatted text:

# escape-prehtml.sed
s/	/\&#9;/g

Here is a awk script to escape m4:

# escape-m4.awk
{
  j = length();
  for ( i = 0; i < j; i++) {
    c=substr($0,i+1,1);
    if (c == "'") {
      printf "'APOS`", c
    } else if (c == "`") {
      printf "'GRAV`", c
    } else if (c == "$") {
      printf "'DOLL`", c
    } else {
      printf "%s", c
    }
  }
  printf "\n"
}

Now a shell script to apply them all together:

#!/bin/sh -f

exec sed -f escape-xml.sed \
        -f escape-prehtml.sed | \
        awk -f escape-m4.awk

Basic HTML structure

Much of all HTML pages is the same, so you could define a macro to generate this common structure:

define(`PAGE',

``<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
                    "http://www.w3.org/TR/REC-html40/loose.dtd">

<html'ifdef(`LANGUAGE',`ifelse(LANGUAGE,,,`` lang="'LANGUAGE`"'')')`>

<head>

'ifdef(`CHARSET',``<meta name="HTTP-EQUIV"
   content="Content-type: text/html; charset='CHARSET`">'')`

<title>'INCTXT(``PCDATA'',`$1')`</title>

'ifelse($2,,,``<meta name="DESCRIPTION"
         content="'INCTXT(``PCDATA'',`$2')`">'')`

'$4`

</head>

<body'ifelse($5,,,`` '$5')`>

'$3`

</body>

</html>'')

(Put that definition in include/html.m4, then you can define it differently for XHTML in include/xhtml.m4.)

Use it like this:

PAGE(``My Website'', ``A website about me'',

``<p>'Q(``Danger'')` could be my middle name, but it'APOS`s John.</p>'')`

The fourth argument provides extra header mark-up, and the fifth forms BODY attributes.

Site-specific HTML structure

Tune PAGE for the particular layout of your website:

define(`SITEPAGE',`PAGE(`$1',`$3',

``<div id=HDR>

'Hn(``1'', `SITENAME')`

'NAVBAR`

</div>

<br clear=ALL class=NOSTYLE'ELEMEND`>

<hr class=NOSTYLE'ELEMEND`>

<div id=BDY>

'Hn(``2'', `$2')`

'$4`

</div>

<br clear=ALL class=NOSTYLE'ELEMEND`>

<hr class=NOSTYLE'ELEMEND`>

<div id=FTR>

<p>'LANG(``eo'', ``Aktualigita'', ``Updated'')`: 'FILEUPDATED`</p>

</div>'',


`LREL_HTML(``START'', ``index'',, `SITENAME')')')dnl

…or even for different types of pages within it:

define(`COVERPAGE',`SITEPAGE(`SITEABBR',$@)')dnl
define(`DESCPAGE',`SITEPAGE(`SITEABBR`: '$1',$@)')dnl


Updated: 2007-May-11 16:56 GMT
Contact Steven Simpson

Ĉi tiu paĝo disponeblas ĉi-lingve, laŭ via krozila agordo.