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\">"
![]() Prints
n break tags. |
>(br)
<br>
|
![]() Prints two break tags.
|
>(br2)
<br><br>
|
![]() Prints
body in a center tag. |
>(center (pr "hello"))
<center>hello</center>
|
![]() Prints
body in an underline tag. |
>(underline (pr "hello ") (pr "world"))
<u>hello world</u>
hello world |
![]() Prints a bold (
b ) tag around arg . |
>(prbold "hello")
<b>hello</b>
hello |
![]() Prints a paragraph (
p ) tag followed by the args. |
>(para "hello " "world")
<p>hello world
hello world |
![]() Creates a white page containing the body.
|
>(whitepage (prn "hello"))
<html><body bgcolor=#ffffff alink=#0000be>hello
</body>
</html>
|
![]() Prints a white page containing the args.
|
>(errpage "hello " "world")
<html><body bgcolor=#ffffff alink=#0000be>hello world
</body></html>
|
![]() Prints a horizonal spacer using
span . |
>(new-hspace 3)
<span style="padding-left:3px" />
|
![]() Returns path to a blank spacer GIF (
s.gif ). |
>(blank-url)
"s.gif"
|
![]() Prints a horizontal spacer image of width
w . |
>(hspace 3)
<img src="s.gif" height=1 width=3>
|
![]() Prints a vertical spacer image of height
h . |
>(vspace 3)
<img src="s.gif" height=3 width=0>
|
![]() Prints a spacer image of height
h and width w . |
>(vhspace 3 5)
<img src="s.gif" height=3 width=5>
|
![]() Prints a non-breaking space.
|
>(nbsp)
|
![]() 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 |
![]() 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 |
![]() 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 |
![]() 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"
|
![]() Prints
body in a span tag. |
>(spanclass myclass (pr "hello ") (pr "world"))
<span class="myclass">hello world</span>
|
![]() Prints
text followed by two breaks, if it is not nil . |
>(pagemessage "hello")
hello
<br><br>
>(pagemessage nil) |
![]() Prints
body in a form tag. |
>(form "http://arcfn.com" (pr "hello"))
<form method=post action="http://arcfn.com">hello</form>
| ||||||
![]() Prints a
submit tag. |
>(submit "hello")
<input type=submit value="hello">
| ||||||
![]() Prints a
submit button tag. |
>(but "foo" "bar")
<input type=submit name="bar" value="foo">
| ||||||
![]() 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">
| ||||||
![]() Prints
body in a textarea tag. |
>(textarea "foo" 1 40 (pr "Contents"))
<textarea name="foo" rows=1 cols=40>Contents</textarea>
| ||||||
![]() 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>
| ||||||
![]() Prints an
input tag. |
>(input "foo" "bar" 10)
<input type=text name="foo" value="bar" size=10>
| ||||||
![]() 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>
| ||||||
![]() 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 |
![]() Defines that
tag can have attribute . f is on of the op... functions, defining the type of attribute . |
>(attribute a class opsym)
#<procedure: opsym>
|
![]() 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))
|
![]() 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))
|
![]() Creates a color object representing a gray level.
n is between 0 and 255. |
>(gray 100)
#hash((b . 100) (g . 100) (r . 100))
|
![]() Converts a color object to a hex triplet string.
|
>(hexrep orange)
"ff6600"
|
![]() Converts
str from hex to integer. Returns nil if the conversion fails. |
>(dehex "40")
64
>(dehex "0x12")
nil
|
![]() Prints the tag.
|
>(gentag img src "foo.gif")
<img src="foo.gif">
|
![]() Prints
body surrounded by the tag specified by spec . |
>(gentag a href "/index.html")
<a href="/index.html">
>(pr "click")
click
|
![]() 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
|
![]() Prints
str with <, >, ", and & HTML-escaped. |
>(pr-escaped "abc< > \" ' &")
abc< > " ' &
|
![]() Returns a string that is
str with <, >, ", ', and & HTML-escaped. |
>(eschtml "abc< > \" ' &")
"abc< > " ' &"
|
![]() 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<>
|
![]() Prints
body in a CDATA section. |
>(cdata (pr "hello"))
<![CDATA[hello]]>
|
![]() 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.
![]() 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)))
|
![]() Generates code to assign a string to an attribute, if the string is not
nil . |
>(opstring 'class "foo")
(aif "foo" (pr " class=\"" it #\"))
|
![]() Generates code to assign a number to an attribute, if
num is not nil . |
>(opnum 'width 42)
(aif 42 (pr " width=" it))
|
![]() Generates code to assign a value to an attribute.
|
>(opsym 'width 42)
(pr " width=" 42)
|
![]() 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 #\"))
|
![]() Generates code to set
attribute to selected if val is true. |
>(opsel 'foo 'bar)
(if bar (pr " selected"))
|
![]() Generates code to start a tag.
|
>(start-tag '(a href foo))
(do (pr "<a") (aif foo (pr " href=\"" it #\")) (pr ">"))
|
![]() Generates code to end a tag.
|
>(end-tag '(a href foo))
(pr "</a>")
|
![]() 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")
|
![]() Table indexed by list of tag and attribute.
|
>(opmeths* '(a href))
#<procedure: opstring>
|
![]() Looks up the HTML tag and attribute in
opmeths* |
>(opmeth 'a 'href)
#<procedure: opstring>
|
Copyright 2008 Ken Shirriff.