diff --git a/CHANGELOG.md b/CHANGELOG.md
index c469dda..4792b51 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,10 @@
# Change Log
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
-## [Unreleased]
+## 0.1.4 - 2018-0922
+
+### Added
+Mainly documentation and tidy-up; Beta release.
## 0.1.0 - 2018-06-17
### Added
diff --git a/README.md b/README.md
index 61793e1..dc6b14b 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ A Clojure library designed to support auto-generated [ADL](https://github.com/si
## Usage
-You don't really use this; code auto-generated by ADL does.
+You don't really use this; code auto-generated by ADL does. Some functions which may be more generally useful are in `adl-support.core`, q.v.
## License
diff --git a/doc/adl-support.core.html b/doc/adl-support.core.html
new file mode 100644
index 0000000..8edc691
--- /dev/null
+++ b/doc/adl-support.core.html
@@ -0,0 +1,28 @@
+
+
Application Description Language support - utility functions likely
+to be useful in user-written code.
*warn*
dynamic
The idea here is to have a function with which to show warnings to the user,
+which can be dynamically bound. Any binding should be a function of one
+argument, which it should print, log, or otherwise display.
Compose a reason message for this `exception`, log it (with its
+stacktrace), and return the reason message.
do-or-log-and-return-reason
macro
(do-or-log-and-return-reason form)
Clojure stacktraces are unreadable. We have to do better; evaluate
+this `form` in a try-catch block; return a map. If the evaluation
+succeeds, the map will have a key `:result` whose value is the result;
+otherwise it will have a key `:error` which will be bound to the most
+sensible error message we can construct. Additionally, log the exception
do-or-log-error
macro
(do-or-log-error form & {:keys [message error-return], :or {message (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/str)) (clojure.core/list "A failure occurred in ") (clojure.core/list (list (quote quote) form))))}})
Evaluate the supplied `form` in a try/catch block. If the
+keyword param `:message` is supplied, the value will be used
+as the log message; if the keyword param `:error-return` is
+supplied, the value will be returned if an exception is caught.
do-or-return-reason
macro
(do-or-return-reason form intro)(do-or-return-reason form)
Clojure stacktraces are unreadable. We have to do better; evaluate
+this `form` in a try-catch block; return a map. If the evaluation
+succeeds, the map will have a key `:result` whose value is the result;
+otherwise it will have a key `:error` which will be bound to the most
+sensible error message we can construct.
do-or-warn
macro
(do-or-warn form)(do-or-warn form intro)
Evaluate this `form`; if any exception is thrown, show it to the user
+via the `*warn*` mechanism.
do-or-warn-and-log
macro
(do-or-warn-and-log form)(do-or-warn-and-log form intro)
Evaluate this `form`; if any exception is thrown, log the reason and
+show it to the user via the `*warn*` mechanism.
massage-params
Sending empty strings, or numbers as strings, to the database often isn't
+helpful. Massage these `params` and `form-params` to eliminate these problems.
+We must take key field values out of just params, but we should take all other
+values out of form-params - because we need the key to load the form in
+the first place, but just accepting values of other params would allow spoofing.
massage-value
(massage-value k m)
Return a map with one key, this `k` as a keyword, whose value is the binding of
+`k` in map `m`, as read by read.
Sending empty strings, or numbers as strings, to the database often isn't
+helpful. Massage these `params` and `form-params` to eliminate these problems.
+Date and time fields also need massaging.
raw-resolve-template
(raw-resolve-template n)
FIXME: write docs
resolve-template
FIXME: write docs
\ No newline at end of file
diff --git a/doc/adl-support.filters.html b/doc/adl-support.filters.html
new file mode 100644
index 0000000..eb4d979
--- /dev/null
+++ b/doc/adl-support.filters.html
@@ -0,0 +1,7 @@
+
+adl-support.filters documentation
Application Description Language support - custom Selmer filters
+used in generated templates.
*default-international-dialing-prefix*
dynamic
The international dialing prefix to use, if none is specified.
+
email
(email arg)
If `arg` is, or appears to be, a valid email address, convert it into
+a `mailto:` link, else leave it be.
telephone
(telephone arg)
If `arg` is, or appears to be, a valid telephone number, convert it into
+a `tel:` link, else leave it be.
\ No newline at end of file
diff --git a/doc/adl-support.forms-support.html b/doc/adl-support.forms-support.html
new file mode 100644
index 0000000..165c2a7
--- /dev/null
+++ b/doc/adl-support.forms-support.html
@@ -0,0 +1,15 @@
+
+adl-support.forms-support documentation
Application Description Language support - functions useful in
+generating forms.
all-keys-present?
macro
(all-keys-present? m keys)
Return true if all the keys in `keys` are present in the map `m`.
+
auxlist-data-name
macro
(auxlist-data-name auxlist)
The name to which data for this `auxlist` will be bound in the
+Selmer params.
get-current-value
macro
(get-current-value f params entity-name)
Use the function `f` and these `params` to fetch an `entity` record from the database.
+
get-menu-options
macro
(get-menu-options entity-name get-q list-q fk value)
Fetch options for a menu of `entity-name` from the database, using this
+`get-q` query and this `list-q` query, using the key `fk`, where the current
+value is this `value`.
prepare-insertion-params
macro
(prepare-insertion-params params fields)
Params for insertion into the database must have keys for all fields in the
+insert query, even if the value of some of those keys is nil. Massage these
+`params` to have a value for each field in these `fields`.
property-defaults
(property-defaults entity)
Get a map of property names and default values for all properties of this
+`entity` which have explicit defaults.
query-name
(query-name entity-or-name q-type)
Generate a query name for the query of type `q-type` (expected to be one
+of `:create`, `:delete`, `:get`, `:list`, `:search-strings`, `:update`) of
+the entity `entity-or-name` NOTE: if `entity-or-name` is passed as a string,
+it should be the full, unaltered name of the entity.
\ No newline at end of file
diff --git a/doc/adl-support.print-usage.html b/doc/adl-support.print-usage.html
new file mode 100644
index 0000000..85b573e
--- /dev/null
+++ b/doc/adl-support.print-usage.html
@@ -0,0 +1,8 @@
+
+adl-support.print-usage documentation
Print a UN*X style usage message. `project-name` should be the base name of
+the executable jar file you generate, `parsed-options` should be options as
+parsed by [clojure.tools.cli](https://github.com/clojure/tools.cli). If
+`extra-args` is supplied, it should be a map of name, documentation pairs
+for each additional argument which may be supplied.
\ No newline at end of file
diff --git a/doc/adl-support.rest-support.html b/doc/adl-support.rest-support.html
new file mode 100644
index 0000000..2e2e421
--- /dev/null
+++ b/doc/adl-support.rest-support.html
@@ -0,0 +1,9 @@
+
+adl-support.rest-support documentation
Application Description Language support - functions useful in
+generating JSON route handlers.
do-or-server-fail
macro
(do-or-server-fail form status)
Evaluate this `form`; if it succeeds, return an HTTP response with this
+status code and the JSON-formatted result as body; if it fails, return an
+HTTP 500 response.
if-valid-user
macro
(if-valid-user form request error-return)(if-valid-user form request)
Evaluate this `form` only if there is a valid user in the session of
+this `request`; otherwise return the `error-return` value.
valid-user-or-forbid
macro
(valid-user-or-forbid form request)
Evaluate this `form` only if there is a valid user in the session of
+this `request`; otherwise return an HTTP forbidden response.
with-params-or-error
macro
(with-params-or-error form params required)
Evaluate this `form` only if these `params` contain all these `required` keys;
+otherwise return an HTTP 400 response.
\ No newline at end of file
diff --git a/doc/adl-support.tags.html b/doc/adl-support.tags.html
new file mode 100644
index 0000000..43dc61e
--- /dev/null
+++ b/doc/adl-support.tags.html
@@ -0,0 +1,5 @@
+
+adl-support.tags documentation
If at least one of these `args` matches some group name in the `:user-roles`
+of this `context`, return this `success`, else this `failure`.
\ No newline at end of file
diff --git a/doc/adl-support.utils.html b/doc/adl-support.utils.html
new file mode 100644
index 0000000..b6d9c58
--- /dev/null
+++ b/doc/adl-support.utils.html
@@ -0,0 +1,65 @@
+
+adl-support.utils documentation
Application Description Language support - utility functions.
+
*locale*
dynamic
The locale for which files will be generated.
+
*output-path*
dynamic
The path to which generated files will be written.
+
*verbosity*
dynamic
The verbosity of output from the generator.
+
all-properties
macro
(all-properties entity)
Return all properties of this `entity` (including key properties).
+
attributes
(attributes element)(attributes element predicate)
Return the attributes of this `element`; if `predicate` is passed, return only those
+attributes satisfying the predicate.
base-type
(base-type property application)
FIXME: write docs
capitalise
(capitalise s)
Return a string like `s` but with each token capitalised.
+
child
(child element predicate)
Return the first child of this `element` satisfying this `predicate`.
+
child-with-tag
(child-with-tag element tag)(child-with-tag element tag predicate)
Return the first child of this `element` which has this `tag`;
+if `element` is `nil`, return `nil`. If `predicate` is supplied,
+return only the first child with the specified `tag` which satisfies
+the `predicate`.
children
(children element)(children element predicate)
Return the children of this `element`; if `predicate` is passed, return only those
+children satisfying the predicate.
children-with-tag
(children-with-tag element tag)(children-with-tag element tag predicate)
Return all children of this `element` which have this `tag`;
+if `element` is `nil`, return `nil`. If `predicate` is supplied,
+return only those children with the specified `tag` which satisfy
+the `predicate`.
column-name
(column-name property)
Return, as a string, the name for the column which represents this `property`.
+
descendant-with-tag
(descendant-with-tag element tag)(descendant-with-tag element tag predicate)
Return the first descendant of this `element`, recursively, which has this `tag`.
+If `predicate` is specified, return the first also satisfying this `predicate`.
descendants-with-tag
(descendants-with-tag element tag)(descendants-with-tag element tag predicate)
Return all descendants of this `element`, recursively, which have this `tag`.
+If `predicate` is specified, return only those also satisfying this `predicate`.
distinct-properties
(distinct-properties entity)
FIXME: write docs
editor-name
(editor-name entity application)
Return the path-part of the editor form for this `entity`. Note:
+assumes the editor form is the first form listed for the entity.
element?
(element? o)
True if `o` is a Clojure representation of an XML element.
+
emit-header
(emit-header prefix & content)
Emit this `content` as a sequence of wrapped lines each prefixed with
+`prefix`, and the whole delimited by rules.
entity-for-property
(entity-for-property property application)
If this `property` references an entity, return that entity from this `application`
+
entity?
(entity? x)
Return true if `x` is an ADL entity.
+
find-permissions
(find-permissions & elements)
Return appropriate the permissions of the first of these `elements` which
+has permissions.
formal-primary-key?
(formal-primary-key? prop-or-name entity)
Does this `prop-or-name` appear to be a property (or the name of a property)
+which is a formal primary key of this entity?
has-non-key-properties?
(has-non-key-properties? entity)
FIXME: write docs
has-primary-key?
(has-primary-key? entity)
FIXME: write docs
insertable-key-properties
macro
(insertable-key-properties entity)
FIXME: write docs
insertable-properties
macro
(insertable-properties entity)
Return all the properties of this `entity` (including key properties) into
+which user-supplied data can be inserted
insertable?
(insertable? property)
Return `true` it the value of this `property` may be set from user-supplied data.
+
is-quotable-type?
(is-quotable-type? property application)
True if the value for this field should be quoted.
+
Canonical name of a link table between entity `e1` and entity `e2`. However, there
+may be different links between the same two tables with different semantics; if
+`property` is specified, and if more than one property in `e1` links to `e2`, generate
+a more specific link name.
link-table?
(link-table? entity)
Return true if this `entity` represents a link table.
+
Return the canonical name of the HugSQL query to return all records on
+`farside` which match a given record on `nearside`, where `nearide` and
+`farside` are both entities.
path-part
(path-part form entity application)
Return the URL path part for this `form` of this `entity` within this `application`.
+Note that `form` may be a Clojure XML representation of a `form`, `list` or `page`
+ADL element, or may be one of the keywords `:form`, `:list`, `:page` in which case the
+first child of the `entity` of the specified type will be used.
permission-groups
(permission-groups permissions predicate)
Return a list of names of groups to which this `predicate` is true of
+some permission taken from these `permissions`, else nil.
pretty-name
(pretty-name element)
Return a version of the name of this `element` (entity, field,
+form, list, page, property) suitable for use in text visible to the user.
prompt
(prompt field-or-property form entity application)
Return an appropriate prompt for the given `field-or-property` taken from this
+`form` of this `entity` of this `application`, in the context of the current
+binding of `*locale*`. TODO: something more sophisticated about i18n
properties
macro
(properties entity)
Return all the properties of this `entity`.
+
property-for-field
(property-for-field field entity)
Return the property within this `entity` which matches this `field`.
+
property?
(property? o)
True if `o` is a property.
+
required-properties
(required-properties entity)
Return the properties of this `entity` which are required and are not
+system generated.
safe-name
(safe-name o)(safe-name o convention)
Return a safe name for the object `o`, given the specified `convention`.
+`o` is expected to be either a string or an element. Recognised values for
+`convention` are: #{:c :c-sharp :java :sql}
singularise
(singularise string)
Attempt to construct an idiomatic English-language singular of this string.
+
sort-by-name
(sort-by-name elements)
Sort these `elements` by their `:name` attribute.
+
system-generated?
(system-generated? property)
True if the value of the `property` is system generated, and
+should not be set by the user.
type-for-defined
(type-for-defined property application)
FIXME: write docs
typedef
(typedef property application)
If this `property` is of type `defined`, return its type definition from
+this `application`, else nil.
unique-link?
(unique-link? e1 e2)
True if there is exactly one link between entities `e1` and `e2`.
+
user-distinct-properties
(user-distinct-properties entity)
Return the properties of this `entity` which are user distinct
+
user-distinct-property-names
(user-distinct-property-names entity)
Return, as a set, the names of properties which are user distinct
+
visible-to
(visible-to permissions)
Return a list of names of groups to which are granted read access,
+given these `permissions`, else nil.
volatility
(volatility entity)
Return the cache ttl in seconds for records of this `entity`.
+
wrap-lines
(wrap-lines width text)(wrap-lines text)
Wrap lines in this `text` to this `width`; return a list of lines.
+
Return a list of names of groups to which are granted write access,
+given these `permissions`, else nil.
+TODO: TOTHINKABOUT: properties are also writeable by `insert` and `noedit`, but only if the
+current value is nil.
\ No newline at end of file
diff --git a/doc/intro.html b/doc/intro.html
new file mode 100644
index 0000000..2114302
--- /dev/null
+++ b/doc/intro.html
@@ -0,0 +1,4 @@
+
+Introduction to adl-support
adl-support is a small library of functions used by the Application Description Language system to generate elements of a Clojure web-app, which may be useful to people writing web-apps either based on Application Description Language or otherwise.