aboutsummaryrefslogtreecommitdiff
path: root/doc/ref
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ref')
-rw-r--r--doc/ref/Makefile9
-rw-r--r--doc/ref/calp.texi5
-rw-r--r--doc/ref/guile.texi65
-rw-r--r--doc/ref/guile/datetime.texi680
-rw-r--r--doc/ref/guile/srfi-41.texi80
-rw-r--r--doc/ref/guile/util-config.texi93
-rw-r--r--doc/ref/guile/util.texi17
-rw-r--r--doc/ref/javascript.texi12
-rw-r--r--doc/ref/javascript/components/tab_group_element.texi4
-rw-r--r--doc/ref/javascript/components/vevent_description.texi6
-rw-r--r--doc/ref/javascript/formatters.texi16
-rw-r--r--doc/ref/javascript/lib.texi33
-rw-r--r--doc/ref/javascript/types.texi5
-rw-r--r--doc/ref/javascript/user-additions.texi18
-rw-r--r--doc/ref/javascript/vevent.texi1
15 files changed, 1019 insertions, 25 deletions
diff --git a/doc/ref/Makefile b/doc/ref/Makefile
index 2232a70e..79486a46 100644
--- a/doc/ref/Makefile
+++ b/doc/ref/Makefile
@@ -1,7 +1,12 @@
+.PHONY: all install
+
TEXI_FILES := $(shell find . -type f -name \*.texi)
-INFOFLAGS :=
+INFOFLAGS := --no-split
all: calp.info
calp.info: $(TEXI_FILES)
- makeinfo $(INFOFLAGS) calp.texi
+ makeinfo -o $@ $(INFOFLAGS) calp.texi
+
+install: all
+ install -m644 -D -t $(DESTDIR)/usr/share/info/ calp.info
diff --git a/doc/ref/calp.texi b/doc/ref/calp.texi
index 474ad3e2..92c30242 100644
--- a/doc/ref/calp.texi
+++ b/doc/ref/calp.texi
@@ -5,6 +5,11 @@
Copyright @copyright{} 2020 Hugo Hörnquist
@end copying
+@dircategory The Algorithmic Language Scheme
+@direntry
+* Calp: (calp). Parsing and displaying of icalendar files
+@end direntry
+
@c Borrowed from guile.texi
@c @nicode{S} is plain S in info, or @code{S} elsewhere. This can be used
@c when the quotes that @code{} gives in info aren't wanted, but the
diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi
index 67828b09..eb9e3bcc 100644
--- a/doc/ref/guile.texi
+++ b/doc/ref/guile.texi
@@ -1,10 +1,68 @@
@node Guile
@chapter Guile
+@include guile/datetime.texi
+@include guile/srfi-41.texi
@include guile/util.texi
@include guile/util-path.texi
+@include guile/util-config.texi
@include guile/vcomponent.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
@@ -43,8 +101,8 @@ type = 'BINARY | 'BOOLEAN | 'CAL-ADDRES | 'DATE | 'DATE-TIME
@subsubsection types
@defun escape-chars str
-Escape ``@verb{|,|}'', ``@verb{|;|}'' and ``@verb{|\|}'' with a
-backslash, and encode newlines as ``@verb{|\n|}''.
+Escape @code{,}, @code{;} and @code{\} with a
+backslash, and encode newlines as @code{\n}.
@end defun
@defun get-writer type
@@ -80,7 +138,7 @@ type = 'BINARY | 'BOOLEAN | 'CAL-ADDRES | 'DATE | 'DATE-TIME
@defun ns-wrap
@lisp
(define (ns-wrap sxml)
- `(icalendar (@ (xmlns "urn:ietf:params:xml:ns:icalendar-2.0"))
+ `(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}.
@@ -121,3 +179,4 @@ 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/guile/datetime.texi b/doc/ref/guile/datetime.texi
new file mode 100644
index 00000000..d49c4ada
--- /dev/null
+++ b/doc/ref/guile/datetime.texi
@@ -0,0 +1,680 @@
+@node Datetime
+@section Datetime
+
+My datetime library, with focus on date manipulation in ways sensible
+for humans. So that a date-time plus one day always keep the time of
+day.
+For example, 26 mars 2022 10:00 plus 1 day would give 27 mars 2022
+10:00, even though 25 hours have passed due to summer time starting
+(in Sweden).
+
+Note that while some of these procedures mentions timezones, almost
+nothing is actually done with it.
+
+@subsection Constants
+
+@defvar jan
+@defvarx january
+@defvarx feb
+@defvarx february
+@defvarx mar
+@defvarx mars
+@defvarx apr
+@defvarx april
+@defvarx may
+@defvarx jun
+@defvarx june
+@defvarx jul
+@defvarx july
+@defvarx aug
+@defvarx august
+@defvarx sep
+@defvarx september
+@defvarx oct
+@defvarx october
+@defvarx nov
+@defvarx november
+@defvarx dec
+@defvarx december
+Numeric constants for all months.
+@code{@var{jan} = 1}, @code{@var{dec} = 12}.
+@end defvar
+
+@defvar sun
+@defvarx sunday
+@defvarx mon
+@defvarx monday
+@defvarx tue
+@defvarx tuesday
+@defvarx wed
+@defvarx wednesday
+@defvarx thu
+@defvarx thursday
+@defvarx fri
+@defvarx friday
+@defvarx sat
+@defvarx saturday
+@anchor{sunday}
+Numeric constants for all weekdays.
+@code{@var{sunday} = 0}, @code{@var{saturday} = 6}.
+@end defvar
+
+@subsection Parameters and Configuration
+
+@deftp {parameter} week-start
+@anchor{week-start}
+Which weekday should be considered the first. Used for calculating
+week numbers, the start dates of week, and is available for UI-code
+and the like which wants it.
+@end deftp
+
+@deftp {config} week-start
+Configuration item, updates @xref{week-start}.
+@end deftp
+
+
+@subsection Datatypes
+
+@deftp {Immutable Record} <date> year month day
+Object representing a date, without any timezone information.
+Given the date 2040-03-23 (in ISO-8601 format), @var{year} = 2020,
+@var{month} = 3 and @var{day} = 23.
+
+Values higher than those usually used are possible, but not recommended.
+
+@defun date? x
+Is @var{x} a date object?
+@end defun
+
+@defun date [#:year=0] [#:month=0] [#:day=0]
+Create a new date object.
+@end defun
+
+@defun year <date>
+@defunx month <date>
+@defunx day <date>
+Fetch corresponding field from the date object.
+@end defun
+@end deftp
+
+@deftp {Immutable Record} <time> hour minute second
+Object representing a timestamp in a given day,
+without any timezone information.
+Given the time 10:20:30, @var{hour} = 10,
+@var{minute} = 20 and @var{second} = 30.
+
+Values larger than the ``regular'' are allowed, and useful since this
+type is also used for time offsets.
+
+@defun time? x
+Is @var{x} a time object?
+@end defun
+
+@defun time [#:hour=0] [#:minute=0] [#:second=0]
+Create a new time object.
+@end defun
+
+@defun hour <time>
+@defunx minute <time>
+@defunx second <time>
+Fetch corresponding field from the time object.
+@end defun
+@end deftp
+
+
+@deftp {Immutable Record} <datetime> date time tz
+
+A collation of date and time, along with an optional timezone.
+Set @code{tz = #f} if a timezone is not desired.
+
+@defun datetime? x
+Is @var{x} a datetime object?
+@end defun
+
+@defun datetime [#:date] [#:time] [#:tz] [#:year=0] [#:month=0] [#:day=0] [#:hour=0] [#:minute=0] [#:second=0]
+Creates a new <datetime>. If @var{date} or @var{time} is given, those
+are used. Otherwise, a date object is created from @var{year},
+@var{month} and @var{day}, and time is respectively created from
+@var{hour}, @var{minute} and @var{second}.
+@end defun
+
+@defun get-date
+@defunx get-timezone
+Note that @code{get-time} doesn't exists.
+@end defun
+@end deftp
+
+
+@subsection Reader Extensions
+
+This module registers reader extensions on @code{#0}, @code{#1}, and
+@code{#2}. These read either dates, times, or datetimes; using @code{string->date/-time}.
+
+@c @subsection CTIME
+
+@c These procedures are for interfacing with C's time procedures, see CTIME(3).
+
+@c The datetime<->tm procedures are internal, since they are slightly
+@c unstable (see comments in code).
+@c They are thereby not documented.
+@c @defun datetime->tm datetime
+@c Convert a @code{<datetime>} object to a @code{struct tm}, encoded in a
+@c scheme vector.
+@c @end defun
+@c
+@c @defun tm->datetime tm
+@c Converts a @code{struct tm}, as returned from @code{datetime->tm} back
+@c into a @code{<datetime>} object.
+@c @end defun
+
+@subsection Procedures
+
+@defun datetime->unix-time datetime
+Converts @var{datetime} to an integer representing its unix time.
+@end defun
+
+@defun unix-time->datetime n
+Converts a given unix timestamp to a datetime object.
+Currently forces the timezone to be UTC.
+@end defun
+
+@defun current-datetime
+Return a datetime object of the current date and time.
+Currently always returns it in UTC.
+@end defun
+
+@defun current-date
+Get the date component from a call to @code{current-datetime}.
+@end defun
+
+
+@defun get-datetime datetime
+Takes a datetime in any timezone, and renormalize it to local time (as
+defined by the environment variable TZ). This means that given UTC
+10:00 new years day would return 11:00 new years day if ran in sweden.
+@end defun
+
+
+@defun as-date date/-time
+@defunx as-time date/-time
+Both procedures takes a <date>, <time>, or <datetime>, and return
+respectively a <date> or <time> object.
+
+@code{as-date}, when given a time will return a zeroed date object.
+Vice versa for @code{as-time}.
+@end defun
+
+@defun as-datetime date/-time
+Takes a <date>, <time>, or <datetime>, and returns a <datetime> object
+with the same data, with the (possibly) missing date or time set to
+all zeroes.
+@end defun
+
+
+@defun date-zero? date
+@defunx time-zero? time
+Checks if all components are zero.
+@end defun
+
+
+@defun leap-year? year
+Given an integer @var{year}, return @code{#t} if it's a leap year, and
+@code{#f} otherwise.
+@end defun
+
+@defun days-in-month date
+Returns how many days are in the month specified by the <date> @var{date}.
+Note that the day component is ignored.
+@end defun
+
+@defun days-in-year date
+Returns how many days are in the year pointed to by @var{date}.
+@end defun
+
+@defun start-of-month date
+Returns a <date> object equal to date, but with the day component set
+to 1.
+@end defun
+
+@defun end-of-month date
+Returns a <date> object equal to date, but with the day component set
+to the last day of the month.
+
+@example
+(end-of-month #2020-01-10)
+⇒ #2020-01-31
+(end-of-month #2020-02-01)
+⇒ #2020-02-29
+@end example
+@end defun
+
+
+@defun start-of-year date
+Returns a <date> object equal to date, but with the day and month
+component set to 1.
+@end defun
+
+@defun date-stream date-increment start-day
+Returns an @ref{(guile)SRFI-43} stream of <date> objects, starting at
+@var{start-day} and stepping in increments of @var{date-increment}.
+@end defun
+
+@defun day-stream start-day
+Returns a stream of each day from @var{start-day}.
+@end defun
+
+@defun month-stream start-day
+Returns a stream of each months from @var{start-day}.
+Day component stays the same.
+@end defun
+
+@defun week-stream start-day
+Returns a stream of each week from @var{start-day}
+(increments of 7 days).
+@end defun
+
+@defun time-min a b
+@defunx time-max a b
+@defunx date-min a b
+@defunx date-max a b
+@defunx datetime-min a b
+@defunx datetime-max a b
+Returns the smaller (or larger) of @var{a} or @var{b}.
+@end defun
+
+@defun month+ date [change=1]
+@defunx month- date [change=1]
+Equivalent to @code{(date+ date (date month: change))}.
+@end defun
+
+@defun week-day date
+Returns an integer representing the week day of @var{date}.
+@ref{sunday}
+@end defun
+
+
+@defun week-1-start date [week-start=(week-start)]
+Returns the date which week 1 starts on, according to the (at least)
+Swedish rule of week counting.
+@ref{week-start}
+@end defun
+
+
+@defun week-number date [week-start=(week-start)]
+Returns the week number of @var{date}, according to the (at least)
+Swedish rule of week counting.
+@ref{week-start}
+@end defun
+
+@defun date-starting-week week-number date [week-start=(week-start)]
+Returns the first day of week @var{week-number}, @var{date} is used
+for year information.
+@ref{week-start}
+@end defun
+
+
+@defun week-day-name week-day [truncate-to] [#:key locale]
+Returns the locale dependent name for the given week day.
+
+@var{week-day} is a number per @ref{sunday}.
+@var{truncate-to} may be a number, which limits to the first @var{n}
+letters of the resulting string.
+@end defun
+
+
+@defun timespan-overlaps? s1-begin s1-end s2-begin s2-end
+Check if the interval @var{s1-begin} to @var{s1-end} overlaps with the
+interval @var{s2-begin} to @var{s2-end}.
+@end defun
+
+@defun find-first-week-day week-day date
+Returns the first instance of the given week-day after @var{date}.
+
+@example
+(find-first-week-day mon #2020-04-01)
+⇒ #2020-04-06
+(find-first-week-day mon #2020-04-10)
+⇒ #2020-04-13
+(find-first-week-day mon #2020-04-30)
+⇒ #2020-05-04
+@end example
+@end defun
+
+@defun all-wday-in-month week-day month-date
+Returns instances of the given week-day in month between
+month-date and end of month.
+@example
+(all-wday-in-month mon #2020-06-01)
+⇒ (#2020-06-01 #2020-06-08 #2020-06-15 #2020-06-22 #2020-06-29)
+(all-wday-in-month mon #2020-06-10)
+⇒ (#2020-06-15 #2020-06-22 #2020-06-29)
+@end example
+@end defun
+
+@defun all-wday-in-year week-day year-date
+Returns a list of all instances of @var{week-day} in @var{year-date}.
+@end defun
+
+@defun add-day date
+@defunx remove-day date
+@code{@var{date} ± (date day: 1)}
+@end defun
+
+@defun in-date-range? start-date end-date → date → boolean
+Returns a predicate procedure, which checks if a given date is between
+@var{start-date} and @var{end-date}.
+@end defun
+
+@defun weekday-list [week-start=(week-start)]
+Returns a list of the seven week days, with @var{week-start}
+as the beginning of the week.
+@end defun
+
+
+@defun start-of-week d [week-start=(week-start)]
+@defunx end-of-week d [week-start=(week-start)]
+Returns the date the week containing @var{d} started or ended.
+@end defun
+
+
+@defun month-days date [week-start=(week-start)]
+Given a month and and which day the week starts on,
+returns three lists, which are:
+The days leading up to the current month, but share a week
+The days in the current month
+The days after the current month, but which shares a week.
+
+@example
+ mars 2020
+må ti on to fr lö sö
+ 1
+ 2 3 4 5 6 7 8
+ 9 10 11 12 13 14 15
+16 17 18 19 20 21 22
+23 24 25 26 27 28 29
+30 31
+@end example
+@lisp
+(month-days #2020-03-01 mon)
+; ⇒ (2020-02-24 ... 2020-02-29)
+; ⇒ (2020-03-01 ... 2020-03-31)
+; ⇒ (2020-04-01 ... 2020-04-05)
+@end lisp
+Ignores day component of @var{date}.
+@end defun
+
+
+@defun days-in-interval start-date end-date
+The amount of days in the given interval, including both endpoints.
+@end defun
+
+
+@defun year-day date
+Day from start of the year, so 1 feb would be day 32.
+Also known as Julian day.
+@end defun
+
+
+@defun time->decimal-hour time
+Convert @var{time} to a decimal value, so 10:30 would become 10.5.
+@end defun
+
+@defun datetime->decimal-hour dt [start-date]
+Similar to @code{time->decimal-hour}, but also looks at the date component.
+
+@var{start-date} is required if either the month of year component of
+@var{dt} is non-zero (since months and years have a variable number of hours).
+@end defun
+
+@defun date-range start end [increment=(date day: 1)]
+Returns a list of all dates from start to end.
+Both inclusive
+@end defun
+
+@defun locale-month
+@defunx locale-month-short
+These are direct re-exports from (ice-9 i18n)
+
+@xref{Accessing Locale Information,,,guile}.
+@end defun
+
+@defun date= args ...
+@defunx date=? args ...
+@defunx date< args ...
+@defunx date<? args ...
+@defunx date> args ...
+@defunx date>? args ...
+@defunx date<= args ...
+@defunx date<=? args ...
+@defunx date>= args ...
+@defunx date>=? args ...
+Checks if all date arguments satisfy the predicate.
+@end defun
+
+@defun time= args ...
+@defunx time=? args ...
+@defunx time< a b
+@defunx time<? a b
+@defunx time> a b
+@defunx time>? a b
+@defunx time<= a b
+@defunx time<=? a b
+@defunx time>= a b
+@defunx time>=? a b
+Checks if all time arguments satisfy the predicate.
+@end defun
+
+@defun datetime= args ...
+@defunx datetime=? args ...
+@defunx datetime< a b
+@defunx datetime<? a b
+@defunx datetime> a b
+@defunx datetime>? a b
+@defunx datetime<= a b
+@defunx datetime<=? a b
+@defunx datetime>= a b
+@defunx datetime>=? a b
+Check if all datetime arguments satisfy the predicate.
+The timezone field is ignored.
+@end defun
+
+@defun date/-time< a b
+@defunx date/-time<? a b
+@defunx date/-time> a b
+@defunx date/-time>? a b
+@defunx date/-time<= a b
+@defunx date/-time<=? a b
+@defunx date/-time>= a b
+@defunx date/-time>=? a b
+Equivalent to the @code{datetime*} versions, but wraps its arguments
+in @code{as-datetime}.
+@end defun
+
+@subsection Arithmetic
+
+While only one date (and one time) type is available, it really should
+be seen as two. Absolute dates, such as the fourth of november,
+2022. The other type are intervals, such as 3 years, 4 months and 2 days.
+
+A ``type mismatch'' might therefore lead to some confounding results.
+@example
+(date- #2020-01-01 #2020-01-01)
+⇒ #00-1-11-31
+(date-difference #2020-01-01 #2020-01-01)
+⇒ #0000-00-00
+@end example
+
+@defun date+ base rest ...
+@defunx date- base rest ...
+Add or remove each difference from base.
+@end defun
+
+@defun date-difference end start
+Returns difference between the two dates, in years, months, and days.
+In such a way that
+
+@lisp
+(date= (date+ start (date-difference end start)))
+@end lisp
+@end defun
+
+@defun time+ base rest ...
+@defunx time- base rest ...
+Adds (or subtracts) each difference from the base, and returns two
+values. The sum, and how many midnight's have passed.
+
+@lisp
+(time+ #22:00:00 (time hour: 4))
+⇒ #02:00:00
+⇒ 1
+@end lisp
+@end defun
+
+@defun datetime+ base change
+@defunx datetime- base change
+@end defun
+
+@defun datetime-difference end start
+@end defun
+
+@subsection Parsing and Formatting
+
+@defun datetime->string datetime [fmt=''~Y-~m-~dT~H:~M:~S''] [#:allow-unknown?]
+
+Formats @var{datetime} into a string.
+The function will throw an error when encountering an unknown format
+specifier, unless @var{#:allow-unknown} is true.
+
+@table @samp
+@item ~~
+A literal tilde (~).
+@item ~H
+Hour, left padded with zeroes to length 2.
+@item ~k
+Like @samp{~H}, but padded with spaces.
+@item ~M
+Minute, left padded with zeroes to length 2.
+@item ~S
+Seconds, left padded with zeroes to length 2.
+@item ~Y
+Year, left padded with zeroes to length 4;
+@item ~m
+Month number, left padded with zeroes to length 2.
+@item ~d
+Day in month, left padded with zeroes to length 2.
+@item ~s
+Epoch time, per UNIX.
+@item ~e
+Same as @samp{~d}, but padded with spaces.
+@item ~1
+Shorthand for @samp{~Y-~m-~d}.
+@item ~3
+Shorthand for @samp{~H:~M:~S}.
+@item ~A
+Locale week day name.
+@item ~a
+Locale week day name, truncated to 3 characters.
+@item ~b
+Locale month name, truncated.
+@item ~B
+Locale month name, in full.
+@item ~Z
+@samp{Z} if the timezone is @samp{UTC}. Nothing otherwise.
+@end table
+@end defun
+
+@defun date->string date [fmt=''~Y-~m-~d''] [#:allow-unknown?]
+@defunx time->string date [fmt=''~H:~M:~S''] [#:allow-unknown?]
+Simple wrappers around @code{datetime->string}, which works directly
+on date or time objects.
+@end defun
+
+
+@defun string->datetime str [fmt=''~Y-~m-~dT~H:~M:~S~Z''] [locale=%global-locale]
+Attempts to parse @var{str} as a datetime, according to the ruleset @var{fmt}.
+An invalid or unparsable string will throw an error.
+
+Each token in @var{fmt} informs the parser what the next expected
+token in @var{str} is. If a binding rule is parsed multiple times,
+then the last one is used for the resulting object. For example,
+@example
+(string->datetime "10:20" "~H:~H")
+⇒ (datetime hour: 20)
+@end example
+
+spaces are literal, there is no way to match an arbitrary number of
+whitespace characters
+
+@table @samp
+@item ~~
+Next token is a literal tilde.
+
+@item ~Z
+If next token is a literal @samp{Z} then the resulting timezone is set
+to @samp{UTC}, otherwise does nothing.
+
+@item ~p
+The next token is an AM/PM indicator, matched by the regex
+@code{^([AaPp])[.]?[Mm][.]?}. A valid token will reinterpret the last
+hour indicator as 12-hour time (instead of 24 hour time), regardless
+if its before or after this token.
+
+@item ~b
+@itemx ~B
+@itemx ~h
+Parses a month by name, just as @code{parse-month}.
+
+@item ~H
+@itemx ~M
+@itemx ~S
+@itemx ~m
+@itemx ~d
+Parses up to two digits, but possibly less if a non-digit appears in
+the string. Then stores the resulting value in either the hour,
+minute, second, month, or day slot of the resulting object.
+
+This double function allows both dates without delimiters, such as
+``0102'' to be correctly parsed, but also more free form formats, such
+as ``1 jan''.
+
+@item ~Y
+Equivalent to @samp{~H}, but reads up to 4 digits, and stores the
+result in the year field.
+@end table
+@end defun
+
+
+@defun parse-month str [locale=%global-locale]
+Returns the first month whose name has @var{str} as its prefix.
+The result will be on the interval [1, 12], or -1 if no month matched.
+@end defun
+
+
+@defun string->time str [fmt=''~H:~M:~S''] [locale=%global-locale]
+@defunx string->date str [fmt=''~Y-~m-~d''] [locale=%global-locale]
+Wrappers around @code{string->datetime}, but only returning the time
+or date component.
+@end defun
+
+
+@defun string->date/-time string
+Parses string as an ISO-8601 string. Checks for the existence of
+@code{T}, @code{:}, or @code{-} to determine if it's a datetime, time
+or date.
+@end defun
+
+@defun parse-ics-date str
+@defunx parse-ics-time str
+@defunx parse-ics-datetime str [zone]
+Parses dates per RFC5545.
+@end defun
+
+@defun parse-iso-date str
+@defunx parse-iso-time str
+@defunx parse-iso-datetime str
+Parses (the well known subset) of ISO-compatible dates.
+@end defun
+
+@defun parse-freeform-date str
+Currently an alias for parse-iso-datetime, but should preferably be extended.
+@end defun
diff --git a/doc/ref/guile/srfi-41.texi b/doc/ref/guile/srfi-41.texi
new file mode 100644
index 00000000..8c65b6eb
--- /dev/null
+++ b/doc/ref/guile/srfi-41.texi
@@ -0,0 +1,80 @@
+@node SRFI 41 Utilities
+@section SRFI 41 Utilities
+
+Extra utilities for handling streams. Provided by @code{(srfi srfi-41
+util)}.
+
+@defun stream-car+cdr stream
+Returns the car and cdr of stream.
+@end defun
+
+@defun interleave-streams < streams
+Merges a number of totally ordered streams into a single
+totally ordered stream.
+
+((≺, stream)) → (≺, stream)
+@end defun
+
+@defun stream-insert < item stream
+Insert item in the totally ordered stream (≺, stream).
+@end defun
+
+
+@defun filter-sorted-stream pred stream
+@end defun
+
+
+@defun filter-sorted-stream* pred keep-remaining? stream
+@end defun
+
+@defun get-stream-interval start-pred end-pred stream
+Get the substream from stream from the first match of start-pred, to
+the first match of end-pred after start-pred.
+@end defun
+
+
+@defun stream-find pred stream
+Find the first element in stream satisfying the predicate, or #f none
+was found.
+@end defun
+
+
+@defun stream-remave pred stream
+Stream-filter, but with predicate negated.
+@end defun
+
+
+@defun stream->values stream
+Equivalent to list->values. Returns as many objects as the stream is long.
+@end defun
+
+
+@defun repeating-naturals from repeats
+Natural numbers from @var{from} and up, but each repeated @var{repeat}
+times.
+@example
+(stream->list 15 (repeating-naturals 1 3))
+⇒ (1 1 1 2 2 2 3 3 3 4 4 4 5 5 5)
+@end example
+@end defun
+
+
+@defun stream-partition pred stream
+@end defun
+
+@defun stream-split idx stream
+@end defun
+
+@defun stream-paginate stream [page-size=10]
+@end defun
+
+
+@defun eager-stream-cons a b
+stream cons, but eval arguments beforehand.
+@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
+``final'' element matching a predicate in an infinite stream.
+@end defun
diff --git a/doc/ref/guile/util-config.texi b/doc/ref/guile/util-config.texi
new file mode 100644
index 00000000..2e197bcc
--- /dev/null
+++ b/doc/ref/guile/util-config.texi
@@ -0,0 +1,93 @@
+@node Configuration
+
+@section Configuration
+
+Provided by the module @code{(calp util config)}.
+
+Configuration items are similar to regular defines, but global to the
+entire program, and assignable before they are declared.
+Their primary purpose is to allow a user supplied @file{config.scm},
+without needing all appropriate modules already loaded.
+
+@defmac define-config name default kw-parameters ...
+Declares a new configuration variable named @var{named}, with the
+default value @var{default}. @var{kw-parameters} are given on Guile's
+standard @code{hash: value} form. @pxref{get-property} for available parameters.
+@end defmac
+
+@defun get-property config-name property-key
+@anchor{get-property}
+Returns a metadata-slot value for the given configuration setting.
+
+Each declared configuration item has (at least) the following metadata
+slots:
+
+@table @samp
+@item description
+Short human-readable description of this configuration item.
+
+@item source-module
+Module in which this item was declared. Automatically filled in by @code{define-config}.
+
+@item pre
+Procedure which can pre-process or validate set values. Think about it
+as if @code{(set-config! key value)} expands to
+@code{(true-set-config! key (pre value))},
+with the bonus that if @code{pre value} returns @code{#f} then the
+assignment fail.
+
+@item post
+Procedure to run after the value is set. For example for updating a
+local parameter.
+@example
+(define-public week-start (make-parameter sun))
+(define-config week-start sun
+ description: "First day of week"
+ pre: (ensure (lambda (x) (<= sun x sat)))
+ post: week-start)
+@end example
+@end table
+
+@findex set-property!
+Note that @code{set-property!} doesn't exist, since properties are read-only.
+@end defun
+
+@defun set-config! name value
+Sets the @var{value} of the configuration variable @var{name}.
+@end defun
+
+@defun get-config key [default]
+Retrieve the configured value for @var{key}. Throws an error if key
+isn't set, and @var{default} isn't given (to differentiate it from
+@code{#f} being set.
+@end defun
+
+@defun {(ensure predicate)} value
+Helper procedure for @code{pre} hooks. Curried function which checks
+if @var{value} satisfies @var{predicate}, and if so returns @var{value}.
+
+@example
+(define-public ((ensure predicate) value)
+ (if (predicate value)
+ value #f))
+@end example
+@end defun
+
+@defun get-configuration-documentation
+Collects all variables we know about (both defined and non-defined
+(but set)), and builds a markup-tree with information about them.
+@c TODO document markup format, link it here
+@end defun
+
+@defun format-procedure procedure
+Procedure mainly used by @code{get-configuration-documentation}. Gives
+a simple string representation of the given procedure.
+
+@example
+(format-procedure format-procedure)
+⇒ "format-procedure(proc)"
+
+(format-procedure (lambda* (key: (a 1)) (+ a 3)))
+⇒ "λkey: a"
+@end example
+@end defun
diff --git a/doc/ref/guile/util.texi b/doc/ref/guile/util.texi
index 71e3f93a..3f37491d 100644
--- a/doc/ref/guile/util.texi
+++ b/doc/ref/guile/util.texi
@@ -338,7 +338,20 @@ Similar to @var{let}, but sets environment variables for the code in
body. Restores the old values once we leave.
@end defmac
+@defmac catch* thunk (symbol proc) ...
+Macro allowing multiple exception types to be caught. Each (symbol
+proc) pair expands to a regular @code{catch}, with the leftmost being
+innermost.
+@end defmac
+
+@subsection UUID generation
+
+Provided by module @code{(hnh util uuid)}.
+
+@defun uuid-v4
+Generates a UUID-v4 string.
+@end defun
-@defun uuidgen
-Generates a UUID.
+@defun uuid
+Generates an implementation defined (but guaranteed valid) UUID.
@end defun
diff --git a/doc/ref/javascript.texi b/doc/ref/javascript.texi
index 7510e4f5..bbe1cb25 100644
--- a/doc/ref/javascript.texi
+++ b/doc/ref/javascript.texi
@@ -10,6 +10,7 @@
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
@@ -17,6 +18,8 @@ All elements are initialized in elements.ts
@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
@@ -34,3 +37,12 @@ All elements are initialized in elements.ts
@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/components/tab_group_element.texi b/doc/ref/javascript/components/tab_group_element.texi
index 7d9ca412..67f3a359 100644
--- a/doc/ref/javascript/components/tab_group_element.texi
+++ b/doc/ref/javascript/components/tab_group_element.texi
@@ -13,14 +13,14 @@ 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:
-@verbatim
+@example
+---------------+ +----------------+
| TabLabel | | Tab |
+---------------+ +----------------+
| id |<----| aria-labeledby |
| aria-controls |---->| id |
+---------------+ +----------------+
-@end verbatim
+@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}
diff --git a/doc/ref/javascript/components/vevent_description.texi b/doc/ref/javascript/components/vevent_description.texi
index 492c8dff..54dda7e3 100644
--- a/doc/ref/javascript/components/vevent_description.texi
+++ b/doc/ref/javascript/components/vevent_description.texi
@@ -7,4 +7,10 @@
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/formatters.texi b/doc/ref/javascript/formatters.texi
new file mode 100644
index 00000000..16a988c4
--- /dev/null
+++ b/doc/ref/javascript/formatters.texi
@@ -0,0 +1,16 @@
+@node formatters
+@subsection formatters
+
+Formatting procedures used by some components.
+@c TODO can we have a backref of every node containing @ref{formatters-proc}?
+
+@deftypevar {Map<string, (e:HTMLElement, s:any) => void>} formatters
+@anchor{formatters-proc}
+
+Each procedure takes two arguments. The HTML-element which contents
+should be replaced, along with the target value, as returned by @ref{VEvent.getProperty}.
+@end deftypevar
+
+@deftypevr {Window Value} {Map<string, (e:HTMLElement, s:string) => void>} formatters
+Same object as @xref{formatters-proc}. Provided for @xref{user-additions.js}.
+@end deftypevr
diff --git a/doc/ref/javascript/lib.texi b/doc/ref/javascript/lib.texi
index e5b13383..a3fb0697 100644
--- a/doc/ref/javascript/lib.texi
+++ b/doc/ref/javascript/lib.texi
@@ -116,22 +116,29 @@ This means that the @var{utc} field is @code{false}, and that
Formats a Date object according to the format specification @var{str}.
Keeping with Guile each format specifier starts with a ~.
-@c table formatting borrowed from Gulie Reference (SRFI-19 Date to string)
-@multitable {MMMM} {MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM}
-@item @nicode{~~} @tab literal ~
+@table @samp
+@item ~~
+literal ~
@c Almost all fields are left padded. How do I signify this
@c with a single footnote?
-@item @nicode{~Y} @tab year, left-padding with zeroes.
-@item @nicode{~m} @tab month number, left padded with zeroes.
-@item @nicode{~d} @tab day of month.
-@item @nicode{~H} @tab hour
-@item @nicode{~M} @tab minute
-@item @nicode{~S} @tab second
-@item @nicode{~Z} @tab 'Z' if Date is UTC, otherwise nothing
-
-@item @nicode{~L} @tab Converts the date to local time
+@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 multitable
+@end table
@end defmethod
@defun format_date date str
diff --git a/doc/ref/javascript/types.texi b/doc/ref/javascript/types.texi
index b9e6dbbf..6f518f53 100644
--- a/doc/ref/javascript/types.texi
+++ b/doc/ref/javascript/types.texi
@@ -57,9 +57,8 @@ Alias of @code{'string'}.
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 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
diff --git a/doc/ref/javascript/user-additions.texi b/doc/ref/javascript/user-additions.texi
new file mode 100644
index 00000000..706b1dd4
--- /dev/null
+++ b/doc/ref/javascript/user-additions.texi
@@ -0,0 +1,18 @@
+@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
index ae54cfd4..4ceaa380 100644
--- a/doc/ref/javascript/vevent.texi
+++ b/doc/ref/javascript/vevent.texi
@@ -31,6 +31,7 @@ through @code{calendar}). Almost all changes through these interfaces
are logged, and can be viewed in @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