gentag
to generate a standalone tag such as <img>
, and tag
to generate an open/close tag pair surrounding something. In addition, Arc provides special-purpose functions for common HTML operations.
Arc has many operations to support forms, as well as many table operations, as tables are its primary layout technique.
For example, the following code generates a simple page with text, formatting, and a link.
(whitepage (prn "Hello world!") (para) (link "Click here") (prn "for") (prbold "more stuff"))
The basic model is gentag
generates a stand-alone tag, tag
generates a begin/end tag pair surrounding something, and a variety of operations can be used for many tags.
A tag in Arc can be defined with a tag spec, which is a tag followed by attributes and values. The syntax is slightly different for gentag
and tag
. gentag
takes the tag, attributes and values as arguments, while tag
takes the tag spec as a single argument followed by body code that outputs the tag content to stdout. For example:
arc> (tostring (gentag p style "mystyle")) "<p style=\"mystyle\">" arc> (tostring (tag (p style "mystyle") (pr "Content.") (pr "More content"))) "<p style=\"mystyle\">Content.More content</p>"
Most of the HTML generation in Arc is stdout-based, rather than return-value-based. A typical HTML operation in Arc outputs a tag to stdout and executes body code which outputs the tag contents to stdout. The return value is generally not useful. This programming model fits well with Arc's web server, which expects content to be written to stdout in many cases. Note that this programming model is different from the standard functional programming model, but it has the advantage that the outputs from multiple functions can be collected and concatenated. For example,
arc> (tostring (underline (prn "hello") (prn "world"))) "<u>hello\nworld\n</u>"(In the examples, the code is wrapped in
tostring
to explicitly capture stdout for clarity, but tostring
normally wouldn't be used when implementing web pages.)
However, some HTML operations don't collect output from the body code, but use explicit arguments. For example,
arc> (tostring (row 1 2)) "<tr><td>1</td><td>2</td></tr>"Other HTML operations accept either a list of atom arguments, or body code that outputs to stdout, but not a mixture. For example,
arc> (tostring (td (pr "hi"))) "<td>hi</td>" arc> (tostring (td "hi")) "<td>hi</td>"Arc's HTML generation is relatively inflexible. Tags can only use attributes that are explicitly registered in the attributes table. The only exception is the
style
attribute; all tags support that attribute. Other attributes are ignored with a comment in the created HTML code. The following table shows the attributes supported by Arc:
<a class=string href=string id=sym onclick=string rel=string> <body alink=color bgcolor=color leftmargin=number link=color marginheight=number marginwidth=number topmargin=number vlink=color> <font color=color face=string size=number> <form action=string method=sym> <hr color=color> <img align=sym border=number height=number hspace=number src=string vspace=number width=number> <input name=string size=number type=sym value=escaped> <option selected=selected> <rss version=string> <select name=string> <span align=string class=string id=sym> <table bgcolor=color border=number cellpadding=number cellspacing=number width=string> <td align=sym bgcolor=color class=string colspan=number valign=sym width=number> <textarea cols=number name=string rows=number wrap=sym> <tr bgcolor=color>New tags do not need to be explicitly defined, but any desired attributes that are not listed above need to be defined using
attribute
. For instance to support the "class" attribute for img
:
arc> (attribute img class opstring) arc> (tostring (gentag img class "foo")) "<img class=\"foo\">"
br [n]
Prints
n break tags. |
>(br)
<br>
|
br2
Prints two break tags.
|
>(br2)
<br><br>
|
center [body ...]
Prints
body in a center tag. |
>(center (pr "hello"))
<center>hello</center>
|
underline [body ...]
Prints
body in an underline tag. |
>(underline (pr "hello ") (pr "world"))
<u>hello world</u>
hello world |
prbold [arg ...]
Prints a bold (
b ) tag around arg . |
>(prbold "hello")
<b>hello</b>
hello |
para [arg ...]
Prints a paragraph (
p ) tag followed by the args. |
>(para "hello " "world")
<p>hello world
hello world |
whitepage [body ...]
Creates a white page containing the body.
|
>(whitepage (prn "hello"))
<html><body bgcolor=#ffffff alink=#0000be>hello
</body>
</html>
|
errpage [arg ...]
Prints a white page containing the args.
|
>(errpage "hello " "world")
<html><body bgcolor=#ffffff alink=#0000be>hello world
</body></html>
|
new-hspace n
Prints a horizonal spacer using
span . |
>(new-hspace 3)
<span style="padding-left:3px" />
|
blank-url
Returns path to a blank spacer GIF (
s.gif ). |
>(blank-url)
"s.gif"
|
hspace w
Prints a horizontal spacer image of width
w . |
>(hspace 3)
<img src="s.gif" height=1 width=3>
|
vspace h
Prints a vertical spacer image of height
h . |
>(vspace 3)
<img src="s.gif" height=3 width=0>
|
vhspace h w
Prints a spacer image of height
h and width w . |
>(vhspace 3 5)
<img src="s.gif" height=3 width=5>
|
nbsp
Prints a non-breaking space.
|
>(nbsp)
|
link text [href [color]]
Prints an HTML link.
|
>(link "click here" "http://arcfn.com" orange)
<a href="http://arcfn.com"><font color=#ff6600>click here
</font></a>
click here |
underlink text [dest]
Prints an HTML link with explicitly underlined text.
|
>(underlink "click here" "http://arcfn.com")
<a href="http://arcfn.com"><u>click here</u></a>
click here |
shortlink url
Prints a link to
url with http:// removed from the text. |
>(shortlink "http://arcfn.com")
<a href="http://arcfn.com">arcfn.com</a>
arcfn.com |
parafy str
Returns
str with paragraph tags. A p tag is inserted after each blank line. |
>(parafy "hello\n\nworld\npeople")
"hello\n\n<p>world\npeople"
|
spanclass classname [body ...]
Prints
body in a span tag. |
>(spanclass myclass (pr "hello ") (pr "world"))
<span class="myclass">hello world</span>
|
pagemessage text
Prints
text followed by two breaks, if it is not nil . |
>(pagemessage "hello")
hello
<br><br>
>(pagemessage nil) |
form action [body ...]
Prints
body in a form tag. |
>(form "http://arcfn.com" (pr "hello"))
<form method=post action="http://arcfn.com">hello</form>
| ||||||
submit [value]
Prints a
submit tag. |
>(submit "hello")
<input type=submit value="hello">
| ||||||
but [value [name]]
Prints a
submit button tag. |
>(but "foo" "bar")
<input type=submit name="bar" value="foo">
| ||||||
buts name [text ...]
Prints multiple
submit button tags, one for each text . |
>(buts "foo" "bar" "baz")
<input type=submit name="foo" value="bar">
<input type=submit name="foo" value="baz">
| ||||||
textarea name rows cols [body ...]
Prints
body in a textarea tag. |
>(textarea "foo" 1 40 (pr "Contents"))
<textarea name="foo" rows=1 cols=40>Contents</textarea>
| ||||||
menu name itemlist [sel]
Prints a menu with
select and option. Each element of itemlist becomes an option. If sel is an item in itemlist , that item is marked as selected. |
>(menu "foo" '(item1 item2 item3) 'item2)
<select name="foo"><option>item1</option>
<option selected>item2</option><option>item3</option>
</select>
| ||||||
input name [val [size ]]
Prints an
input tag. |
>(input "foo" "bar" 10)
<input type=text name="foo" value="bar" size=10>
| ||||||
inputs [name label size value ...]
Prints a table of labelled text rows. If
size is an atom, a text input of the specified size is generated. If size is a list (rows cols) , then a textarea of the specified size is generated. If the label is password a password input is generated. The label is followed by a colon. |
>(inputs i1 "Foo" 10 "contents"
p1 password 10 "pw"
i2 "Bar" '(2 5) "stuff")
<table border=0><tr><td>Foo:</td><td>
<input type=text name="i1" size=10 value="contents"></td>
</tr><tr><td>password:</td><td>
<input type=password name="p1" size=10 value="pw"></td></tr>
<tr><td>Bar:</td><td><textarea name="i2" rows=2 cols=5>stuff
</textarea></td></tr></table>
| ||||||
single-input label name size buttontext [password]
Prints a text or password input prefixed with
label followed by a submit button. |
>(single-input "Secret" 'i1 5 "Submit" 'password)
Secret<input type=password name="i1" size=5>
<input type=submit value="Submit">
Secret |
attribute tag attribute f
Defines that
tag can have attribute . f is on of the op... functions, defining the type of attribute . |
>(attribute a class opsym)
#<procedure: opsym>
|
color r g b
Creates a color object with the specified red, green, and blue components (0 to 255)
|
>(color 255 0 128)
#hash((b . 128) (g . 0) (r . 255))
|
hex>color str
Converts a string of length 6 representing a hex triplet into a color object. Returns
nil on failure. |
>(hex>color "ff00cc")
#hash((b . 204) (g . 0) (r . 255))
|
gray n
Creates a color object representing a gray level.
n is between 0 and 255. |
>(gray 100)
#hash((b . 100) (g . 100) (r . 100))
|
hexrep color
Converts a color object to a hex triplet string.
|
>(hexrep orange)
"ff6600"
|
dehex str
Converts
str from hex to integer. Returns nil if the conversion fails. |
>(dehex "40")
64
>(dehex "0x12")
nil
|
gentag tag [attribute value ...]
Prints the tag.
|
>(gentag img src "foo.gif")
<img src="foo.gif">
|
tag spec [body ...]
Prints
body surrounded by the tag specified by spec . |
>(gentag a href "/index.html")
<a href="/index.html">
>(pr "click")
click
|
tag-if test spec [body ...]
If
test is true, body is wrapped in the tag spec . Otherwise, body is printed without the tag. |
>(tag-if t (underline) (pr "hi"))
<underline>hi</underline>
>(tag-if nil (underline) (pr "hi"))
hi
|
pr-escaped str
Prints
str with <, >, ", and & HTML-escaped. |
>(pr-escaped "abc< > \" ' &")
abc< > " ' &
|
eschtml str
Returns a string that is
str with <, >, ", ', and & HTML-escaped. |
>(eschtml "abc< > \" ' &")
"abc< > " ' &"
|
esc<>& str
Returns a string that is
str with <, >, and & HTML-escaped. |
>(esc<>& "abc< > \" ' &")
Error: _esc
<>: undefined;
cannot reference an identifier before its de
finition
in module: top-level
internal name: _esc<>
|
cdata [body ...]
Prints
body in a CDATA section. |
>(cdata (pr "hello"))
<![CDATA[hello]]>
|
striptags str
Returns
str without tags. Anything between angle brackets is removed. |
>(striptags "abc<foo>def</foo>ghi")
"abcdefghi"
|
opmeths*
table, which maps from a tag and attribute to one of the op...
functions. These functions generate the code that generates the HTML to set an attribute.
One Arc design pattern used in the HTML code is to use multiple functions to generate the code, and then use these functions inside macros. This provides a simulation of first-class macros.
opcolor attribute color
Generates code to assign a color object to an attribute.
|
>(opcolor 'bgcolor orange)
(whenlet gs2254 #hash((b . 0) (g . 102) (r . 255)) (pr " bgcolor=#" (hexrep gs2254)))
|
opstring attribute string
Generates code to assign a string to an attribute, if the string is not
nil . |
>(opstring 'class "foo")
(aif "foo" (pr " class=\"" it #\"))
|
opnum attribute num
Generates code to assign a number to an attribute, if
num is not nil . |
>(opnum 'width 42)
(aif 42 (pr " width=" it))
|
opsym attribute val
Generates code to assign a value to an attribute.
|
>(opsym 'width 42)
(pr " width=" 42)
|
opesc attribute val
Generates code to assign a quoted value to an attribute. If
val is a string, it is escaped with pr-escaped . |
>(opesc 'foo 'val)
(awhen val (pr " foo=\"") (if (isa it (quote string)) (pr-escaped it) (pr it)) (pr #\"))
|
opsel attribute val
Generates code to set
attribute to selected if val is true. |
>(opsel 'foo 'bar)
(if bar (pr " selected"))
|
start-tag spec
Generates code to start a tag.
|
>(start-tag '(a href foo))
(do (pr "<a") (aif foo (pr " href=\"" it #\")) (pr ">"))
|
end-tag spec
Generates code to end a tag.
|
>(end-tag '(a href foo))
(pr "</a>")
|
tag-options tag options
Generates code to assign values to attributes.
options is a list of attribute/value pairs. The allowable attributes are defined by opmeth , and style is allowed for all tags. |
>(tag-options 'td '((bgcolor red) (width 42)))
((whenlet gs2255 red (pr " bgcolor=#" (hexrep gs2255))) " width=42")
|
opmeths*
Table indexed by list of tag and attribute.
|
>(opmeths* '(a href))
#<procedure: opstring>
|
opmeth tag attr
Looks up the HTML tag and attribute in
opmeths* |
>(opmeth 'a 'href)
#<procedure: opstring>
|
Copyright 2008 Ken Shirriff.