aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/ref/calp-prime.texi8
-rw-r--r--doc/ref/calp.texi14
-rw-r--r--doc/ref/entry-points.texi62
-rw-r--r--doc/ref/general.texi31
-rw-r--r--doc/ref/general/base64.texi (renamed from doc/ref/guile/base64.texi)0
-rw-r--r--doc/ref/general/bst.texi37
-rw-r--r--doc/ref/general/crypto.texi17
-rw-r--r--doc/ref/general/data-formats.texi (renamed from doc/ref/guile/data-formats.texi)0
-rw-r--r--doc/ref/general/data-stores.texi (renamed from doc/ref/guile/data-stores.texi)0
-rw-r--r--doc/ref/general/datetime.texi (renamed from doc/ref/guile/datetime.texi)0
-rw-r--r--doc/ref/general/glob.texi37
-rw-r--r--doc/ref/general/graph.texi65
-rw-r--r--doc/ref/general/graphviz.texi10
-rw-r--r--doc/ref/general/io.texi31
-rw-r--r--doc/ref/general/lens.texi (renamed from doc/ref/guile/lens.texi)0
-rw-r--r--doc/ref/general/options.texi32
-rw-r--r--doc/ref/general/srfi-41.texi (renamed from doc/ref/guile/srfi-41.texi)22
-rw-r--r--doc/ref/general/sxml.texi (renamed from doc/ref/guile/sxml.texi)0
-rw-r--r--doc/ref/general/util-config.texi (renamed from doc/ref/guile/util-config.texi)0
-rw-r--r--doc/ref/general/util-exceptions.texi40
-rw-r--r--doc/ref/general/util-object.texi (renamed from doc/ref/guile/util-object.texi)0
-rw-r--r--doc/ref/general/util-path.texi (renamed from doc/ref/guile/util-path.texi)9
-rw-r--r--doc/ref/general/util-type.texi (renamed from doc/ref/guile/util-type.texi)0
-rw-r--r--doc/ref/general/util.texi (renamed from doc/ref/guile/util.texi)84
-rw-r--r--doc/ref/general/uuid.texi17
-rw-r--r--doc/ref/general/webdav.texi (renamed from doc/ref/guile/webdav.texi)0
-rw-r--r--doc/ref/general/xdg-basedir.texi62
-rw-r--r--doc/ref/general/zic.texi (renamed from doc/ref/guile/zic.texi)0
-rw-r--r--doc/ref/guile.texi192
-rw-r--r--doc/ref/introspection.texi84
-rw-r--r--doc/ref/javascript.texi48
-rw-r--r--doc/ref/javascript/clock.texi78
-rw-r--r--doc/ref/javascript/components/changelog.texi10
-rw-r--r--doc/ref/javascript/components/date_time_input.texi34
-rw-r--r--doc/ref/javascript/components/edit_rrule.texi10
-rw-r--r--doc/ref/javascript/components/input_list.texi16
-rw-r--r--doc/ref/javascript/components/popup_element.texi40
-rw-r--r--doc/ref/javascript/components/tab_group_element.texi46
-rw-r--r--doc/ref/javascript/components/vevent.texi23
-rw-r--r--doc/ref/javascript/components/vevent_block.texi10
-rw-r--r--doc/ref/javascript/components/vevent_description.texi16
-rw-r--r--doc/ref/javascript/components/vevent_dl.texi11
-rw-r--r--doc/ref/javascript/components/vevent_edit.texi9
-rw-r--r--doc/ref/javascript/eventCreator.texi15
-rw-r--r--doc/ref/javascript/formatters.texi23
-rw-r--r--doc/ref/javascript/globals.texi41
-rw-r--r--doc/ref/javascript/jcal.texi7
-rw-r--r--doc/ref/javascript/lib.texi148
-rw-r--r--doc/ref/javascript/server_connect.texi22
-rw-r--r--doc/ref/javascript/types.texi95
-rw-r--r--doc/ref/javascript/user-additions.texi18
-rw-r--r--doc/ref/javascript/vevent.texi113
-rw-r--r--doc/ref/text.texi9
-rw-r--r--doc/ref/text/flow.texi23
-rw-r--r--doc/ref/text/markup.texi71
-rw-r--r--doc/ref/text/numbers.texi42
-rw-r--r--doc/ref/text/utilities.texi67
-rw-r--r--doc/ref/vcomponent.texi (renamed from doc/ref/guile/vcomponent.texi)17
-rw-r--r--doc/ref/vulgar.texi27
-rw-r--r--doc/ref/vulgar/color.texi18
-rw-r--r--doc/ref/vulgar/termios.texi217
-rw-r--r--doc/ref/web.texi6
-rw-r--r--doc/ref/web/query.texi9
-rw-r--r--doc/ref/web/routes.texi (renamed from doc/ref/guile/web.texi)23
-rw-r--r--doc/ref/web/uri-query.texi7
65 files changed, 1115 insertions, 1108 deletions
diff --git a/doc/ref/calp-prime.texi b/doc/ref/calp-prime.texi
new file mode 100644
index 00000000..a13cbd0b
--- /dev/null
+++ b/doc/ref/calp-prime.texi
@@ -0,0 +1,8 @@
+@node Calp as a Program
+@chapter Calp as a Program
+
+@include calp/translation.texi
+@include calp/error.texi
+@include calp/other.texi
+
+
diff --git a/doc/ref/calp.texi b/doc/ref/calp.texi
index 92c30242..5815d922 100644
--- a/doc/ref/calp.texi
+++ b/doc/ref/calp.texi
@@ -1,4 +1,5 @@
\input texinfo
+@setfilename calp.info
@settitle Calp
@copying
@@ -63,8 +64,14 @@ text @footnote{Improvements welcome}
@c * Index::
@c @end menu
-@include guile.texi
-@include javascript.texi
+@include calp-prime.texi
+@include entry-points.texi
+@include general.texi
+@include vcomponent.texi
+@include web.texi
+@include text.texi
+@include vulgar.texi
+@include introspection.texi
@node Index
@unnumbered Index
@@ -75,7 +82,4 @@ text @footnote{Improvements welcome}
@printindex tp
@printindex vr
-@unnumbered Web Components
-@printindex wc
-
@bye
diff --git a/doc/ref/entry-points.texi b/doc/ref/entry-points.texi
new file mode 100644
index 00000000..4c4ec90f
--- /dev/null
+++ b/doc/ref/entry-points.texi
@@ -0,0 +1,62 @@
+@node Entry Points
+@chapter Entry Points
+
+Calp has many different entry points. Each is implemented in a module
+residing under @code{calp entry-points}. Each such module @emph{must}
+export a @code{main} procedure, which should take a list of command
+line arguments (as a single parameter).
+
+When starting Calp from the command line, the @code{main} procedure
+located in @code{(calp main)} is called. That procedure parse it's own
+command line flags, up until the first non-flag argument. That word
+will be used to chose the actual entry point, which is then
+responsible for parsing the remaining command line flags.
+
+Information about global command line arguments can be accessed by
+running @command{calp --help}, and subcommands arguments through
+@command{calp @var{<subcommand>} --help}.
+
+@deftp {Entry Point} benchmark module
+Run @code{(@ (calp benchmark @var{module}) run-benchmark)} with
+profiling enabled, and prints the collected data.
+@end deftp
+
+@deftp {Entry Point} convert
+Convert calendar files between filetypes.
+@end deftp
+
+@deftp {Entry Point} html
+Generates static HTML files.
+@end deftp
+
+@deftp {Entry Point} ical
+Generates static iCal files.
+@end deftp
+
+@deftp {Entry Point} import
+Import entry into database.
+@end deftp
+
+@deftp {Entry Point} server
+Start the web server.
+@end deftp
+
+@deftp {Entry Point} terminal
+Start the terminal interface.
+@end deftp
+
+@deftp {Entry Point} text
+Format text, completely ignoring calendars.
+@end deftp
+
+@deftp {Entry Point} tidsrapport
+Generate an FDF (PDF Form submission file) for some very specific time
+reporting sheets.
+
+TODO this should be removed from this project, and moved to a
+``private'' repo of hugo.
+@end deftp
+
+@deftp {Entry Point} update-zoneinfo
+Downloads zoneinfo files and places them in the correct location.
+@end deftp
diff --git a/doc/ref/general.texi b/doc/ref/general.texi
new file mode 100644
index 00000000..b97dece0
--- /dev/null
+++ b/doc/ref/general.texi
@@ -0,0 +1,31 @@
+@node Generally Useful Utilities
+@chapter Generally Useful Utilities
+
+These are all general utilitios with no direct relation to Calp. Many
+of these should be generally useful in any project.
+
+@include general/datetime.texi
+@include general/zic.texi
+@include general/srfi-41.texi
+@include general/util.texi
+@include general/uuid.texi
+@include general/io.texi
+@include general/bst.texi
+@include general/util-path.texi
+@include general/util-config.texi
+@include general/util-exceptions.texi
+@include general/base64.texi
+@include general/xdg-basedir.texi
+@include general/glob.texi
+@include general/graphviz.texi
+@include general/crypto.texi
+@include general/graph.texi
+@include general/options.texi
+
+
+@include general/util-type.texi
+@include general/util-object.texi
+@include general/lens.texi
+@include general/data-formats.texi
+@include general/data-stores.texi
+@include general/webdav.texi
diff --git a/doc/ref/guile/base64.texi b/doc/ref/general/base64.texi
index ab6bba81..ab6bba81 100644
--- a/doc/ref/guile/base64.texi
+++ b/doc/ref/general/base64.texi
diff --git a/doc/ref/general/bst.texi b/doc/ref/general/bst.texi
new file mode 100644
index 00000000..d2bba0ff
--- /dev/null
+++ b/doc/ref/general/bst.texi
@@ -0,0 +1,37 @@
+@node Binary Search Tree
+@section Binary Search Tree
+
+A simple ``read only'' binary search tree.
+
+@defun make-tree pred? lst
+Constructs a new tree. @var{pred?} should be a procedure taking the
+first element of @var{lst}, along with each element, and should return
+a boolean value indicating if the specific element should go in the
+left or right subtree. (left subtree is ``truthy'' values).
+
+This operation is done recursively.
+@end defun
+
+@defun tree-node tree
+Return the value of a tree node.
+@end defun
+
+@defun left-subtree tree
+Return all ``truthy'' children of tree node.
+@end defun
+
+@defun right-subtree tree
+Return all ``falsy children of tree node.
+@end defun
+
+@defun length-of-longest-branch tree
+Get the depth of a tree.
+@end defun
+
+@defun tree-map proc tree
+Apply proc onto the value of every node in tree, keeping the structure
+of the tree.
+
+@b{Note:} this can cause the tree to no longer be a binary search
+tree, but simply a ``formless'' binary tree.
+@end defun
diff --git a/doc/ref/general/crypto.texi b/doc/ref/general/crypto.texi
new file mode 100644
index 00000000..b9e362d3
--- /dev/null
+++ b/doc/ref/general/crypto.texi
@@ -0,0 +1,17 @@
+@node Cryptographic and Hash Procedures
+@section Cryptographic and Hash Procedures
+
+This module links libcrypto, exposing some hash procedures.
+
+@defun sha256 message
+Calculate the sha256-sum of @var{message}. The message can either be a
+bytevector or a string (in which case it will de encoded as UTF-8).
+
+Returns the checksum as a bytevector.
+@end defun
+
+@defun checksum->string message-digest [port]
+Generates a hex digest string from a checksum (generated by
+@code{sha256}). The checksum is written to @var{port} if given, or
+returned as a string otherwise.
+@end defun
diff --git a/doc/ref/guile/data-formats.texi b/doc/ref/general/data-formats.texi
index 037d3ae7..037d3ae7 100644
--- a/doc/ref/guile/data-formats.texi
+++ b/doc/ref/general/data-formats.texi
diff --git a/doc/ref/guile/data-stores.texi b/doc/ref/general/data-stores.texi
index ec3962da..ec3962da 100644
--- a/doc/ref/guile/data-stores.texi
+++ b/doc/ref/general/data-stores.texi
diff --git a/doc/ref/guile/datetime.texi b/doc/ref/general/datetime.texi
index 037ac8d5..037ac8d5 100644
--- a/doc/ref/guile/datetime.texi
+++ b/doc/ref/general/datetime.texi
diff --git a/doc/ref/general/glob.texi b/doc/ref/general/glob.texi
new file mode 100644
index 00000000..400eb1f7
--- /dev/null
+++ b/doc/ref/general/glob.texi
@@ -0,0 +1,37 @@
+@node Glob
+@section Glob
+
+@defun glob str
+Globs (glob(7)) on @var{str}, returing a list of files, which will be
+on the same form of the glob. E.g. @code{(glob "../*")} will return
+strings all starting with ``../''
+
+If no matches are found, a misc error is thrown.
+@end defun
+
+
+
+@defvar GLOB_NOMAGIC
+@defvarx GLOB_NOCHECK
+@defvarx unix
+@defvarx GLOB_NOSPACE
+@defvarx GLOB_TILDE_CHECK
+@defvarx GLOB_ALTDIRFUNC
+@defvarx GLOB_NOSORT
+@defvarx GLOB_NOMATCH
+@defvarx GLOB_TILDE
+@defvarx GLOB_ERR
+@defvarx GLOB_MAGCHAR
+@defvarx GLOB_BRACE
+@defvarx GLOB_APPEND
+@defvarx GLOB_NOSYS
+@defvarx GLOB_DOOFFS
+@defvarx GLOB_NOESCAPE
+@defvarx GLOB_MARK
+@defvarx GLOB_PERIOD
+@defvarx linux
+@defvarx GLOB_ABORTED
+@defvarx _POSIX_VDISABLE
+@defvarx GLOB_ONLYDIR
+``Symbols'' imported from the C header ``glob.h''. See that documentation.
+@end defvar
diff --git a/doc/ref/general/graph.texi b/doc/ref/general/graph.texi
new file mode 100644
index 00000000..1677b635
--- /dev/null
+++ b/doc/ref/general/graph.texi
@@ -0,0 +1,65 @@
+@node A Graph data structure
+@section A Graph data structure
+
+This is a simple immutable directed graph.
+
+Most operations are O(n), since Scheme lacks a total order betwen
+arbitrary objects.
+
+@defun make-graph [node-key-proc=identity] [node-equal?=eq?]
+Constructs a new graph.
+
+@var{node-key-proc} should be a procedure mapping the actual nodes to
+a value which can be compared. These values are sometimes called
+``node keys''.
+@cindex node keys
+
+@var{node-equal?} should return if two nodes are equal or not.
+@end defun
+
+@defun rebuild-graph [old-graph] [nodes='()] [edges='()]
+@c TODO document me
+@end defun
+
+@defun graph-empty? graph
+Does the graph contaitn
+@end defun
+
+@defun add-node graph node edge-neighbors
+Adds the value @var{node} to @var{graph}. @var{edge-neighbors} should
+be a list of node keys.
+@end defun
+
+@defun get-node graph key
+Retrieve a node from the graph, given its node key.
+
+Returns @code{#f} if no such node exists.
+@end defun
+
+@defun remove-node graph node
+Remvoe @var{node} from @var{graph}, if it exists.
+@end defun
+
+@defun find-dangling-node graph
+Find a node in the graph which no other node ``depends'' on (has an
+edge pointing at it).
+
+NOTE this is O(n^2) (maybe, sort of?)
+Getting it faster would require building an index, which
+is hard since there isn't a total order on symbols.
+@end defun
+
+
+@defun pop-dandling-node graph
+Find a node as per @code{find-dangling-node}, and return two values:
+the node, and a new graph without that node.
+@end defun
+
+@defun resolve-dependency-graph graph
+If each edge is assumed to indicate a nodes dependencies, then this
+procedure will find return a flat list where each dependency is before
+its dependants.
+
+If any link is missing, or a cycle exists, then the result is
+undefined.
+@end defun
diff --git a/doc/ref/general/graphviz.texi b/doc/ref/general/graphviz.texi
new file mode 100644
index 00000000..72817ea8
--- /dev/null
+++ b/doc/ref/general/graphviz.texi
@@ -0,0 +1,10 @@
+@node Graphviz
+@section Graphviz
+
+The graphviz library comes bundled with Guile bindings, but without a
+corresponding .scm file exporting the symbols. The module @code{(guile)} does
+exactly that.
+
+This ``header'' is borrowed from
+@url{https://github.com/roelj/graphviz-guile/blob/master/graphviz.scm},
+under GPL 3.0.
diff --git a/doc/ref/general/io.texi b/doc/ref/general/io.texi
new file mode 100644
index 00000000..3f67700b
--- /dev/null
+++ b/doc/ref/general/io.texi
@@ -0,0 +1,31 @@
+@node IO operations
+@section IO operations
+
+Provided by module @code{(hnh util io)}.
+
+@defun open-input-port path
+@defunx open-output-port path
+Like @code{open-*-file}, but ``-'' gives @code{standard-@{input,output@}}.
+@end defun
+
+@defun read-lines port
+Return a list of all lines read from port.
+@end defun
+
+@defun with-atomic-output-to-file filename thunk
+Same functionality as the regular @var{with-output-to-file}, but
+with the difference that either everything is written, or nothing
+is written, and if anything is written it's all written atomicaly at
+once (the original file will never contain an intermidiate state).
+Does NOT handle race conditions between threads.
+
+propagates the return value of @var{thunk} upon successfully writing
+the file, and @code{#f} otherwise.
+@end defun
+
+@defun call-with-tmpfile proc [#:tmpl ``/tmp/file-XXXXXXX'']
+@end defun
+
+@defun read-file path
+Open file at path, and return its content as a string.
+@end defun
diff --git a/doc/ref/guile/lens.texi b/doc/ref/general/lens.texi
index eeddd6ca..eeddd6ca 100644
--- a/doc/ref/guile/lens.texi
+++ b/doc/ref/general/lens.texi
diff --git a/doc/ref/general/options.texi b/doc/ref/general/options.texi
new file mode 100644
index 00000000..675e91f3
--- /dev/null
+++ b/doc/ref/general/options.texi
@@ -0,0 +1,32 @@
+@node Getopt-Long Extensions
+@section Getopt-Long extensions
+
+The module @code{(hnh util options)} extend Guile's
+@code{(ice-9 getopt-long)}. The extra keys which can be specified on
+an option are
+
+@table @samp
+@item (description string)
+A propper description of the value. Should be written for human
+consumption.
+
+@item (value value-spec)
+Value is from the core library, but here ...
+@c TODO document me
+@end table
+
+@defun getopt-opt options
+Remove extensions from @var{options}, turning it into a structure
+which can be passed to @code{getopt-long}.
+@end defun
+
+@defun format-arg-help options
+Pretty print an option summary.
+
+Each description will be parsed as XML and then fed through our markup
+system @xref{Markup}.
+@end defun
+
+@defun print-arg-help options [port=(current-error-port)]
+Formats and prints option spec.
+@end defun
diff --git a/doc/ref/guile/srfi-41.texi b/doc/ref/general/srfi-41.texi
index 8c65b6eb..d8020ecc 100644
--- a/doc/ref/guile/srfi-41.texi
+++ b/doc/ref/general/srfi-41.texi
@@ -39,7 +39,7 @@ was found.
@end defun
-@defun stream-remave pred stream
+@defun stream-remove pred stream
Stream-filter, but with predicate negated.
@end defun
@@ -73,6 +73,26 @@ times.
stream cons, but eval arguments beforehand.
@end defun
+@defun stream-split-by pred strm
+Chunks the content of @var{strm} into lists, breaking on @var{pred}.
+If the end of the stream is reached, the remaining objects
+are put into a final chunk.
+
+Can for example be used to split a stream of characters into a stream
+of words.
+
+@lisp
+(stream-split-by (lambda (c) (char=? c #\space))
+ (-> "This is a short test"
+ string->list list->stream))
+⇒ #<stream (#\T #\h #\i #\s #\space)
+ (#\i #\s #\space)
+ (#\a #\space)
+ (#\s #\h #\o #\r #\t #\space)
+ (#\t #\e #\s #\t)>
+@end lisp
+@end defun
+
@defun stream-timeslice-limit stream timeslice
Wrap a stream in time limits. Each element has at most @var{timeslice}
seconds to produce a value, otherwise the stream ends. Useful for finding the
diff --git a/doc/ref/guile/sxml.texi b/doc/ref/general/sxml.texi
index dd635b4c..dd635b4c 100644
--- a/doc/ref/guile/sxml.texi
+++ b/doc/ref/general/sxml.texi
diff --git a/doc/ref/guile/util-config.texi b/doc/ref/general/util-config.texi
index 2e197bcc..2e197bcc 100644
--- a/doc/ref/guile/util-config.texi
+++ b/doc/ref/general/util-config.texi
diff --git a/doc/ref/general/util-exceptions.texi b/doc/ref/general/util-exceptions.texi
new file mode 100644
index 00000000..34ba33f9
--- /dev/null
+++ b/doc/ref/general/util-exceptions.texi
@@ -0,0 +1,40 @@
+@node Exception & Warning Utilities
+@section Exception & Warning Utilities
+@anchor{warning}
+
+Warnings are like exceptions, but only fatal when wanted.
+
+@code{(hnh util exceptions)}
+
+@defun warning fmt args ...
+Emit a warning.
+
+If the parameter @var{warnings-are-errors} is true, then an exception
+of type @code{'warning} will be raised, with @var{fmt} and @var{args}
+as arguments.
+
+If that parameter is false, then the procedure in
+@var{warning-handler} will instead be called.
+@end defun
+
+@deftp {parameter} warning-handler
+Parameter containing proceudre which will be called for non-throwing
+warnings. This procedure is assumed by the program to log the warning
+in some way, and continue program flow. But anything goes.
+
+The procedure is given a format specifier (as per Scheme's basic
+@code{format}), along with the correct number of arguments.
+@end deftp
+
+@deftp {parameter} warnings-are-errors
+Boolean parameter, which if set causes warnings to be thrown as exceptions.
+@end deftp
+
+@defun fatal fmt args ...
+Display the message in fmt, populated with args, then raises the UNIX
+signal SIGINT, which kills the program.
+@end defun
+
+@defun filter-stack pred? stack
+@c TODO document me
+@end defun
diff --git a/doc/ref/guile/util-object.texi b/doc/ref/general/util-object.texi
index ceac2f2a..ceac2f2a 100644
--- a/doc/ref/guile/util-object.texi
+++ b/doc/ref/general/util-object.texi
diff --git a/doc/ref/guile/util-path.texi b/doc/ref/general/util-path.texi
index 9cf41b40..ba78a828 100644
--- a/doc/ref/guile/util-path.texi
+++ b/doc/ref/general/util-path.texi
@@ -1,14 +1,19 @@
@node Path Utilities
@section Path Utilities
-Provided by the module @code{(hnh util path)}.
+An extended path library for Guile. This library builds upon the path
+utilities provided by @xref{File System,,,guile}, but adds
+manipulation procedures. These procedures should work no matter what
+the systems directory delimiter is, even though this documentation
+uses ``/'' for its examples.
+Provided by the module @code{(hnh util path)}.
@defun path-absolute? string
Alias of @code{absolute-file-name?} from Guile.
@end defun
-@defun path-append strings ...
+@defun path-append path paths ...
Joins all strings into a path, squeezing duplicated delimiters, but
ensuring that all delimiters that are needed are there.
diff --git a/doc/ref/guile/util-type.texi b/doc/ref/general/util-type.texi
index 104b00b3..104b00b3 100644
--- a/doc/ref/guile/util-type.texi
+++ b/doc/ref/general/util-type.texi
diff --git a/doc/ref/guile/util.texi b/doc/ref/general/util.texi
index 1d35e0bf..1d6a4e7a 100644
--- a/doc/ref/guile/util.texi
+++ b/doc/ref/general/util.texi
@@ -1,5 +1,8 @@
-@node General Utilities
-@section General Utilities
+@node Miscellaneous utilities
+@section Miscellaneous utilities
+
+A kitchen sink utility library. Note should be taken that some core
+procedures and forms are replaced, but all in compatible ways.
Provided by the module @code{(hnh util)}.
@@ -34,8 +37,8 @@ our extra specialized @var{when}}, but binds the return of
@defmacx for (key ...) in collection body ...
Syntactic sugar over @code{map}.
@example
-for x in collection
- body ...
+(for x in collection
+ body ...)
@end example
expands into
@example
@@ -44,6 +47,17 @@ expands into
If keys are a list, an match-lambda is used instead.
@xref{Pattern Matching,,,guile}
+
+@defun break args ...
+Abandon the entire loop. Returing what was given to @code{break}.
+@end defun
+
+@defun continue [arg]
+Abandon the current iteration of the loop. If an argument is given,
+it's used as the result in the resulting list, otherwise @code{#f} is
+used.
+@end defun
+
@end defmac
@@ -322,6 +336,9 @@ Converts @var{any} to a string, as per @var{display}.
@defmac let-env bindings body ...
Similar to @var{let}, but sets environment variables for the code in
body. Restores the old values once we leave.
+
+A variable can also be removed from the environment, by setting its
+value to @code{#f}.
@end defmac
@defmac with-locale1 category locale thunk
@@ -338,51 +355,20 @@ innermost.
then @code{with-throw-handler} is used instead of @code{catch}.
@end defmac
-@subsection UUID generation
+@defun uniq lst
+@defunx univ lst
+@defunx unique lst
+@defunx uniqx comp lst
+Squash repeated equivalent elements in a list into single instances,
+similar to the POSIX command uniq(1). The three variants uses
+@code{eq?}, @code{eqv?}, and @code{equal?} respectively.
-Provided by module @code{(hnh util uuid)}.
-
-@defun uuid-v4
-Generates a UUID-v4 string.
-@end defun
-
-@defun uuid
-Generates an implementation defined (but guaranteed valid) UUID.
+@code{uniqx} also takes @var{comp}, which is sholud be a binary
+procedure returning if the elements are equal.
@end defun
-@subsection IO
-
-Provided by module @code{(hnh util io)}.
-
-@defun open-input-port path
-@defunx open-output-port path
-Like @code{open-*-file}, but ``-'' gives @code{standard-@{input,output@}}.
-@end defun
-
-@defun read-lines port
-Return a list of all lines read from port.
-@end defun
-
-@defun with-atomic-output-to-file filename thunk
-Same functionality as the regular @var{with-output-to-file}, but
-with the difference that either everything is written, or nothing
-is written, and if anything is written it's all written atomicaly at
-once (the original file will never contain an intermidiate state).
-Does NOT handle race conditions between threads.
-
-propagates the return value of @var{thunk} upon successfully writing
-the file, and @code{#f} otherwise.
-@end defun
-
-@defun call-with-tmpfile proc [#:tmpl ``/tmp/file-XXXXXXX'']
-@end defun
-
-@defun ->port port-or-strings
-If @var{port-or-string} is a port, return it directly. If it's a
-string, instead return an input string containing the strings content.
-@end defun
-
-@c Is this even a procedure?
-@defun read-file path
-Open file at path, and return its content as a string.
-@end defun
+@defmac begin1 forms ...
+Port of Common Lisp's @code{begin1} form. Like @code{begin} runs each
+form in its body in order, but returns the first result instead of the
+last.
+@end defmac
diff --git a/doc/ref/general/uuid.texi b/doc/ref/general/uuid.texi
new file mode 100644
index 00000000..78674763
--- /dev/null
+++ b/doc/ref/general/uuid.texi
@@ -0,0 +1,17 @@
+@node UUIDs
+@section UUID generation
+
+Provided by module @code{(hnh util uuid)}.
+
+@defun uuid-v4
+Generates a UUID-v4 string.
+@end defun
+
+@defun uuid
+Generates an implementation defined (but guaranteed valid) UUID.
+@end defun
+
+@deftp {parameter} seed
+Guile parameter containing the seed used when generating UUID's in
+this module. Only set this when you want non-random randomness.
+@end deftp
diff --git a/doc/ref/guile/webdav.texi b/doc/ref/general/webdav.texi
index a495c945..a495c945 100644
--- a/doc/ref/guile/webdav.texi
+++ b/doc/ref/general/webdav.texi
diff --git a/doc/ref/general/xdg-basedir.texi b/doc/ref/general/xdg-basedir.texi
new file mode 100644
index 00000000..2d3b2972
--- /dev/null
+++ b/doc/ref/general/xdg-basedir.texi
@@ -0,0 +1,62 @@
+@node XDG Base Directory
+@section XDG Base Directory
+
+Implementation of the XDG Base Directory Specification
+@url{https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html}, v0.8.
+
+It's recommended to include this module with a symbol prefix:
+
+@example
+(use-modules ((xdg basedir) :prefix xdg-)
+
+(xdg-data-dirs)
+⇒ ("/usr/local/share" "/usr/share")
+@end example
+
+The users home directory is fetched from the environment variable @env{HOME}.
+
+
+@defun data-home
+@findex XDG_DATA_HOME
+@env{XDG_DATA_HOME}, usually @file{~/.local/share}.
+@end defun
+
+@defun config-home
+@findex XDG_CONFIG_HOME
+@env{XDG_CONFIG_HOME}, usually @file{~/.config}.
+@end defun
+
+@defun state-home
+@findex XDG_STATE_HOME
+@env{XDG_STATE_HOME}, usually @file{~/.local/state}.
+@end defun
+
+@defun data-dirs
+@findex XDG_DATA_DIRS
+@env{XDG_DATA_DIRS}, split into a list.
+
+Defaults to @code{("/usr/local/share" "/usr/share")}.
+@end defun
+
+@defun config-dirs
+@findex XDG_CONFIG_DIRS
+@env{XDG_CONFIG_DIRS} as a list, usually @code{("/etc/xdg")}.
+
+Defaults to @file{/etc/xdg}.
+@end defun
+
+@defun cache-home
+@findex XDG_CACHE_HOME
+@env{XDG_CACHE_HOME}, usually @file{~/.cache}.
+@end defun
+
+@defun runtime-dir
+@findex XDG_RUNTIME_DIR
+If @env{XDG_RUNTIME_DIR} is set, than that is used. Otherwise a
+warning message is printed to stderr and @file{/tmp} is returned.
+
+The standard also stipulates a few things about permissons for this
+directory. These are currently not checked.
+
+Systemd usually sets this value to @file{/run/user/$(id -u)}.
+@end defun
diff --git a/doc/ref/guile/zic.texi b/doc/ref/general/zic.texi
index 5af36fd3..5af36fd3 100644
--- a/doc/ref/guile/zic.texi
+++ b/doc/ref/general/zic.texi
diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi
deleted file mode 100644
index cb3d8475..00000000
--- a/doc/ref/guile.texi
+++ /dev/null
@@ -1,192 +0,0 @@
-@node Guile
-@chapter Guile
-
-@include guile/data-formats.texi
-@include guile/data-stores.texi
-@include guile/datetime.texi
-@include guile/zic.texi
-@include guile/srfi-41.texi
-@include guile/util.texi
-@include guile/util-path.texi
-@include guile/util-config.texi
-@include guile/util-type.texi
-@include guile/util-object.texi
-@include guile/lens.texi
-@include guile/base64.texi
-@include guile/web.texi
-@include guile/vcomponent.texi
-@include guile/sxml.texi
-@include guile/webdav.texi
-
-@node Errors and Conditions
-@section Errors and Conditions
-
-@subsection ``Special'' Errors
-
-@deftp{Error type} return
-Thrown in some sub-mains to quickly return from the sub-function.
-Should possibly be replaced by an explicit return-continuation.
-@end deftp
-
-@deftp{Error type} warning fmt args
-Thrown when @code{warnings-are-errors} is true.
-@end deftp
-
-@deftp{Error type} max-page page-number
-@end deftp
-
-@subsection ``Regular'' Errors
-All below mentioned error types behave as expected, e.g., they are
-produced through @code{scm-error}.
-
-@deftp{Error Type} configuration-error
-Thrown by (calp util config), in some scenarios.
-@TODO{Better documentation}
-@end deftp
-
-@deftp{Error Type} c-parse-error
-Errors thrown by our make-shift C parser.
-@end deftp
-
-@deftp{Error Type} decoding-error
-thrown by base64 in some cases
-@end deftp
-
-@deftp{Error Type} parse-error
-Thrown by some things related to parsing, but not all.
-@TODO{normalize parsing errors further}
-@end deftp
-
-@deftp{Error Type} graph-error
-The first element of data is guaranteed to be the graph which caused
-the error.
-@end deftp
-
-@deftp{Error Type} missing-helper
-A helper program we wanted was missing, could be resolved by somehow
-downloading it into one of the searched locations.
-
-@example
-data : (program-name : string)
- , (searched-locations : (list string))
-@end example
-@end deftp
-
-
-
-@node Other
-@section Other
-
-@defun get-parser type
-@example
-get-parser ∷ type-name → hash-table x string → any
-type = 'BINARY | 'BOOLEAN | 'CAL-ADDRES | 'DATE | 'DATE-TIME
- | 'DURATION | 'FLOAT | 'INTEGER | 'PERIOD | 'RECUR
- | 'TEXT | 'TIME | 'URI | 'UTC-OFFSET
-@end example
-
-@ref{ical-get-writer}
-@end defun
-
-@subsection formats ical
-@subsubsection output
-
-@defun component->ical-string component
-@end defun
-
-@defun print-components-with-fake-parent events
-@end defun
-
-@defun print-all-events
-@end defun
-
-@defun print-events-in-interval start end
-@end defun
-
-@subsubsection parse
-
-@defun parse-calendar port
-@end defun
-
-@subsubsection types
-
-@defun escape-chars str
-Escape @code{,}, @code{;} and @code{\} with a
-backslash, and encode newlines as @code{\n}.
-@end defun
-
-@defun get-writer type
-@anchor{ical-get-writer}
-@example
-get-writer ∷ type-name → hash-table x value → string
-type = 'BINARY | 'BOOLEAN | 'CAL-ADDRES | 'DATE | 'DATE-TIME
- | 'DURATION | 'FLOAT | 'INTEGER | 'PERIOD | 'RECUR
- | 'TEXT | 'TIME | 'URI | 'UTC-OFFSET
-@end example
-@end defun
-
-@subsection formats vdir
-@subsubsection parse
-
-@defun parse-vdir path
-@end defun
-
-@subsubsection save-delete
-
-@defun save-event event
-@end defun
-
-@defun remove-event event
-@end defun
-
-@subsection formats xcal
-@subsubsection output
-
-@defun vcomponent->sxcal component
-@end defun
-
-@defun ns-wrap
-@lisp
-(define (ns-wrap sxml)
- `(icalendar (@@ (xmlns "urn:ietf:params:xml:ns:icalendar-2.0"))
- ,sxml))
-@end lisp
-Where @var{sxml} is expected to be the output of @var{vcomponent->sxcal}.
-@end defun
-
-@subsubsection parse
-@defun sxcal->vcomponent sxcal
-Parses a vcomponent in sxcal format. Requires that the vcomponent is
-the root of the document (fragment), so wrapping icalendar-tags or
-similar @emph{must} be removed.
-
-@example
-(vcalendar
- (properties ...)
- (components ...))
-@end example
-@end defun
-
-@subsubsection types
-@defun get-writer type
-@ref{ical-get-writer}
-@end defun
-
-
-@c --------------------------------------------------
-
-@c TODO
-This chapter will probably in the future be replaced by a proper
-system overview in the future.
-
-@c module (vcomponent control)
-
-@defmac with-replaced-properties (component (key value) ...) body ...
-Through the extent of @var{body} each @var{key}'s value in
-@var{component} is replaced by its repspective @var{value}.
-
-Note that @var{body} is guarded through a dynamic-wind, meaning that
-even non-local exits will restore @var{component} to its initial
-state.
-@end defmac
-
diff --git a/doc/ref/introspection.texi b/doc/ref/introspection.texi
new file mode 100644
index 00000000..9c8387d2
--- /dev/null
+++ b/doc/ref/introspection.texi
@@ -0,0 +1,84 @@
+@node Module Introspection
+@chapter Guile Module Introspection
+
+These are various procedures for getting information about modules,
+usually in a static (only looking at ``dead'' source code) way. They
+are currently strewn about a couple files, all under
+@file{hnh/module-introspection}.
+
+TODO rework the file structure.
+
+TODO the all-*-under-directory procedures really need to be
+straightened out.
+
+@defun module-uses* forms
+Find all dependencies of a module by statically analyzing it's source code.
+
+It gives worse resluts than Guile's built in @code{module-uses}, but
+has the benefit that a module which doesn't compile can still be checked.
+
+@var{froms} should be a list gotten by repeateadly calling @code{read}
+on a Scheme source file.
+@end defun
+
+@defun unique-symbols tree
+Return a list of all symbols occuring in @var{tree}. Each symbol is
+noted exactly once, anything which isn't a symbol is discarded.
+@end defun
+
+@defun module-declaration? form
+Checks if @var{form} starts with @code{'define-module}.
+@end defun
+
+@defun find-module-declaration forms
+@anchor{find-module-declaration}
+In a list of forms, find the first one which satisfies @code{module-declarations?}.
+@end defun
+
+@defun get-forms port
+Repeatadly call @code{read} on @var{port}, and return a list of the
+read forms in order of occurence in the file.
+@end defun
+
+@defun all-files-and-modules-under-directory dir
+Like @code{all-modules-under-directory}, but returns 2-lists of
+filename + module name.
+@end defun
+
+@defun all-files-under-directory directory extension
+Return a flat list of all ``regular'' files under @var{directory},
+whose end in @var{extension}.
+
+@example
+(all-files-under-directory "module" ".scm)
+⇒ '("module/hnh/util.scm")
+@end example
+@end defun
+
+@defun all-modules-under-directory directory
+Finds all ``.scm'' files under @var{directory}, and then read them to
+find a module declaration @pref{find-module-declaration}. Returns both
+the list of all the files, as well as all modules found, as a list of
+module lists, each one suitable to be sent to
+@code{reslove-interface}.
+
+Scheme files without a module declaration are not included in the
+result.
+@end defun
+
+@defun fs-find dir
+Find all files under @var{dir}. This includes all file types,
+including directories.
+
+@example
+(fs-find "module")
+;; Would return something on the following form:
+⇒ `(("module/hnh/util.scm" ,(stat "module/hnh/util.scm") regular)
+ ("module/hnh" ,(stat "module/hnh") directory)
+ ("module" ,(stat "module") directory)
+ ...)
+@end example
+@end defun
+
+@defun module-file-mapping dir
+@end defun
diff --git a/doc/ref/javascript.texi b/doc/ref/javascript.texi
deleted file mode 100644
index bbe1cb25..00000000
--- a/doc/ref/javascript.texi
+++ /dev/null
@@ -1,48 +0,0 @@
-@node Javascript
-@chapter Javascript
-
-@c web components
-@defindex wc
-
-@c done
-@node General Stuff
-@section General stuff
-The frontend code has its entry-point in @code{script.ts}
-
-All elements are initialized in elements.ts
-
-@include javascript/clock.texi
-@include javascript/lib.texi
-@include javascript/eventCreator.texi
-@include javascript/types.texi
-@include javascript/vevent.texi
-@include javascript/globals.texi
-@include javascript/server_connect.texi
-@include javascript/formatters.texi
-@include javascript/user-additions.texi
-
-@node General Components
-@section General Components
-@include javascript/components/date_time_input.texi
-@include javascript/components/input_list.texi
-
-@node VEvent Components
-@section VEvent Components
-@include javascript/components/vevent.texi
-@include javascript/components/changelog.texi
-@include javascript/components/edit_rrule.texi
-@include javascript/components/popup_element.texi
-@include javascript/components/tab_group_element.texi
-@include javascript/components/vevent_block.texi
-@include javascript/components/vevent_description.texi
-@include javascript/components/vevent_dl.texi
-@include javascript/components/vevent_edit.texi
-
-@section About our buildsystem
-Currently (almost) everything is written in Typescript, and bundled
-through browserify. Ideally we would, for debug builds, export the
-single transplied Javascript files, but Chromium Chromium lacks
-support for modules on XHTML documents
-@url{https://bugs.chromium.org/p/chromium/issues/detail?id=717643}.
-However, seeing as the issue still gets frequent updates as of 2021 I
-believe that this might one day get resolved.
diff --git a/doc/ref/javascript/clock.texi b/doc/ref/javascript/clock.texi
deleted file mode 100644
index 10ab7d4e..00000000
--- a/doc/ref/javascript/clock.texi
+++ /dev/null
@@ -1,78 +0,0 @@
-@node clock
-@subsection clock.js
-
-@deftp {abstract class} Clock
-Interface for ``things'' which wants to get updated on a human timescale.
-
-@defmethod Clock update now
-@c abstract method
-Called every now and then, with @var{now} being the current time.
-@end defmethod
-@end deftp
-
-@deftp {class} Timebar @extends{Clock}
-The (blue) vertical line which show the current time in the current day.
-
-@c @defmethod Timebar constructor ∅
-@c @end defmethod
-@c
-@c @defmethod Timebar update now
-@c @end defmethod
-@end deftp
-
-@deftp {class} SmallcalCellHighlight @extends{Clock}
-Highlights the current date in the small calendar to the side.
-Currently directly sets a border
-@TODO{but should preferably set a class instead}.
-
-@defmethod SmallcalCellHighlight constructor small_cal
-@var{small_cal} is the DOM-node of the calendar.
-(it should support querySelector).
-@end defmethod
-
-@c @defmethod SmallcalCellHighlight update now
-@c @end defmethod
-@end deftp
-
-@deftp {class} ButtonUpdater @extends{Clock}
-Updates the ``Today'' link in the side panel to point directly to the
-correct web-address. The link works without JavaScript, but then
-requires a redirect from the server.
-
-All actual updating logic is already abstracted away. It would be
-desirable if something more was done with this.
-
-@defmethod ButtonUpdater el proc
-Takes the element @var{el} to be updated, and the procedure @var{proc}
-which will be called with the element, and the current time.
-@end defmethod
-@end deftp
-
-
-As of commit
-@githash{c9719ce7937f0f0f2aa371ced1d585f67af22457,static/script.js,231}
-all objects required manual setup. See static/script.js:
-
-@verbatim
- 231 let start_time = document.querySelector("meta[name='start-time']").content;
- 232 let end_time = document.querySelector("meta[name='end-time']").content;
- 233
- 234 const button_updater = new ButtonUpdater(
- 235 document.getElementById("today-button"),
- 236 (e, d) => e.href = d.format('~Y-~m-~d') + ".html"
- 237 );
- 238
- 239 const sch = new SmallcalCellHighlight(
- 240 document.querySelector('.small-calendar'))
- 241
- 242 const timebar = new Timebar(start_time, end_time);
- 243
- 244 timebar.update(new Date);
- 245 window.setInterval(() => {
- 246 let d = new Date;
- 247 timebar.update(d);
- 248 button_updater.update(d);
- 249 sch.update(d);
- 250 }, 1000 * 60);
- 251
-@end verbatim
diff --git a/doc/ref/javascript/components/changelog.texi b/doc/ref/javascript/components/changelog.texi
deleted file mode 100644
index d14fb84e..00000000
--- a/doc/ref/javascript/components/changelog.texi
+++ /dev/null
@@ -1,10 +0,0 @@
-@subsection Changelog
-
-@deftp {Web Component for VEvent} VEventChangelog
-@wcindex <vevent-changelog>
-@wcindex vevent-changelog
-@anchor{VEventChangelog}
-@code{<vevent-changelog>}
-
-Display of a VEvents changelog. @ref{ChangeLogEntry}
-@end deftp
diff --git a/doc/ref/javascript/components/date_time_input.texi b/doc/ref/javascript/components/date_time_input.texi
deleted file mode 100644
index f26627d2..00000000
--- a/doc/ref/javascript/components/date_time_input.texi
+++ /dev/null
@@ -1,34 +0,0 @@
-@subsection date-time-input
-
-@deftp {Web Component} DateTimeInput
-@wcindex <date-time-input>
-@wcindex date-time-input
-@code {<date-time-input>}
-
-An element for input for date-times. Similar to
-@example
-<input type="date"/>
-<input type="time"/>
-@end example
-But as a single unit.
-
-@deftypeivar DateTimeInput boolean dateonly
-Setting this to true disabled the time part of the input, and makes
-any output only have date components (alternativly, the time component
-set to zero).
-@end deftypeivar
-
-@defcv {Attribute} DateTimeInput dateonly
-Same data as the field dateonly, but as an attribute. Present means
-true, absent means false.
-@end defcv
-
-@deftypeivar DateTimeInput Date value
-Returns current value as a Date object.
-@end deftypeivar
-
-@deftypeivar DateTimeInput string stringValue
-Returns current value as an ISO-8601 formatted string.
-@end deftypeivar
-
-@end deftp
diff --git a/doc/ref/javascript/components/edit_rrule.texi b/doc/ref/javascript/components/edit_rrule.texi
deleted file mode 100644
index 21437863..00000000
--- a/doc/ref/javascript/components/edit_rrule.texi
+++ /dev/null
@@ -1,10 +0,0 @@
-@subsection Edit RRule
-
-@deftp {Web Component for VEvent} EditRRule
-@wcindex <vevent-edit-rrule>
-@wcindex vevent-edit-rrule
-@code{<vevent-edit-rrule>}
-
-An edit form for a recurrence rule. Searches its template for elements
-with @code{[name="<<field name>>"]}, and binds to those.
-@end deftp
diff --git a/doc/ref/javascript/components/input_list.texi b/doc/ref/javascript/components/input_list.texi
deleted file mode 100644
index bdc00ecb..00000000
--- a/doc/ref/javascript/components/input_list.texi
+++ /dev/null
@@ -1,16 +0,0 @@
-@subsection input_list.js
-
-@deftp {Web Component} InputList
-@wcindex <input-list>
-@wcindex input-list
-@code{<input-list>}
-
-A list of identical input fields, which forms a group. For example
-useful to handle keywords.
-
-@deftypeivar DateTimeInput {any[]} value
-The value from each element, except the last which should always be empty.
-Has an unspecified type, since children:s value field might give non-strings.
-@end deftypeivar
-
-@end deftp
diff --git a/doc/ref/javascript/components/popup_element.texi b/doc/ref/javascript/components/popup_element.texi
deleted file mode 100644
index 2b76b347..00000000
--- a/doc/ref/javascript/components/popup_element.texi
+++ /dev/null
@@ -1,40 +0,0 @@
-@subsection Popup
-
-@deftp {Web Component for VEvent} PopupElement
-@wcindex <popup-element>
-@wcindex popup-element
-@code{<popup-element>}
-
-A (small) floating window containing information, which can be dragged
-arround. Consists of a navigation bar with a few buttons for
-controlling the window, which also works as a drag handle, along with
-an area for contents, which can be resized by the user.
-
-Currently tightly coupled to VEvent's, since their color
-profile is derived from their owning events calendar, and they have
-action buttons for the event in their navigation bar.
-
-@deftypecv {Static Member} PopupElement {PopupElement?} activePopup
-The popup which was most recently interacted with by the user. Used to
-move it on top of all others, as well as sending relevant key events there.
-@end deftypecv
-
-@defcv {Attribute} PopupElement visible
-Present is the popup is currently visible, absent otherwise.
-@end defcv
-
-@deftypeivar PopupElement boolean visible
-See the attribute of the same name.
-@end deftypeivar
-
-@defmethod PopupElement maximize
-Resize the popup window to fill the current viewport (mostly). Is
-probably bonud to the maximize button in the navigation bar.
-@end defmethod
-@end deftp
-
-@deftypefun PopupElement setup_popup_element VEvent
-Create a new popup element for the given VEvent, and ready it for
-editing the event. Used when creating event (through the frontend).
-The return value can safely be ignored.
-@end deftypefun
diff --git a/doc/ref/javascript/components/tab_group_element.texi b/doc/ref/javascript/components/tab_group_element.texi
deleted file mode 100644
index 7e0b190a..00000000
--- a/doc/ref/javascript/components/tab_group_element.texi
+++ /dev/null
@@ -1,46 +0,0 @@
-@subsection Tab Group Element
-
-@deftp {Web Component for VEvent} TabGroupElement
-@wcindex <tab-group>
-@wcindex tab-group
-@code{<tab-group>}
-
-A group of tabs, where only one can be visible at a time.
-
-@c TODO which form does the HTML document have? For CSS purposes
-
-Each tab consists of two parts, a label which is used for selecting
-it, and a tab-element, which contains the actual content. These two
-should refer to each other as follows:
-
-@example
-+---------------+ +-----------------+
-| TabLabel | | Tab |
-+---------------+ +-----------------+
-| id |<----| aria-labelledby |
-| aria-controls |---->| id |
-+---------------+ +-----------------+
-@end example
-
-Further information about tabs in HTML can be found here:
-@url{https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role}
-
-@defvr {CSS Variable} {--tabcount}
-Each tab element has the style property @code{--tabcount} set to how
-many tabs it has. This is mostly useful to make sure the tab context
-is large enough to fit all tab labels without overflowing.
-@end defvr
-
-@deftypemethod TabGroupElement void addTab {HTMLElement} {label: string?} {title: string?}
-Adds a new tab to the group. The first parameter will make up the body
-of the tab. The label is whath should be shown in the tab selector,
-but defaults to the first letter of the text content of the body node.
-Title is the hoover text of the label.
-@end deftypemethod
-
-@deftypemethod TabGroupElement void removeTab {HTMLElement}
-HTMLElement must be one of the tab bodies in this group. This method
-removes it, along with its TabLabel.
-@end deftypemethod
-
-@end deftp
diff --git a/doc/ref/javascript/components/vevent.texi b/doc/ref/javascript/components/vevent.texi
deleted file mode 100644
index be53a46e..00000000
--- a/doc/ref/javascript/components/vevent.texi
+++ /dev/null
@@ -1,23 +0,0 @@
-@subsection vevent
-
-@deftp {Abstract Web Component} ComponentVEvent {uid: string?}
-
-@c TODO what is done in the default constructor,
-@c and the default connectedCallback
-
-This registeres itself, but doesn't redraw
-We do however redraw in connectedCallback
-
-@deftypeivar ComponentVEvent uid uid
-@end deftypeivar
-
-@deftypeivar ComponentVEvent {HTMLTemplateElement?} template
-@end deftypeivar
-
-@deftypemethod ComponentVEvent void redraw (data: VEvent)
-While abstract for this, @emph{must} be overridden for everyone else
-@end deftypemethod
-@end deftp
-
-Note that many of these assume that their initial children are
-configured specifically, that is however not completely documented.
diff --git a/doc/ref/javascript/components/vevent_block.texi b/doc/ref/javascript/components/vevent_block.texi
deleted file mode 100644
index 1a0ef160..00000000
--- a/doc/ref/javascript/components/vevent_block.texi
+++ /dev/null
@@ -1,10 +0,0 @@
-@subsection VEvent Block
-
-@deftp {Web Component for VEvent} ComponentBlock
-@wcindex <vevent-block>
-@wcindex vevent-block
-@code{<vevent-block>}
-A block in our graphical view.
-
-Unique in that it works quite differently between the week and month view.
-@end deftp
diff --git a/doc/ref/javascript/components/vevent_description.texi b/doc/ref/javascript/components/vevent_description.texi
deleted file mode 100644
index 54dda7e3..00000000
--- a/doc/ref/javascript/components/vevent_description.texi
+++ /dev/null
@@ -1,16 +0,0 @@
-@subsection VEvent Description
-
-@deftp {Web Component for VEvent} ComponentDescription
-@wcindex <vevent-description>
-@wcindex vevent-description
-@code{<vevent-description>}
-
-A text representation of a VEvent. Used as the summary tab of our
-popup windows, and in the sidebar.
-
-When redrawn, it looks for an HTML-tag inside its template having the
-attribute @code{data-property} matching the properties name. If one is
-found, it looks in the @code{formatters} table
-(@ref{formatters-proc}), for a field matching the property value, and
-defaults to the key @code{default}.
-@end deftp
diff --git a/doc/ref/javascript/components/vevent_dl.texi b/doc/ref/javascript/components/vevent_dl.texi
deleted file mode 100644
index 26bc8fd4..00000000
--- a/doc/ref/javascript/components/vevent_dl.texi
+++ /dev/null
@@ -1,11 +0,0 @@
-@subsection VEvent Description List
-
-@deftp {Web Component for VEvent} VEventDL
-@wcindex <vevent-dl>
-@wcindex vevent-dl
-@code{<vevent-dl>}
-A description list of a vevent, used for debugging.
-
-No guarantees are given about the contents of the data fields, more
-than that they are related to the value in question.
-@end deftp
diff --git a/doc/ref/javascript/components/vevent_edit.texi b/doc/ref/javascript/components/vevent_edit.texi
deleted file mode 100644
index 67e9f6b3..00000000
--- a/doc/ref/javascript/components/vevent_edit.texi
+++ /dev/null
@@ -1,9 +0,0 @@
-@subsection VEvent Edit
-
-@deftp {Web Component for VEvent} ComponentEdit
-@wcindex <vevent-edit>
-@wcindex vevent-edit
-@code{<vevent-edit>}
-Edit form for a vevent, designed for useful human interaction (and
-thereby not being all-encompassing).
-@end deftp
diff --git a/doc/ref/javascript/eventCreator.texi b/doc/ref/javascript/eventCreator.texi
deleted file mode 100644
index 164d1335..00000000
--- a/doc/ref/javascript/eventCreator.texi
+++ /dev/null
@@ -1,15 +0,0 @@
-@deftp {class} EventCreator
-
-@defmethod EventCreator create_empty_event
-@end defmethod
-
-@defmethod EventCreator create_event_down intended_target
-@end defmethod
-
-@defmethod EventCreator create_event_move pos_in [round=1] [wide_element=false]
-@end defmethod
-
-@defmethod EventCreator create_event_finisher callback
-@end defmethod
-
-@end deftp
diff --git a/doc/ref/javascript/formatters.texi b/doc/ref/javascript/formatters.texi
deleted file mode 100644
index a3086aa9..00000000
--- a/doc/ref/javascript/formatters.texi
+++ /dev/null
@@ -1,23 +0,0 @@
-@node formatters
-@subsection formatters
-
-Formatting procedures used by some components.
-@c TODO can we have a backref of every node containing @ref{formatters-proc}?
-
-@deftypefun void format(targetElement:HTMLElement, data:VEvent, key:string)
-Checks if a specific formatter exists for the given key, and executes
-it.
-Defaults to 'default', and also runs that if the regular formatter throws.
-@end deftypefun
-
-@deftypevar {Map<string, (e:HTMLElement, d:VEvent, s:any) => void>} formatters
-@anchor{formatters-proc}
-
-Each procedure takes three arguments. The HTML-element which contents
-should be replaced, the VEvent containing all data, and the target
-value, as returned by @ref{VEvent.getProperty}.
-@end deftypevar
-
-@deftypevr {Window Value} {Map<string, (e:HTMLElement, d:VEvent, s:string) => void>} formatters
-Same object as @xref{formatters-proc}. Provided for @xref{user-additions.js}.
-@end deftypevr
diff --git a/doc/ref/javascript/globals.texi b/doc/ref/javascript/globals.texi
deleted file mode 100644
index 5ef7a43b..00000000
--- a/doc/ref/javascript/globals.texi
+++ /dev/null
@@ -1,41 +0,0 @@
-@node globals
-@subsection globals.ts
-
-Different variables and values which for different reasons needs to be
-global. Window Value's are those that are bound to the @code{window}
-context in JavaScript, so is really always available, no opt out.
-
-@deftypevar {Map<uid, VEvent>} vcal_objects
-All VEvent objects on current page, indexed by their unique identifiers.
-
-A global object store.
-@end deftypevar
-
-@deftypevar {Map<uid, string>} event_calendar_mapping
-Mapping from VEvent unique identifier, to name of its calendar. Should
-probably not be global, so refrain from using it.
-@end deftypevar
-
-@deftypevr {Window Value} {Map<uid, VEvent>} vcal_objects
-The exact same object store as the regular variable of the same
-name. Mostly here for human debugability.
-@end deftypevr
-
-@deftypevr {Window Value} {@code{'month'} | @code{'string'}} VIEW
-How the calendar is currently formatted. Should be set by the backend
-through a simple @code{script}-tag.
-@end deftypevr
-
-@deftypevr {Window Value} {boolean} EDIT_MODE
-However editing of events is enabled or not.
-Should be set by the backend through a simple @code{script}-tag.
-@end deftypevr
-
-@deftypevr {Window Value} {string} default_calendar
-Name of the calendar to assume when creating new events.
-Should be set by the backend through a simple @code{script}-tag.
-@end deftypevr
-
-@c TODO addNewEvent
-@c @deftypevr {Window Value} {string} default_calendar
-@c @end deftypevr
diff --git a/doc/ref/javascript/jcal.texi b/doc/ref/javascript/jcal.texi
deleted file mode 100644
index 997b4d59..00000000
--- a/doc/ref/javascript/jcal.texi
+++ /dev/null
@@ -1,7 +0,0 @@
-@node jcal
-@subsection jcal.js
-
-@deftypefun Document jcal_to_xcal {JCal ...}
-A document with the xcal namespace, and @code{icalendar} as its root
-element. Each child is a valid xcal representation of our JCal object.
-@end deftypefun
diff --git a/doc/ref/javascript/lib.texi b/doc/ref/javascript/lib.texi
deleted file mode 100644
index a3fb0697..00000000
--- a/doc/ref/javascript/lib.texi
+++ /dev/null
@@ -1,148 +0,0 @@
-
-@node lib
-@subsection lib.js
-
-General procedures which in theory could be used anywhere.
-
-
-@node Default prototype extensions
-@subsubsection Default prototype extensions
-
-HTMLElement extensions
-
-@defmethod HTMLElement addEventListener name proc
-Replace the default @code{addEventListener} with a version that stores
-all listeners in the dictionary @var{listeners}.
-@end defmethod
-
-@defivar HTMLElement listeners
-Dictionary of all registered listeners to this element.
-Keys are taken from @code{addEventListener}.
-@end defivar
-
-@defmethod DOMTokenList find regexp
-Finds the first element of the DOMTokenList whichs value matches
-the supplied regexp. Returns a pair of the index and the value.
-@end defmethod
-
-@defmethod Object format args ...
-Returns a string representation of the given object.
-Allows extending for custom types,
-@ref{date-format}
-@end defmethod
-
-@node General
-@subsubsection General
-
-@defun zip args ...
-Takes a list of lists, and returns a single list of tuples.
-@example
-» zip([1,2,3,4,5], "Hello")
-← [[1,'H'],[2,'e'],[3,'l'],[4,'l'],[5,'o']]
-@end example
-@end defun
-
-@defun makeElement name [attr=@{@}]
-Creates a new DOM element of type @var{name}, with all keys in
-@var{attr} transfered to it. For example, the equivalent of
-@example
-<input type='number'/>
-@end example
-would be
-@verbatim
-values.push(makeElement('input', {
- type: 'number',
-}));
-@end verbatim
-.
-@end defun
-
-@defun round_time time fraction
-TODO
-@end defun
-
-@defun date_to_percent date
-Retuns how far along the date specified by @var{date} is, between 0
-and 100, where 00:00 maps to 0, and 23:59 to ~100.
-@end defun
-
-@defun gensym [pxrefix='gensym']
-Generates a new string which is (hopefully) globally unique.
-Compare with @code{gensym} from Lisp.
-@end defun
-
-@defun asList thing
-Ensures that @var{thing} is a list. Returning it outright if it
-already is one, otherwise wrapping it in a list.
-@end defun
-
-@node Date
-@subsubsection Date
-
-Some extensions to the builtin class ``Date'' is made.
-
-@defivar Date utc
-Boolean indicating if the given timestamp is in UTC or local time.
-true means UTC.
-@end defivar
-
-@defivar Date dateonly
-Boolean indicating if the time component of the Date object should be disregarded.
-@end defivar
-
-@defun parseDate str
-Takes a string @var{str}, which should be in ISO-8601 date-format, and
-returns a javascript Date object.
-Handles date-times, with and without seconds, trailing `Z' for
-time-zones, and dates without times.
-If no time is given the @code{dateonly} attribute is set to yes.
-@end defun
-
-@defun copyDate date
-Creates a new instance of the given Date @var{date}, also transfers my
-custom fields.
-@end defun
-
-@defun to_local date
-@anchor{to_local}
-Returns a Date object (which may be new) which is guaranteed in local
-time.
-This means that the @var{utc} field is @code{false}, and that
-@code{to_local(current_time())} should show what your wall-clock shows.
-@end defun
-
-@defmethod Date format str args ...
-@anchor{date-format}
-Formats a Date object according to the format specification @var{str}.
-Keeping with Guile each format specifier starts with a ~.
-
-@table @samp
-@item ~~
-literal ~
-@c Almost all fields are left padded. How do I signify this
-@c with a single footnote?
-@item ~Y
-year, left-padding with zeroes.
-@item ~m
-month number, left padded with zeroes.
-@item ~d
-day of month.
-@item ~H
-hour
-@item ~M
-minute
-@item ~S
-second
-@item ~Z
-'Z' if Date is UTC, otherwise nothing
-@item ~L
-Converts the date to local time
-(@pxref{to_local}) (doesn't modify source object). Outputs nothing
-@end table
-@end defmethod
-
-@defun format_date date str
-Equivalent to @code{(@var{date}).format(@var{str})}.
-@c TODO link
-@end defun
-
diff --git a/doc/ref/javascript/server_connect.texi b/doc/ref/javascript/server_connect.texi
deleted file mode 100644
index c67f47ff..00000000
--- a/doc/ref/javascript/server_connect.texi
+++ /dev/null
@@ -1,22 +0,0 @@
-@node server_connect
-@subsection server_connect.js
-
-Procedures for interfacing with the backend server.
-
-@deftypefn {Async Function} void create_event {event: VEvent}
-Packs up the given event and sends it to the server to either be
-created, or simply be updated in the persistant database.
-
-Also does some minor updates registered components, to show that the
-event is actually created.
-@end deftypefn
-
-@deftypefn {Async Function} void remove_event {uid: uid}
-Requests that the server permanently remove the event with the given
-unique id from its persistant storage.
-
-If the server responds with a success also delete it from our local
-store (@code{vcal_objects}).
-
-@c TODO link to our backend flow here
-@end deftypefn
diff --git a/doc/ref/javascript/types.texi b/doc/ref/javascript/types.texi
deleted file mode 100644
index 6f518f53..00000000
--- a/doc/ref/javascript/types.texi
+++ /dev/null
@@ -1,95 +0,0 @@
-@node types
-@subsection types.js
-
-Collection of type information for calendar data.
-
-@defvar all_types
-Name of all valid icalendar types.
-
- text, uri, binary, float, integer, date-time, date, duration,
- period, utc-offset, cal-address, recur, boolean,
-@end defvar
-
-@deftp {Data Type} ical_type
-The union of all elements in @var{all_types}.
-@end deftp
-
-@defvar property_names
-All known names properties (top level keys) can have.
-Such as ``calscale'', ``dtstart'', ...
-@end defvar
-
-@deftypevar {Map<string, string[]>} valid_fields
-Which property fields each component can hold.
-
-@verbatim
-{ 'VCALENDAR': ['PRODID', 'VERSION', 'CALSCALE', 'METHOD'],
- ...
-}
-@end verbatim
-@end deftypevar
-
-@deftypevar {Map<string, Array<ical_type | ical_type[]>>} valid_input_types
-Which types are valid to store under each property.
-If multiple values are an option for that property, then
-the list of possibilities will contain a sub-list (see example).
-
-@verbatim
-{ 'DTSTART': ['date', 'date-time'],
- 'CATEGORIES': [['text']],
- ...
-}
-@end verbatim
-@end deftypevar
-
-@deftp {Data Type} tagname
-Alias of (@code{'vevent'} | @code{'string'}).
-@end deftp
-
-@deftp {Data Type} uid
-Alias of @code{'string'}.
-@end deftp
-
-@c TODO link to the RFC
-@c - RFC 7265 (jCal)
-
-@deftp {Data Type} JCalProperty
-Alias for a record consisting of
-@itemize @bullet
-@item the name of the type, as a string
-@item All parameters of the object, as a @code{Record<string, any>}
-@footnote{Which is simply a regular javascript object, mapping strings to anything}.
-@item An @code{ical_type} value, noting the type of the final field(s)
-@item And one or more values of the type specified by the third field.
-@end itemize
-@end deftp
-
-@deftp {Data Type} JCal
-A record consisting of a @code{tagname}, a list of
-@code{JCalProperties}, and a list of other @code{JCal} objects.
-@end deftp
-
-@defvar xcal
-The xml namespace name for xcalendar, which is
-``urn:ietf:params:xml:ns:icalendar-2.0''.
-@end defvar
-
-
-@deftp {Interface} ChangeLogEntry
-@anchor{ChangeLogEntry}
-
-@ref{VEventChangelog}
-
-@deftypecv {Interface Field} ChangeLogEntry {(@code{'calendar'} | @code{'property'})} type
-@end deftypecv
-
-@deftypecv {Interface Field} ChangeLogEntry {string} name
-@end deftypecv
-
-@deftypecv {Interface Field} ChangeLogEntry {string?} from
-@end deftypecv
-
-@deftypecv {Interface Field} ChangeLogEntry {string?} to
-@end deftypecv
-
-@end deftp
diff --git a/doc/ref/javascript/user-additions.texi b/doc/ref/javascript/user-additions.texi
deleted file mode 100644
index 706b1dd4..00000000
--- a/doc/ref/javascript/user-additions.texi
+++ /dev/null
@@ -1,18 +0,0 @@
-@node user-additions.js
-@section user-additions.js
-
-Some things in the JavaScript code is built to be user-extendable.
-The HTML-page attempts to load @code{/static/user/user-additions.js}.
-
-
-Currently; this only entails @ref{formatters}, where you could, for
-example, parse all HTTP-links in a description.
-
-@example
-window.formatters.set('description', (el, d) => @{
- el.innerHTML = d.replaceAll(/https?:\/\/\S+/g, '<a href="$&">$&</a>');
-@})
-@end example
-
-Remember that the documents are X-HTML, so be @emph{extremely} careful
-with innerHTML.
diff --git a/doc/ref/javascript/vevent.texi b/doc/ref/javascript/vevent.texi
deleted file mode 100644
index 97d15f2a..00000000
--- a/doc/ref/javascript/vevent.texi
+++ /dev/null
@@ -1,113 +0,0 @@
-@node vevent
-@subsection vevent.js
-
-@deftp {Interface} Redrawable
-@deftypeop {Interface Field} Redrawable void redraw VEvent
-@end deftypeop
-@end deftp
-
-@deffn {Type Predicate} isRedrawable element
-Checks if the given element is an instance of Redrawable.
-@end deffn
-
-
-@deftp {class} VEventValue {type: ical_type} {value: any} {parameters: Map<string, any>}
-
-@deftypemethod VEventValue {[Record<string, any>, ical_type, any]} @
- to_jcal {}
-The return value is @emph{almost} a @code{JCalProperty}, just without
-the field name.
-@end deftypemethod
-
-@end deftp
-
-@deftp VEvent {properties: Map<string, VEventValue | VEventValue[]>} @
- {components: VEvent[]}
-
-Component for a single instance of a calendar event. Almost all data
-access should go through @code{getProperty} and @code{setProperty},
-with the exception of the current calendar (which is accessed directly
-through @code{calendar}). Almost all changes through these interfaces
-are logged, and can be viewed through @var{changelog}.
-
-@deftypemethod VEvent {any?} getProperty {key: string}
-@anchor{VEvent.getProperty}
-Returns the value of the given property if set, or undefined otherwise.
-
-For the keys
-@itemize
-@item @code{'CATEGORIES'},
-@item @code{'RESOURCES'},
-@item @code{'FREEBUSY'},
-@item @code{'EXDATE'}, and
-@item @code{'RDATE'}
-@end itemize
-instead returns a list list of values.
-@end deftypemethod
-
-
-@deftypemethod VEvent void setProperty {key: string} {value: any} {type: ical_type?}
-Sets the given property to the given value. If type is given it's
-stored alongside the value, possibly updating what is already
-there. Do however note that no validation between the given type and
-the type of the value is done.
-
-@var{value} may also be a list, but should only be so for the keys
-mentioned in @var{getProperty}.
-
-After the value is set, @var{redraw} is called on all registered
-objects, notifying them of the change.
-@end deftypemethod
-
-@deftypemethod VEvent void setProperties {[string, any, ical_type?][]}
-Equivalent to running @var{setProperty} for each element in the input
-list, but only calls @var{redraw} once at the end.
-@end deftypemethod
-
-@deftypemethod VEvent {IteratableIterator<string>} boundProperties
-Returns an iterator of all our properties.
-@end deftypemethod
-
-@deftypeivar VEvent {ChangeLogEntry[]} {#changelog}
-Every write through getProperty gets logged here, and can be
-consumed. Hopefully this will one day turn into an undo system.
-@ref{ChangeLogEntry}.
-@end deftypeivar
-
-@deftypeivar VEvent {IterableIterator<[number, ChangeLogEntry]>} changelog
-Public (read only) interface to changelog.
-@end deftypeivar
-
-@deftypeivar VEvent {string?} calendar
-The name of the calendar which this event belongs to.
-@end deftypeivar
-
-@deftypemethod VEvent void register {htmlNode: Redrawable}
-Register something redrawable, which will be notified whenever this
-VEvents data is updated.
-@end deftypemethod
-
-@deftypemethod VEvent void unregister {htmlNode: Redrawable}
-Stop recieving redraw events on the given component.
-@end deftypemethod
-
-@deftypemethod VEvent JCal to_jcal
-Converts the object to JCal data.
-@end deftypemethod
-
-@end deftp
-
-
-@deftp {class} RecurrenceRule
-@deftypemethod RecurrenceRule {Record<string, any>} to_jcal
-Converts ourselves to JCal data.
-@end deftypemethod
-@end deftp
-
-@deftypefun RecurrencRule xml_to_recurrence_rule {Element}
-Parse a XCAL recurrence rule into a RecurrenceRule object.
-@end deftypefun
-
-@deftypefun VEvent xml_to_vcal {Element}
-Parse a complete XCAL object into a JS VEvent object.
-@end deftypefun
diff --git a/doc/ref/text.texi b/doc/ref/text.texi
new file mode 100644
index 00000000..ec7074ae
--- /dev/null
+++ b/doc/ref/text.texi
@@ -0,0 +1,9 @@
+@node Text Procedures
+@chapter Text Procedures
+
+Various utilities for formatting text in various ways.
+
+@include text/utilities.texi
+@include text/flow.texi
+@include text/markup.texi
+@include text/numbers.texi
diff --git a/doc/ref/text/flow.texi b/doc/ref/text/flow.texi
new file mode 100644
index 00000000..0613d78f
--- /dev/null
+++ b/doc/ref/text/flow.texi
@@ -0,0 +1,23 @@
+@node Reflowing Text
+@section Reflowing Text
+
+@code{(text flow)}
+
+@defun flow-text str [width=70]
+Reflow and justify @var{str} to @var{width} columns.
+
+Each newline is as a newline, so each paragraph needs to be on its own
+line. The output will look something like the following:
+
+@example
+muck calendar's Hobart's Kendall's lighthouse wooziest knot's swanky
+Ghats's witless heftiness's hailstorm's ladybugs abridgment's
+whispered Willemstad's ludo stewardess photostatic potshot ninety
+perfected Potsdam asinine swings Valiums Adrenalin's contralto
+emigration's besmears finessing resorption's literariness's
+verbalize maximums Bjork diverticulitis cascaras implacably
+overeager deepen funeral's Edwardian Calvinistic seawards microlight
+palatial Shaun fungus's unmounted armrests Culbertson's lineage
+@end example
+
+@end defun
diff --git a/doc/ref/text/markup.texi b/doc/ref/text/markup.texi
new file mode 100644
index 00000000..bec33557
--- /dev/null
+++ b/doc/ref/text/markup.texi
@@ -0,0 +1,71 @@
+@node Markup
+@section Markup
+
+@defun sxml->ansi-text tree
+Takes an HTML-like document in SXML format, and produces a formatted
+string with embedded ANSI-escapes suitable to print to a terminal.
+
+Supported tags are:
+
+@table @samp
+@item group
+@item block
+Groups elements, concatenating their format. Mainly here for helper
+procedres and the like. Also used for the root node.
+
+@item header
+Centers and bolds its content. Attributes will be sent along to the
+inner @code{<center/>} tag.
+
+@item center
+Center its contents on the line. The output is undefined if the body
+serializes to a multiline string.
+
+@item p
+A text paragraph. Justifies the content inside.
+
+Ends with a double newline, unless the parameter @code{inline} is set.
+
+@item b
+Make content bold.
+
+@item i
+@item em
+Make content italics.
+
+@item code
+Format content as code.
+
+(currently does nothing since we only support output to terminal)
+
+@item blockquote
+Justifies content, and sets it slightly indented.
+
+@item ws
+Forces horizontal whitespace. Use the parameter @code{minwidth} to
+specify how many spaces should be inserted.
+
+@item br
+Forces a linebreak.
+
+@item hr
+Generates a horrizontal line.
+
+@item dl
+Declares a description list.
+
+@item dt
+A key in a description list, only valid inside @code{dl}.
+
+@item dd
+A value of a description list, only valid inside @code{dl}.
+
+@item scheme
+Set content as Scheme code. The content will be passed through Guile's
+pretty-print.
+@end table
+
+
+Almost all of the block environments accept the attribute @var{width},
+which specifies the desired output width.
+@end defun
diff --git a/doc/ref/text/numbers.texi b/doc/ref/text/numbers.texi
new file mode 100644
index 00000000..fce5c9fa
--- /dev/null
+++ b/doc/ref/text/numbers.texi
@@ -0,0 +1,42 @@
+@node Spelled out Numbers
+@section Spelled out Numbers
+
+Numbers writtens as word. The usual interface is through
+@code{(text numbers)} which uses the current locale for translations.
+However, @code{(text numbers @var{<lang-code>})} can also be imported
+directly with the exact same interface. Language codes should be two
+letter ISO language codes (e.g. ``se'', ``en'', ...)
+
+When resolving the current language, first the environment variable
+@env{LC_MESSAGES} is checked, followed by @env{LC_ALL}, and finaly
+falls back to ``en''.
+
+English is also chosen if no implementation for the chosen language
+exists.
+
+Note that English uses the term cardinal and ordinal @emph{numeral},
+rather than @emph{number}.
+
+
+@defun number->string-ordinal n [language=(resolve-language)]
+Convert a string into an ordinal number. These are the ``ranking''
+numbers, e.g. ``first'', ``second'', ...
+@end defun
+
+@defun number->string-cardinal n [language=(resolve-language)]
+Convert a string into a cardinal number. These are the ``ordinary''
+counting numbers, e.g. ``one'', ``two'', ...
+@end defun
+
+@defun resolve-language
+Return the current language.
+@end defun
+
+@defun each-string count args ...
+Return a (locale dependant) string indicating which elements of a set
+are targeted, such as ``each'', ``every other'', ...
+
+@var{args} is reserved for locale specific extensions, such as in
+Swedish where both ``var tredje'' and ``vart tredje'' (meaning ``every
+third'') exists, and is chosen depending on the following noun.
+@end defun
diff --git a/doc/ref/text/utilities.texi b/doc/ref/text/utilities.texi
new file mode 100644
index 00000000..175b8f60
--- /dev/null
+++ b/doc/ref/text/utilities.texi
@@ -0,0 +1,67 @@
+@node Text Utilities
+@section Text Utilities
+
+@code{(text util)}
+
+Various general utilities for basic text manipulation.
+
+Some of these procedures claim to use ``true'' text width. These
+calculate text width in unicode code-points, but with (some) ANSI
+escape sequences omitted. In a perfect world, these would show exactly
+how many characters wide the outputed string is when printed to a
+(sufficiently advanced) terminal.
+
+@defun words str
+Split string on spaces. No space merging is done.
+@end defun
+
+@defun unwords list
+Join list with spaces.
+@end defun
+
+@defun lines str
+Split string on newlines.
+@end defun
+
+@defun unlines list
+Join string with newlines.
+@end defun
+
+@defun true-string-length word
+@anchor{true-string-length}
+Alternative string-length whith counts ANSI escapes as 0-length.
+@end defun
+
+@defun true-string-pad str len [chr=#\space]
+Works like the regular @code{string-pad}, but uses the ``true''
+length. @ref{true-string-length}
+@end defun
+
+@defun trim-to-width str len
+Forces @var{str} to be exactly @var{len} characters long.
+
+This is done by either right padding the string, or by drop
+characters from the right until the string is one shorter than length,
+then an ellipsis character is added.
+
+@example
+(trim-to-width "Hello, World!" 6)
+⇒ "Hello…"
+
+(trim-to-width "Hello" 10)
+⇒ "Hello "
+@end example
+@end defun
+
+@defun add-enumeration-punctuation list [final-delim=``&'']
+Intersperse punctuation into @var{list}, preparing it to be formatted
+as a inline list in the body of the document. The sequence ``, ''
+inserted between each element, except the last which will use
+@var{final-delim}. An oxford comma is not used.
+
+@example
+(string-concatenate (add-enumeration-punctuation
+ '("Pasta" "Hamburgers" "Hotdog and Mash")))
+⇒ "Pasta, Hamburgers & Hotdog and Mash"
+@end example
+@end defun
diff --git a/doc/ref/guile/vcomponent.texi b/doc/ref/vcomponent.texi
index 2560bdde..d0e032b3 100644
--- a/doc/ref/guile/vcomponent.texi
+++ b/doc/ref/vcomponent.texi
@@ -1,5 +1,12 @@
-@node VComponent
-@section (vcomponent)
+@node VComponents
+@chapter VComponents
+
+Procedures for manipulating VComponents.
+VComponents are the general container type as specified by RFC5545
+(iCalendar). The term VComponent isn't from the standard, but rather
+the generialization of VCALENDAR, VEVENT, ...
+
+Some of these values are still Calp specific.
@defvr {Configuration Variable} calendar-files
List of filepaths
@@ -89,10 +96,10 @@ have parent in its parent slot
@end lisp
@end deffn
-@deffn (extract field) vcomponent
-@deffnx (extract* field) vcomponent
+@defun {(extract field)} vcomponent
+@defunx {(extract* field)} vcomponent
Curried version of @var{prop}.
-@end deffn
+@end defun
@defun delete-property! component key
@end defun
diff --git a/doc/ref/vulgar.texi b/doc/ref/vulgar.texi
new file mode 100644
index 00000000..70101aab
--- /dev/null
+++ b/doc/ref/vulgar.texi
@@ -0,0 +1,27 @@
+@node Vulgar Terminal Interface
+@chapter Vulgar Terminal Interface
+
+The Vulgar@footnote{Since it's not Curses}
+Terminal Interface aims to be a simple way to semi advanced terminal
+interfaces.
+
+@defun cls
+Clear the screen, and move the cursor to the ``home''.
+@end defun
+
+@defun set-cursor-pos x y
+Move the cursor to the specified position on the screen.
+@end defun
+
+@defun with-vulgar [bits] thunk
+Runs @var{thunk} with
+@code{iattr.lflag &= @var{bits}} and
+@code{oattr.lflag &= @var{bite}}, along with
+@command{tput civis} being run on entrance, and
+@command{tput cnorm} being run on exit.
+
+The thunk is properly prepared on non-local entrances and exits.
+@end defun
+
+@include vulgar/color.texi
+@include vulgar/termios.texi
diff --git a/doc/ref/vulgar/color.texi b/doc/ref/vulgar/color.texi
new file mode 100644
index 00000000..611f4c54
--- /dev/null
+++ b/doc/ref/vulgar/color.texi
@@ -0,0 +1,18 @@
+@node Color
+@section Color
+
+@defvar STR-RESET
+ANSI escape sequence for removing all current formatting, as a string.
+@end defvar
+
+@defmac color-if predicate color body ...
+@code{(begin body ...)} is run, coloring it's return value using the
+ANSI escape sequence @var{color}, if @var{predicate} is true, and
+uncolored otherwise.
+@end defmac
+
+@defun color-escape n
+Generates an RGB color escape code. @var{n} can either be @code{#f},
+in which case the empty string is returned, or a a 24 bit color code
+encoded hexadecimaly as @samp{#RRGGBB}.
+@end defun
diff --git a/doc/ref/vulgar/termios.texi b/doc/ref/vulgar/termios.texi
new file mode 100644
index 00000000..58a83e61
--- /dev/null
+++ b/doc/ref/vulgar/termios.texi
@@ -0,0 +1,217 @@
+@node Termios
+@section Termios
+
+Interface to termios procedures. See termios(3) and @code{termios.h}
+for general information.
+
+@code{(vulgar termios)}
+
+Refer to termios(3) for deeper information about all these fields.
+
+@deftp {Record Type} <termios>
+See ``The termios structure'' in termios(3).
+@defun make-termios
+Create a new (empty) termios structure.
+@end defun
+
+@defun cc termios
+@defunx cflag termios
+@defunx iflag termios
+@defunx ispeed termios
+@defunx lflag termios
+@defunx line termios
+@defunx oflag termios
+@defunx ospeed termios
+Accessors to termios each field.
+@end defun
+@end deftp
+
+@defun copy-termios termios
+Create a copy of the given termios structure.
+@end defun
+
+@defun tcsetattr! termios [port] [when=TCSANOW]
+Updates @var{port} with flags from @var{termios}.
+@end defun
+
+@defun tcgetattr! termios [port=(current-input-port)]
+Gets termios information about @var{port}, and stores it in @var{termios}.
+@end defun
+
+@defun cfmakeraw! termios
+Calls the termios function @code{cfmakeraw} on @var{termios}, updating
+the structure.
+@end defun
+
+
+@defvar TOSTOP
+@defvarx NLDLY
+@defvarx CREAD
+@defvarx VSTOP
+@defvarx B1500000
+@defvarx B4000000
+@defvarx B150
+@defvarx VEOL
+@defvarx VQUIT
+@defvarx CSTART
+@defvarx CBAUD
+@defvarx CR0
+@defvarx OLCUC
+@defvarx CSTATUS
+@defvarx VSTART
+@defvarx IXANY
+@defvarx ONOCR
+@defvarx VERASE
+@defvarx TTYDEF_IFLAG
+@defvarx B1000000
+@defvarx NL0
+@defvarx FLUSHO
+@defvarx TABDLY
+@defvarx CDSUSP
+@defvarx CEOL
+@defvarx CIBAUD
+@defvarx TAB3
+@defvarx CR2
+@defvarx NL1
+@defvarx CS8
+@defvarx CERASE
+@defvarx OPOST
+@defvarx TTYDEF_SPEED
+@defvarx TAB1
+@defvarx EXTA
+@defvarx B1200
+@defvarx TAB0
+@defvarx B75
+@defvarx EXTB
+@defvarx FF1
+@defvarx CR1
+@defvarx CS5
+@defvarx INPCK
+@defvarx B576000
+@defvarx B3000000
+@defvarx OCRNL
+@defvarx TCOON
+@defvarx CBAUDEX
+@defvarx CCEQ
+@defvarx IXOFF
+@defvarx CREPRINT
+@defvarx FF0
+@defvarx ECHONL
+@defvarx IXON
+@defvarx ISTRIP
+@defvarx CSTOP
+@defvarx PENDIN
+@defvarx BRKINT
+@defvarx IEXTEN
+@defvarx TCIFLUSH
+@defvarx VSUSP
+@defvarx B38400
+@defvarx TCION
+@defvarx B921600
+@defvarx ECHOPRT
+@defvarx CQUIT
+@defvarx IMAXBEL
+@defvarx CRTSCTS
+@defvarx ECHOCTL
+@defvarx CEOT
+@defvarx VMIN
+@defvarx ICANON
+@defvarx ONLRET
+@defvarx VINTR
+@defvarx CSTOPB
+@defvarx B3500000
+@defvarx B230400
+@defvarx CS7
+@defvarx TCOFLUSH
+@defvarx TIOCSER_TEMT
+@defvarx B200
+@defvarx CSUSP
+@defvarx BS1
+@defvarx XTABS
+@defvarx CLNEXT
+@defvarx VT0
+@defvarx NCCS
+@defvarx BSDLY
+@defvarx B9600
+@defvarx ECHOKE
+@defvarx VEOF
+@defvarx TTYDEF_OFLAG
+@defvarx VTDLY
+@defvarx VT1
+@defvarx CTRL
+@defvarx NOFLSH
+@defvarx VREPRINT
+@defvarx ICRNL
+@defvarx CINTR
+@defvarx ADDRB
+@defvarx B2500000
+@defvarx EXTPROC
+@defvarx B110
+@defvarx XCASE
+@defvarx ECHOE
+@defvarx IUTF8
+@defvarx CS6
+@defvarx CFLUSH
+@defvarx B500000
+@defvarx CKILL
+@defvarx CDISCARD
+@defvarx VDISCARD
+@defvarx B2400
+@defvarx TTYDEF_CFLAG
+@defvarx VWERASE
+@defvarx INLCR
+@defvarx ONLCR
+@defvarx OFDEL
+@defvarx B1800
+@defvarx ISIG
+@defvarx IGNPAR
+@defvarx TAB2
+@defvarx CTIME
+@defvarx B1152000
+@defvarx ECHO
+@defvarx CR3
+@defvarx CMSPAR
+@defvarx PARENB
+@defvarx B2000000
+@defvarx VKILL
+@defvarx B4800
+@defvarx CLOCAL
+@defvarx IGNBRK
+@defvarx BS0
+@defvarx TCSAFLUSH
+@defvarx B19200
+@defvarx TCSANOW
+@defvarx VTIME
+@defvarx B0
+@defvarx TCOOFF
+@defvarx CEOF
+@defvarx B460800
+@defvarx PARMRK
+@defvarx VEOL2
+@defvarx FFDLY
+@defvarx TCSADRAIN
+@defvarx IGNCR
+@defvarx CRDLY
+@defvarx VLNEXT
+@defvarx PARODD
+@defvarx CRPRNT
+@defvarx B600
+@defvarx VSWTC
+@defvarx IUCLC
+@defvarx HUPCL
+@defvarx B50
+@defvarx TCIOFF
+@defvarx TTYDEF_LFLAG
+@defvarx CBRK
+@defvarx ECHOK
+@defvarx B115200
+@defvarx CSIZE
+@defvarx B300
+@defvarx OFILL
+@defvarx CWERASE
+@defvarx B134
+@defvarx B57600
+@defvarx TCIOFLUSH
+@defvarx CMIN
+Imported from the ``termios.h'' header file.
+@end defvar
diff --git a/doc/ref/web.texi b/doc/ref/web.texi
new file mode 100644
index 00000000..8574e166
--- /dev/null
+++ b/doc/ref/web.texi
@@ -0,0 +1,6 @@
+@node Webservers and -Clients
+@chapter Webservers and -Clients
+
+@include web/query.texi
+@include web/uri-query.texi
+@include web/routes.texi
diff --git a/doc/ref/web/query.texi b/doc/ref/web/query.texi
new file mode 100644
index 00000000..df3ba953
--- /dev/null
+++ b/doc/ref/web/query.texi
@@ -0,0 +1,9 @@
+@node Web Query
+@section (web query)
+
+@defun parse-query query-string [encoding=''UTF-8'']
+Given a string like ``?key=value&other=something'', returns
+@code{(key: "value" other: "something")}. Performs uri-decoding of
+both key and value. A key without a value decodes to that key, with
+itself as its value
+@end defun
diff --git a/doc/ref/guile/web.texi b/doc/ref/web/routes.texi
index 69ab726f..a2249c7a 100644
--- a/doc/ref/guile/web.texi
+++ b/doc/ref/web/routes.texi
@@ -1,24 +1,5 @@
-@node Web Stuff
-@section Web Stuff
-
-@subsection (web query)
-
-@defun parse-query query-string [encoding=''UTF-8'']
-Given a string like ``?key=value&other=something'', returns
-@code{(key: "value" other: "something")}. Performs uri-decoding of
-both key and value. A key without a value decodes to that key, with
-itself as its value
-@end defun
-
-
-@subsection (web uri-query)
-
-@defun encode-query-parameters parameters
-Given the association list @var{parameter}, encode it into a query
-string on the form ``key=value&...''.
-@end defun
-
-@subsection (web http make-routes)
+@node HTTP Routes
+@section (web http make-routes)
@defun parse-endpoint-string str
Only really public for tests.
diff --git a/doc/ref/web/uri-query.texi b/doc/ref/web/uri-query.texi
new file mode 100644
index 00000000..d3df3a70
--- /dev/null
+++ b/doc/ref/web/uri-query.texi
@@ -0,0 +1,7 @@
+@node URI Query
+@section (web uri-query)
+
+@defun encode-query-parameters parameters
+Given the association list @var{parameter}, encode it into a query
+string on the form ``key=value&...''.
+@end defun