The pludeck Reference Manual

Table of Contents

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

The pludeck Reference Manual

This is the pludeck Reference Manual, version 1.0.0, generated automatically by Declt version 2.4 patchlevel 1 "Will Decker" on Mon Jul 29 16:25:27 2019 GMT+0.


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

1 Introduction

Pludeck

Quicklisp

Pludeck is a small Common Lisp library offering a friendly interface for creating a Plump DOM.

It depends only on Plump (Artistic License 2.0)

Installation

Once Pludeck is in a Quicklisp dist, it can be loaded without any further action:

(ql:quickload :pludeck)

If not, you can clone this repository into quicklisp/local-projects. You may need to call (ql:register-local-projects), after which you can use the same form as above.

Usage

;;; This example generates a document in an imaginary format.

(<>root
  (<?xml "version" "1.0")
  (<!-- "This is a Pludeck example")
  (<> ("document" "markupSyntax" "imaginary" :encoding "utf-8")
    (<> "title" "Fixnums are cool")
    (<> "blocks"
      (<> "paragraph"
        "The maximum value of a fixnum on this system is "
        most-positive-fixnum
        ". That's a lot!")
      (<> ("image" :src "https://example.com/woah.png")))))

Pludeck exports a number of macros, all of which have names starting with <. Some represent specific XML elements you could find in an XML document, in which case the name is made to look like the opening of such an element. This includes <?xml and <!--, used above. Other macros are more general or abstract, in which case the name starts with <>. This includes <>root and the general element construction macro <>.

To insert a text node into the DOM, the macro <>text can be used. It calls PRINC-TO-STRING on its argument. You may notice the above example does not include any invocations of <>text, which is because Pludeck will automatically wrap it around certain expressions in the body of an element. The rule for this is very simple: If it's not a literal list, it gets wrapped in <>text. This replacement does not recurse into the tree. This rule allows you to insert literal values and variables directly into the tree, without explicitly marking them as text.

Pludeck also offers a way to define specific macros for the XML elements you want to use. These can help clean up your code if you use the same elements often.

;;; This is the same example, but with a macro for each type of element.

(<>define <document "document" :attributes t :content t)
(<>define <title> "title" :content t)
(<>define <blocks> "blocks" :content t)
(<>define <paragraph> "paragraph" :content t)
(<>define <image "image" :attributes t)

(<>root
  (<?xml "version" "1.0")
  (<!-- "This is a Pludeck example")
  (<document ("markupSyntax" "imaginary" :encoding "utf-8")
    (<title> "Fixnums are cool")
    (<blocks>
      (<paragraph>
        "The maximum value of a fixnum on this system is "
        most-positive-fixnum
        ". That's a lot!")
      (<image :src "https://example.com/woah.png"))))

Syntax rationale

The Common Lisp ecosystem has various different solutions for turning S-expressions into HTML. Most notable is probably the CL-WHO family, but there is also YACLML (syntax description).

The CL-WHO syntax requires a tradeoff between being aggressive by assuming anything in the body that looks like (:tag) is meant to be a tag (which Spinneret does), and requiring any tags nested inside other code to be explicitly wrapped in some form (which CL-WHO does with its HTM). Both of these require some level of code walking.

The fact that XML is case-sensitive, unlike HTML, means a CL-WHO-like approach would need to either support ("Tags" :like "this"), or require users to use escaped symbols, (:|Tags| :like "this"). This makes the aggressive approach more overbearing than it already is, and can turn even the conservative approach into a bit of a mess.

The YACLML solution is a bit nicer, since each tag is simply a macro. It uses a package named < to give tags a distinct look, which also helps make things clearer. Pludeck looks more like YACLML than like CL-WHO, though it doesn't include a package pre-filled with HTML tags. Instead it uses symbol names starting with <.

Reference

<>root

At the top of a DOM tree you need a DOM root:

(defmacro <>root (&body body)
  "Bind a new Plump DOM root as the parent for enclosed elements.

Note that this binding is dynamic, meaning an element constructed inside a
function called from the body will also have this DOM root as its parent.

Any non-list in the body (non-recursive) is wrapped in a call to <>TEXT.

Returns the constructed DOM root."
  ...)

<>wrap

You can use any DOM element as a parent:

(defmacro <>wrap (parent &body body)
  "Bind the given element as the parent for enclosed elements.

Note that this binding is dynamic, meaning an element constructed inside a
function called from the body will also have this DOM root as its parent.

Any non-list in the body (non-recursive) is wrapped in a call to <>TEXT.

Returns the given parent element."
  ...)

<>

Constructing arbitrary DOM elements is easy with <>:

(defmacro <> (tag/attributes &body body)
  "Create a new element, with the closest enclosing element as the parent. This
element will in turn serve as the parent for any elements constructed in its
body.

Note that this binding is dynamic, meaning an element constructed inside a
function called from the body will also have this DOM root as its parent.

TAG/ATTRIBUTES can either be a string, which will be used as the tag name, or a
list. If it is a list, the first item should be a string that serves as the tag
name, and the rest of the items form a plist of attribute names and values.
Both the names and the values are evaluated. If a name evaluates to a symbol,
its lowercased name is used as the attribute name. In all other cases the value
of (PRINC-TO-STRING name) is used. The values are also passed to
PRINC-TO-STRING.

Any non-list in the body (non-recursive) is wrapped in a call to <>TEXT.

Returns the constructed element."
  ...)

<>text

Text nodes can be constructed using <>text, though this call can often be implicit:

(defmacro <>text (content)
  "Create a new text node with the closest enclosing element as the parent.
CONTENT is passed to PRINC-TO-STRING.

Returns the constructed text node."
  ...)

<>fulltext

Plump also has the construct of a fulltext node, used for <style> and <script> in HTML.

(defmacro <>fulltext (tag/attributes content)
  "Create a new fulltext node with the closest enclosing element as the parent.
CONTENT is passed to PRINC-TO-STRING.

A fulltext node is a DOM element that contains text that is not escaped using
HTML entities. This is primarily useful for <style> and <script> in HTML.

Returns the constructed text node."
  ...)

<?xml

There is a special macro for inserting XML header nodes:

(defmacro <?xml (&rest attributes)
  "Create a new XML header with the closest enclosing element as the parent.
Attributes are handled just like in <>.

Returns the XML header node."
  ...)

<!--

There is a special macro for inserting comments:

(defmacro <!-- (&optional (text ""))
  "Create a comment with the closest enclosing element as the parent.

Returns the comment node."
  ...)

<!doctype

There is a special macro for inserting doctype nodes:

(defmacro <!doctype (doctype)
  "Create a doctype element with the closest enclosing element as the parent.

Returns the doctype node."
  ...)

<![cdata[

There is a special macro for inserting CDATA nodes:

(defmacro <![cdata[ (&optional (text ""))
  "Create a CDATA element with the closest enclosing element as the parent.

Returns the CDATA node."
  ...)

License

Copyright (c) 2018 Joram Schrijver

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

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 pludeck

Author

Joram Schrijver <i@joram.io>

License

MIT

Description

A friendly interface for creating a Plump DOM.

Version

1.0.0

Dependency

plump

Source

pludeck.asd (file)

Component

pludeck.lisp (file)


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 pludeck.asd

Location

pludeck.asd

Systems

pludeck (system)


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

3.1.2 pludeck/pludeck.lisp

Parent

pludeck (system)

Location

pludeck.lisp

Packages

pludeck

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 pludeck

Source

pludeck.lisp (file)

Use List

common-lisp

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


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

5.1.1 Macros

Macro: <!-- &optional TEXT

Create a comment with the closest enclosing element as the parent.

Returns the comment node.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <![cdata[ &optional TEXT

Create a CDATA element with the closest enclosing element as the parent.

Returns the CDATA node.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <!doctype DOCTYPE

Create a doctype element with the closest enclosing element as the parent.

Returns the doctype node.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <> TAG/ATTRIBUTES &body BODY

Create a new element, with the closest enclosing element as the parent. This element will in turn serve as the parent for any elements constructed in its body.

Note that this binding is dynamic, meaning an element constructed inside a function called from the body will also have this DOM root as its parent.

TAG/ATTRIBUTES can either be a string, which will be used as the tag name, or a list. If it is a list, the first item should be a string that serves as the tag name, and the rest of the items form a plist of attribute names and values. Both the names and the values are evaluated. If a name evaluates to a symbol, its lowercased name is used as the attribute name. In all other cases the value of (PRINC-TO-STRING name) is used. The values are also passed to PRINC-TO-STRING.

Any non-list in the body (non-recursive) is wrapped in a call to <>TEXT.

Returns the constructed element.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <>define NAME TAG &key ATTRIBUTES CONTENT

Define a macro to simplify construction of a specific type of DOM element.

The macro will be named NAME, and TAG will be the tag name of the elements it produces. The arguments for this newly defined macro depend on the values of ATTRIBUTES and CONTENT:

- If neither ATTRIBUTES nor CONTENT is true, the macro will take no arguments.

- If ATTRIBUTES is true and CONTENT is not, the macro will take attribute names and values as direct arguments.

- If CONTENT is true and ATTRIBUTES is not, the macro will take a body as its arguments. This body will get the same treatment as the one for <>.

- If both ATTRIBUTES and CONTENT are true, the macro will take a list of attribute names and values as its first argument, followed by a body. This body will similarly get the same treatment as the one for <>.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <>fulltext TAG/ATTRIBUTES CONTENT

Create a new fulltext node with the closest enclosing element as the parent. CONTENT is passed to PRINC-TO-STRING.

A fulltext node is a DOM element that contains text that is not escaped using HTML entities. This is primarily useful for <style> and <script> in HTML.

Returns the constructed text node.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <>root &body BODY

Bind a new Plump DOM root as the parent for enclosed elements.

Note that this binding is dynamic, meaning an element constructed inside a function called from the body will also have this DOM root as its parent.

Any non-list in the body (non-recursive) is wrapped in a call to <>TEXT.

Returns the constructed DOM root.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <>text CONTENT

Create a new text node with the closest enclosing element as the parent. CONTENT is passed to PRINC-TO-STRING.

Returns the constructed text node.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <>wrap PARENT &body BODY

Bind the given element as the parent for enclosed elements.

Note that this binding is dynamic, meaning an element constructed inside a function called from the body will also have this DOM root as its parent.

Any non-list in the body (non-recursive) is wrapped in a call to <>TEXT.

Returns the given parent element.

Package

pludeck

Source

pludeck.lisp (file)

Macro: <?xml &rest ATTRIBUTES

Create a new XML header with the closest enclosing element as the parent. Attributes are handled just like in <>.

Returns the XML header node.

Package

pludeck

Source

pludeck.lisp (file)


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

5.2 Internal definitions


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

5.2.1 Special variables

Special Variable: *parent*
Package

pludeck

Source

pludeck.lisp (file)


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

5.2.2 Functions

Function: parse-attributes ATTRIBUTES ATTRIBUTE-MAP-SYM

Transform a plist of attributes into a list of calls to SETF, putting those attributes into a Plump attribute map. Both the keys and the values are evaluated. An evaluated key may either be a symbol, in which it is lowercased, or any other value that can be turned into a string using PRINC-TO-STRING.

Package

pludeck

Source

pludeck.lisp (file)

Function: preprocess-body BODY

Wrap any element of the body that is not a list in <>text.

Package

pludeck

Source

pludeck.lisp (file)


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

Appendix A Indexes


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

A.1 Concepts

Jump to:   F   L   P  
Index Entry  Section

F
File, Lisp, pludeck.asd: The pludeck<dot>asd file
File, Lisp, pludeck/pludeck.lisp: The pludeck/pludeck<dot>lisp file

L
Lisp File, pludeck.asd: The pludeck<dot>asd file
Lisp File, pludeck/pludeck.lisp: The pludeck/pludeck<dot>lisp file

P
pludeck.asd: The pludeck<dot>asd file
pludeck/pludeck.lisp: The pludeck/pludeck<dot>lisp file

Jump to:   F   L   P  

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

A.2 Functions

Jump to:   <  
F   M   P  
Index Entry  Section

<
<!--: Exported macros
<!doctype: Exported macros
<![cdata[: Exported macros
<>: Exported macros
<>define: Exported macros
<>fulltext: Exported macros
<>root: Exported macros
<>text: Exported macros
<>wrap: Exported macros
<?xml: Exported macros

F
Function, parse-attributes: Internal functions
Function, preprocess-body: Internal functions

M
Macro, <!--: Exported macros
Macro, <!doctype: Exported macros
Macro, <![cdata[: Exported macros
Macro, <>: Exported macros
Macro, <>define: Exported macros
Macro, <>fulltext: Exported macros
Macro, <>root: Exported macros
Macro, <>text: Exported macros
Macro, <>wrap: Exported macros
Macro, <?xml: Exported macros

P
parse-attributes: Internal functions
preprocess-body: Internal functions

Jump to:   <  
F   M   P  

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

A.3 Variables

Jump to:   *  
S  
Index Entry  Section

*
*parent*: Internal special variables

S
Special Variable, *parent*: Internal special variables

Jump to:   *  
S  

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

A.4 Data types

Jump to:   P   S  
Index Entry  Section

P
Package, pludeck: The pludeck package
pludeck: The pludeck system
pludeck: The pludeck package

S
System, pludeck: The pludeck system

Jump to:   P   S