The markup Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The markup Reference Manual

This is the markup Reference Manual, version 0.0.1, generated automatically by Declt version 3.0 "Montgomery Scott" on Mon Dec 02 10:52:03 2019 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

markup

Arnold Noronha arnold@tdrhq.com

Markup let's you write HTML code inside of common lisp, for instance

(let ((x "hello"))
  <h1>,(progn x) <em>world</em>!</h1>)

Motivation

There are several HTML generation libraries for Common Lisp, for example CL-WHO. However, these libraries follow the Lisp style of building up the structure in parenthesis.

For example, it might look like something like this:

;; CL-WHO syntax, not markup's
(:p "hello" (:em "world") "!")

There are many advantages to this structure, but there are a few prominent disadvantages.

First, there's all that double-quotes that becomes hard to track.

Second, and more importantly: There are hundreds of templates and HTML snippeds on the internet that are hard to copy-paste into your project if you have to transform them into CL-WHO structures. Time is money.

Finally, it's already hard to hire Lisp engineers. Don't you want to be able to hire designers who might at least modify HTML they recognize inside your lisp project?

Performance

Performance is not a motivation for Markup. We're focussing on developer productivity. For instance, compared to CL-WHO we generate the entire tree of HTML tags before serializing it into the stream at the last step. We haven't reached a situation where this is a bottleneck for our use cases.

Building the tree also lets us build more complex components that can go modify the tree.

It might be possible to build a streaming version of Markup, but that's not on our radar.

Full example with Hunchentoot

(markup:enable-reader)

(markup:deftag template (children &key title)
  <html>
    <head>
     <title>,(progn title)</title>
    </head>
    <body>
      ,@(progn children)
    </body>
  </html>)

(hunchentoot:define-easy-handler (foobar :uri "/") ()
  (markup:write-xml
     <template title="Hello" >
        <h1>hello world!</h1>
     </template>))

Installation

markup is available via quicklisp

(ql:quickload "markup")

(If that doesn't load, make sure you update your dists, (ql:update-all-dists))

Editor support

We do not have editor support, even for Emacs, so indentation is going to be done manually by the developer.

FAQ

What about expressions like (< x 2)?

Markdown requires tags to follow the < operator, otherwise (or if it's <=) treats it as a symbol.

To simplify editor support in the future, we recommend a style guide of using (|<| x 2) in markup enabled code.

Are custom tags namespaced?

Of course, custom tags are just lisp symbols. So you can define a tag like <admin:template>...</admin:template>.

Certain tag names are treated as special (<b>, <body> etc.) since they're HTML elements.

If you want to output the equivalent HTML element for a tag that isn't treated as special you can also specify the tag using keyword symbols <:foo>..</:foo>.

How do you embed lisp code in markup?

You have already seen some examples in this README. Use ,(...) to escape some lisp code that returns a single element, or ,@sexp that returns a list of elements. (Side note, we really don't need to have both of these, but it matches the backquote syntax much better this way).

You can also embed lisp code as attribute values.

  <a href=(generate-url ...) >...</a>

That is, any expression after the an attribute is read using the standard Lisp reader. A small caveat to this is that in some cases you need to have a space after the ending >. For instance the following will result in an error:

   ;; bad code
   <a href=url-var>...</a>
   ;; correct code
   <a href=url-var >...</a>

Is markup used in production?

Yes it is! Right now it's used on several websites we've built. Granted, they're not high-traffic (for now), but they've solved all of our use cases reliably.

See also

XHP for PHP, and JSX for React both support HTML inside of code for very similar motivations.

@fukamachi released LSX in the same Quicklisp release that markup came out (although his repo goes back much longer, around the time I first started working on Markup internally.). Functionally, it's super similar to Markup and Fukamachi is a pretty fantastic Lisper, and maybe in the future we should consolidate.

License

Apache License, Version 2.0


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 markup

Author

Arnold Noronha <arnold@tdrhq.com>

License

Apache License, Version 2.0

Description

markup provides a reader-macro to read HTML/XML tags inside of Common Lisp code

Version

0.0.1

Dependencies
Source

markup.asd (file)

Components

Next: , Previous: , Up: Top   [Contents][Index]

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

3.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.1 markup.asd

Location

markup.asd

Systems

markup (system)


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.2 markup/package.lisp

Parent

markup (system)

Location

package.lisp

Packages

markup


Previous: , Up: Lisp files   [Contents][Index]

3.1.3 markup/markup.lisp

Dependency

package.lisp (file)

Parent

markup (system)

Location

markup.lisp

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

4 Packages

Packages are listed by definition order.


Previous: , Up: Packages   [Contents][Index]

4.1 markup

Source

package.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

5.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.1 Macros

Macro: deftag NAME (&rest ARGS) &body BODY

Define a new XML tag that.

Tags are namespaced so you if you define a tag foo in namespace bar
you can refer to it as <bar:foo>...</bar:foo>.

The lambda-list has a very specific syntax: it must be: ([children [&key attr*]).

If children is provided, it will be filled with the list of all
child tags while parsing. For instance <bar:foo>x<h1>y</h1></bar:foo>, will set children as ("x" <h1>y</h1>).

Package

markup

Source

markup.lisp (file)

Macro: enable-reader ()
Package

markup

Source

markup.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.2 Functions

Function: make-merge-tag CHILDREN
Package

markup

Source

markup.lisp (file)

Function: make-xml-tag NAME &key CHILDREN ATTRIBUTES
Package

markup

Source

markup.lisp (file)

Function: read-xml STREAM CHAR
Package

markup

Source

markup.lisp (file)

Function: read-xml-from-string STRING
Package

markup

Source

markup.lisp (file)

Function: unescaped STRING
Package

markup

Source

markup.lisp (file)

Function: write-html TREE
Package

markup

Source

markup.lisp (file)

Function: write-xml TREE
Package

markup

Source

markup.lisp (file)

Function: write-xml-to-stream TREE STREAM
Package

markup

Source

markup.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

5.1.3 Generic functions

Generic Function: write-html-to-stream TREE STREAM
Package

markup

Source

markup.lisp (file)

Methods
Method: write-html-to-stream (TREE escaped-string) STREAM
Method: write-html-to-stream (TREE unescaped-string) STREAM
Method: write-html-to-stream (TREE (eql nil)) STREAM
Method: write-html-to-stream (TREE xml-merge-tag) STREAM
Method: write-html-to-stream (TREE string) STREAM
Method: write-html-to-stream (TREE xml-tag) STREAM
Method: write-html-to-stream (TREE integer) STREAM

Previous: , Up: Definitions   [Contents][Index]

5.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.1 Special variables

Special Variable: *escape-map*
Package

markup

Source

markup.lisp (file)

Special Variable: *escape-minimal-map*
Package

markup

Source

markup.lisp (file)

Special Variable: *standard-name-cache*
Package

markup

Source

markup.lisp (file)

Special Variable: *standard-names*
Package

markup

Source

markup.lisp (file)

Special Variable: *void-tag-cache*
Package

markup

Source

markup.lisp (file)

Special Variable: *void-tags*
Package

markup

Source

markup.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.2 Macros

Macro: %deftag NAME (CHILDREN &optional KEY-ATTR &rest ARGS) &body BODY
Package

markup

Source

markup.lisp (file)

Macro: make-escape-map &rest ALIST
Package

markup

Source

markup.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.3 Functions

Function: copy-xml-merge-tag INSTANCE
Package

markup

Source

markup.lisp (file)

Function: copy-xml-tag INSTANCE
Package

markup

Source

markup.lisp (file)

Function: deftag-symbol ARG
Package

markup

Source

markup.lisp (file)

Function: deftag-value ARG
Package

markup

Source

markup.lisp (file)

Function: format-attr-val STREAM VAL
Package

markup

Source

markup.lisp (file)

Function: make-escaped CHILD
Package

markup

Source

markup.lisp (file)

Function: make-xml-merge-tag &key (CHILDREN CHILDREN)
Package

markup

Source

markup.lisp (file)

Function: make-xml-tag-impl &key (ATTRIBUTES ATTRIBUTES) (CHILDREN CHILDREN) (NAME NAME)
Package

markup

Source

markup.lisp (file)

Function: print-escaped-text VALUE STREAM &optional ESCAPE-MAP
Package

markup

Source

markup.lisp (file)

Function: print-escaped-text-minimal VALUE STREAM
Package

markup

Source

markup.lisp (file)

Function: read-attr-key STREAM
Package

markup

Source

markup.lisp (file)

Function: read-attr-val STREAM
Package

markup

Source

markup.lisp (file)

Function: read-attributes STREAM
Package

markup

Source

markup.lisp (file)

Function: read-comment STREAM
Package

markup

Source

markup.lisp (file)

Function: read-string-from-xml STREAM NEXT
Package

markup

Source

markup.lisp (file)

Function: read-tag STREAM
Package

markup

Source

markup.lisp (file)

Function: read-tag-from-string NAME
Package

markup

Source

markup.lisp (file)

Function: read-whitespace STREAM
Package

markup

Source

markup.lisp (file)

Function: read-xml-after-bracket STREAM CHAR
Package

markup

Source

markup.lisp (file)

Function: standard-name? TAG
Package

markup

Source

markup.lisp (file)

Function: void-tag? TAG
Package

markup

Source

markup.lisp (file)

Function: whitespacep CHAR
Package

markup

Source

markup.lisp (file)

Function: write-attributes ATTRIBUTES STREAM
Package

markup

Source

markup.lisp (file)

Function: xml-merge-tag-children INSTANCE
Function: (setf xml-merge-tag-children) VALUE INSTANCE
Package

markup

Source

markup.lisp (file)

Function: xml-merge-tag-p OBJECT
Package

markup

Source

markup.lisp (file)

Function: xml-tag-attributes INSTANCE
Function: (setf xml-tag-attributes) VALUE INSTANCE
Package

markup

Source

markup.lisp (file)

Function: xml-tag-children INSTANCE
Function: (setf xml-tag-children) VALUE INSTANCE
Package

markup

Source

markup.lisp (file)

Function: xml-tag-name INSTANCE
Function: (setf xml-tag-name) VALUE INSTANCE
Package

markup

Source

markup.lisp (file)

Function: xml-tag-p OBJECT
Package

markup

Source

markup.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.4 Generic functions

Generic Function: escaped-string-content OBJECT
Generic Function: (setf escaped-string-content) NEW-VALUE OBJECT
Package

markup

Methods
Method: escaped-string-content (ESCAPED-STRING escaped-string)

automatically generated reader method

Source

markup.lisp (file)

Method: (setf escaped-string-content) NEW-VALUE (ESCAPED-STRING escaped-string)

automatically generated writer method

Source

markup.lisp (file)

Generic Function: unescaped-string-content OBJECT
Generic Function: (setf unescaped-string-content) NEW-VALUE OBJECT
Package

markup

Methods
Method: unescaped-string-content (UNESCAPED-STRING unescaped-string)

automatically generated reader method

Source

markup.lisp (file)

Method: (setf unescaped-string-content) NEW-VALUE (UNESCAPED-STRING unescaped-string)

automatically generated writer method

Source

markup.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

5.2.5 Structures

Structure: xml-merge-tag ()
Package

markup

Source

markup.lisp (file)

Direct superclasses

structure-object (structure)

Direct methods
Direct slots
Slot: children
Type

(or null cons)

Readers

xml-merge-tag-children (function)

Writers

(setf xml-merge-tag-children) (function)

Structure: xml-tag ()
Package

markup

Source

markup.lisp (file)

Direct superclasses

structure-object (structure)

Direct methods
Direct slots
Slot: attributes
Type

(or null cons)

Readers

xml-tag-attributes (function)

Writers

(setf xml-tag-attributes) (function)

Slot: children
Type

(or null cons)

Readers

xml-tag-children (function)

Writers

(setf xml-tag-children) (function)

Slot: name
Type

symbol

Initform

(quote markup::dummy)

Readers

xml-tag-name (function)

Writers

(setf xml-tag-name) (function)


Previous: , Up: Internal definitions   [Contents][Index]

5.2.6 Classes

Class: escaped-string ()
Package

markup

Source

markup.lisp (file)

Direct superclasses

standard-object (class)

Direct methods
Direct slots
Slot: content
Initargs

:content

Readers

escaped-string-content (generic function)

Writers

(setf escaped-string-content) (generic function)

Class: unescaped-string ()
Package

markup

Source

markup.lisp (file)

Direct superclasses

standard-object (class)

Direct methods
Direct slots
Slot: content
Initargs

:content

Readers

unescaped-string-content (generic function)

Writers

(setf unescaped-string-content) (generic function)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   F   L   M  
Index Entry  Section

F
File, Lisp, markup.asd: The markup․asd file
File, Lisp, markup/markup.lisp: The markup/markup․lisp file
File, Lisp, markup/package.lisp: The markup/package․lisp file

L
Lisp File, markup.asd: The markup․asd file
Lisp File, markup/markup.lisp: The markup/markup․lisp file
Lisp File, markup/package.lisp: The markup/package․lisp file

M
markup.asd: The markup․asd file
markup/markup.lisp: The markup/markup․lisp file
markup/package.lisp: The markup/package․lisp file

Jump to:   F   L   M  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   %   (  
C   D   E   F   G   M   P   R   S   U   V   W   X  
Index Entry  Section

%
%deftag: Internal macros

(
(setf escaped-string-content): Internal generic functions
(setf escaped-string-content): Internal generic functions
(setf unescaped-string-content): Internal generic functions
(setf unescaped-string-content): Internal generic functions
(setf xml-merge-tag-children): Internal functions
(setf xml-tag-attributes): Internal functions
(setf xml-tag-children): Internal functions
(setf xml-tag-name): Internal functions

C
copy-xml-merge-tag: Internal functions
copy-xml-tag: Internal functions

D
deftag: Exported macros
deftag-symbol: Internal functions
deftag-value: Internal functions

E
enable-reader: Exported macros
escaped-string-content: Internal generic functions
escaped-string-content: Internal generic functions

F
format-attr-val: Internal functions
Function, (setf xml-merge-tag-children): Internal functions
Function, (setf xml-tag-attributes): Internal functions
Function, (setf xml-tag-children): Internal functions
Function, (setf xml-tag-name): Internal functions
Function, copy-xml-merge-tag: Internal functions
Function, copy-xml-tag: Internal functions
Function, deftag-symbol: Internal functions
Function, deftag-value: Internal functions
Function, format-attr-val: Internal functions
Function, make-escaped: Internal functions
Function, make-merge-tag: Exported functions
Function, make-xml-merge-tag: Internal functions
Function, make-xml-tag: Exported functions
Function, make-xml-tag-impl: Internal functions
Function, print-escaped-text: Internal functions
Function, print-escaped-text-minimal: Internal functions
Function, read-attr-key: Internal functions
Function, read-attr-val: Internal functions
Function, read-attributes: Internal functions
Function, read-comment: Internal functions
Function, read-string-from-xml: Internal functions
Function, read-tag: Internal functions
Function, read-tag-from-string: Internal functions
Function, read-whitespace: Internal functions
Function, read-xml: Exported functions
Function, read-xml-after-bracket: Internal functions
Function, read-xml-from-string: Exported functions
Function, standard-name?: Internal functions
Function, unescaped: Exported functions
Function, void-tag?: Internal functions
Function, whitespacep: Internal functions
Function, write-attributes: Internal functions
Function, write-html: Exported functions
Function, write-xml: Exported functions
Function, write-xml-to-stream: Exported functions
Function, xml-merge-tag-children: Internal functions
Function, xml-merge-tag-p: Internal functions
Function, xml-tag-attributes: Internal functions
Function, xml-tag-children: Internal functions
Function, xml-tag-name: Internal functions
Function, xml-tag-p: Internal functions

G
Generic Function, (setf escaped-string-content): Internal generic functions
Generic Function, (setf unescaped-string-content): Internal generic functions
Generic Function, escaped-string-content: Internal generic functions
Generic Function, unescaped-string-content: Internal generic functions
Generic Function, write-html-to-stream: Exported generic functions

M
Macro, %deftag: Internal macros
Macro, deftag: Exported macros
Macro, enable-reader: Exported macros
Macro, make-escape-map: Internal macros
make-escape-map: Internal macros
make-escaped: Internal functions
make-merge-tag: Exported functions
make-xml-merge-tag: Internal functions
make-xml-tag: Exported functions
make-xml-tag-impl: Internal functions
Method, (setf escaped-string-content): Internal generic functions
Method, (setf unescaped-string-content): Internal generic functions
Method, escaped-string-content: Internal generic functions
Method, unescaped-string-content: Internal generic functions
Method, write-html-to-stream: Exported generic functions
Method, write-html-to-stream: Exported generic functions
Method, write-html-to-stream: Exported generic functions
Method, write-html-to-stream: Exported generic functions
Method, write-html-to-stream: Exported generic functions
Method, write-html-to-stream: Exported generic functions
Method, write-html-to-stream: Exported generic functions

P
print-escaped-text: Internal functions
print-escaped-text-minimal: Internal functions

R
read-attr-key: Internal functions
read-attr-val: Internal functions
read-attributes: Internal functions
read-comment: Internal functions
read-string-from-xml: Internal functions
read-tag: Internal functions
read-tag-from-string: Internal functions
read-whitespace: Internal functions
read-xml: Exported functions
read-xml-after-bracket: Internal functions
read-xml-from-string: Exported functions

S
standard-name?: Internal functions

U
unescaped: Exported functions
unescaped-string-content: Internal generic functions
unescaped-string-content: Internal generic functions

V
void-tag?: Internal functions

W
whitespacep: Internal functions
write-attributes: Internal functions
write-html: Exported functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-html-to-stream: Exported generic functions
write-xml: Exported functions
write-xml-to-stream: Exported functions

X
xml-merge-tag-children: Internal functions
xml-merge-tag-p: Internal functions
xml-tag-attributes: Internal functions
xml-tag-children: Internal functions
xml-tag-name: Internal functions
xml-tag-p: Internal functions

Jump to:   %   (  
C   D   E   F   G   M   P   R   S   U   V   W   X  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *  
A   C   N   S  
Index Entry  Section

*
*escape-map*: Internal special variables
*escape-minimal-map*: Internal special variables
*standard-name-cache*: Internal special variables
*standard-names*: Internal special variables
*void-tag-cache*: Internal special variables
*void-tags*: Internal special variables

A
attributes: Internal structures

C
children: Internal structures
children: Internal structures
content: Internal classes
content: Internal classes

N
name: Internal structures

S
Slot, attributes: Internal structures
Slot, children: Internal structures
Slot, children: Internal structures
Slot, content: Internal classes
Slot, content: Internal classes
Slot, name: Internal structures
Special Variable, *escape-map*: Internal special variables
Special Variable, *escape-minimal-map*: Internal special variables
Special Variable, *standard-name-cache*: Internal special variables
Special Variable, *standard-names*: Internal special variables
Special Variable, *void-tag-cache*: Internal special variables
Special Variable, *void-tags*: Internal special variables

Jump to:   *  
A   C   N   S  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   C   E   M   P   S   U   X  
Index Entry  Section

C
Class, escaped-string: Internal classes
Class, unescaped-string: Internal classes

E
escaped-string: Internal classes

M
markup: The markup system
markup: The markup package

P
Package, markup: The markup package

S
Structure, xml-merge-tag: Internal structures
Structure, xml-tag: Internal structures
System, markup: The markup system

U
unescaped-string: Internal classes

X
xml-merge-tag: Internal structures
xml-tag: Internal structures

Jump to:   C   E   M   P   S   U   X