diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/ref/Makefile | 9 | ||||
-rw-r--r-- | doc/ref/calp.texi | 5 | ||||
-rw-r--r-- | doc/ref/guile.texi | 65 | ||||
-rw-r--r-- | doc/ref/guile/datetime.texi | 680 | ||||
-rw-r--r-- | doc/ref/guile/srfi-41.texi | 80 | ||||
-rw-r--r-- | doc/ref/guile/util-config.texi | 93 | ||||
-rw-r--r-- | doc/ref/guile/util.texi | 17 | ||||
-rw-r--r-- | doc/ref/javascript.texi | 12 | ||||
-rw-r--r-- | doc/ref/javascript/components/tab_group_element.texi | 4 | ||||
-rw-r--r-- | doc/ref/javascript/components/vevent_description.texi | 6 | ||||
-rw-r--r-- | doc/ref/javascript/formatters.texi | 16 | ||||
-rw-r--r-- | doc/ref/javascript/lib.texi | 33 | ||||
-rw-r--r-- | doc/ref/javascript/types.texi | 5 | ||||
-rw-r--r-- | doc/ref/javascript/user-additions.texi | 18 | ||||
-rw-r--r-- | doc/ref/javascript/vevent.texi | 1 |
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 |