diff options
Diffstat (limited to 'doc/ref/general')
-rw-r--r-- | doc/ref/general/base64.texi | 22 | ||||
-rw-r--r-- | doc/ref/general/bst.texi | 37 | ||||
-rw-r--r-- | doc/ref/general/crypto.texi | 17 | ||||
-rw-r--r-- | doc/ref/general/data-formats.texi | 25 | ||||
-rw-r--r-- | doc/ref/general/data-stores.texi | 36 | ||||
-rw-r--r-- | doc/ref/general/datetime.texi | 670 | ||||
-rw-r--r-- | doc/ref/general/glob.texi | 37 | ||||
-rw-r--r-- | doc/ref/general/graph.texi | 65 | ||||
-rw-r--r-- | doc/ref/general/graphviz.texi | 10 | ||||
-rw-r--r-- | doc/ref/general/io.texi | 31 | ||||
-rw-r--r-- | doc/ref/general/lens.texi | 47 | ||||
-rw-r--r-- | doc/ref/general/options.texi | 32 | ||||
-rw-r--r-- | doc/ref/general/srfi-41.texi | 100 | ||||
-rw-r--r-- | doc/ref/general/sxml.texi | 100 | ||||
-rw-r--r-- | doc/ref/general/util-config.texi | 93 | ||||
-rw-r--r-- | doc/ref/general/util-exceptions.texi | 40 | ||||
-rw-r--r-- | doc/ref/general/util-object.texi | 86 | ||||
-rw-r--r-- | doc/ref/general/util-path.texi | 73 | ||||
-rw-r--r-- | doc/ref/general/util-type.texi | 62 | ||||
-rw-r--r-- | doc/ref/general/util.texi | 374 | ||||
-rw-r--r-- | doc/ref/general/uuid.texi | 17 | ||||
-rw-r--r-- | doc/ref/general/webdav.texi | 301 | ||||
-rw-r--r-- | doc/ref/general/xdg-basedir.texi | 62 | ||||
-rw-r--r-- | doc/ref/general/zic.texi | 135 |
24 files changed, 2472 insertions, 0 deletions
diff --git a/doc/ref/general/base64.texi b/doc/ref/general/base64.texi new file mode 100644 index 00000000..ab6bba81 --- /dev/null +++ b/doc/ref/general/base64.texi @@ -0,0 +1,22 @@ +@node Base64 +@section Base64 + +@defun base64->bytevector bv +@defunx bytevector->base64 bv +Base procedure for all Base64 operations. +Takes and returns bytevectors. + +Throws @code{decoding-error} on invalid input. +@end defun + +@defun base64-string->bytevector string +@defunx bytevector->base64-string bv +Base64 side is strings, while data is bytevectors. +@end defun + + +@defun base64encode string [transcoder=(native-transcoder)] +@defunx base64decode string [transcoder=(native-transcoder)] +Highest level Base64 procedures. Both encoded and decoded data is +strings. +@end defun 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/general/data-formats.texi b/doc/ref/general/data-formats.texi new file mode 100644 index 00000000..037d3ae7 --- /dev/null +++ b/doc/ref/general/data-formats.texi @@ -0,0 +1,25 @@ +@node Data Formats +@section Data Formats +A data format is some way that an individual event may get serialized +to disk. The default is iCalendar (TODO reference RFC 5545), but +others might be available (TODO footnote and reference xcal). + +Each available format should be included as +@code{(vcomponent formats @var{format-name})}. +Which module corresponds to what file type is currently defined out of band. + +Each module should expose the following procedures. + +@defun serialize component port +Write a serialized representation of @var{component} to @var{port}. +@end defun + +@defun deserialize port +Read a serialized representation of a component from @var{port}, and +return the deserialized instance of this object. +@end defun + +@subsection iCalendar +RFC 5545 + +@subsection xCal diff --git a/doc/ref/general/data-stores.texi b/doc/ref/general/data-stores.texi new file mode 100644 index 00000000..ec3962da --- /dev/null +++ b/doc/ref/general/data-stores.texi @@ -0,0 +1,36 @@ +@node Data Stores +@section Data Stores +Data stores are persistant stores for events, such as databases or the +file system. Each data store can support any number of data formats, +but which is an implementation detail of that format and shouldn't be +needed information from the high level view. +@footnote{It is however important for interoperability with other programs}. + +@c (make <calendar-store> #:path ``hello'') + +@defun path store +@end defun + +@deftp {GOOPS method} get-calendar this +Returns a vcomponent object of type @code{VCALENDAR}. Should contain +all @code{VEVENT} components of this calendar. +@end deftp + +@deftp {GOOPS method} get-by-uid this uid +Return the event object with UID equal to the string @var{uid}. +@end deftp + +@deftp {GOOPS method} queue-save this event +Queue a save event of @var{event} to the store. +@end deftp + +@deftp {GOOPS method} flush this +Force write of all queued actions. +@end deftp + +@subsection VDir +[VDIR]: http://vdirsyncer.pimutils.org/en/latest/vdir.html + +@subsection File + +@subsection SQLite diff --git a/doc/ref/general/datetime.texi b/doc/ref/general/datetime.texi new file mode 100644 index 00000000..037ac8d5 --- /dev/null +++ b/doc/ref/general/datetime.texi @@ -0,0 +1,670 @@ +@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 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 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/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/general/lens.texi b/doc/ref/general/lens.texi new file mode 100644 index 00000000..eeddd6ca --- /dev/null +++ b/doc/ref/general/lens.texi @@ -0,0 +1,47 @@ +@node Lenses +@section Lenses + +Provided by the module @code{(hnh util lens)} + +@defun modify object lens f args ... +@end defun + +@defmac modify* object lens +@defmacx modify* object lens rest ... +@end defmac + +@defmac set object lenses ... value +@end defmac + +@defmac get object lenses ... +@end defmac + + +@defun make-lens getter setter +@end defun + +@defmac build-lens getter setter +Where any of getter or setter can either be a single symbol, or a list. +@end defmac + +@deftp {Scheme Lens} identity-lens +@end deftp + +@defun compose-lenses lenses ... +@defunx lens-compose lenses ... +Lenses composes left to right, so earlier lenses in @var{lenses} are +applied earlier. +@end defun + +@deftp {Scheme Lens} ref idx +Focuses the element at index @var{idx} in a list. +@end deftp + +@deftp {Scheme Lens} car* +@deftp {Scheme Lens} cdr* +Focuses the first or second element of a pair. +@end deftp + +@defun each object lens proc +@end defun + 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/general/srfi-41.texi b/doc/ref/general/srfi-41.texi new file mode 100644 index 00000000..d8020ecc --- /dev/null +++ b/doc/ref/general/srfi-41.texi @@ -0,0 +1,100 @@ +@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-remove 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-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 +``final'' element matching a predicate in an infinite stream. +@end defun diff --git a/doc/ref/general/sxml.texi b/doc/ref/general/sxml.texi new file mode 100644 index 00000000..dd635b4c --- /dev/null +++ b/doc/ref/general/sxml.texi @@ -0,0 +1,100 @@ +@node sxml namespaced +@section Namespaced SXML + +Namespaces is a variant to ``regular'' SXML. Difference being that +instead of representing XML-tags as symbols, they are instead actual +objects. + +For example +@example +`(a (b "Content")) +@end example + +Would be represented as +@example +`(,(xml 'a) + (,(xml 'b) + "Content")) +@end example + +@defun namespaced-sxml->sxml tree [namespace-prefixes='()] +Takes a tree of namespaced-sxml, and optionally an assoc list from +namespace symbols, to prefered prefix. + +Returns a sxml tree, with xmlns:<prefix>=namespace attributes +@end defun + +@defun namespaced-sxml->xml tree [namespaces='()] [port='(current-output-port)] +Serializes the namespaced sxml tree to port. @var{namespaces} should +be an association list from namespace symbols, to prefered prefixes. +@end defun + +@defun namespaced-sxml->sxml/namespaces tree [namespace-prefixes='()] +Returns two values: +@itemize +@item An SXML tree (which doesn't have namespace attributes) +@item an association list from namespace symbols, to used prefixes. +@end itemize +@end defun + +@c xml->namespcaed-sxml and sxml->namespaced-sxml don't share +@c implementation, despite doing almost the same thing. This is since +@c xml->namespaced-sxml directly uses the ssax parser, giving us great +@c controll, while sxml->namespaced-sxml attempt to look at symbols. + +@defun xml->namespaced-sxml port-or-string +Reads xml from port, and return a namespaced SXML tree. +@end defun + +@defun sxml->namespaced-sxml tree namespaces +Converts a ``regular'' SXML tree into a namespaced sxml tree. +@var{namespaces} must be an association list which maps each prefix +used in @var{tree} onto a full XML namespace. + +The key @code{#f} can be used to map non-namespaced elements into a +namespace. +@end defun + +@defun xml tag +@defunx xml ns tag [attrs] +@anchor{xml-tag} + A single XML element, suitable to go as the car of a list to + create a full object. + + @var{xml} is a shorthand to @code{make-xml-element}, which + either takes just a tag (for non-namespaced elements), or a + namespace, a tag, and a list of attributes. + + @itemize + @item @var{tag} should be a symbol. + @item @var{ns} should be a symbol. + @item @var{attrs} should be a hash table. + @end itemize + + @defun make-xml-element tagname namespace attributes + @end defun + + @defun xml-element? x + @end defun + + @defun xml-element-tagname el + @end defun + + @defun xml-element-namespace el + @end defun + + @defun xml-element-attributes el + @end defun +@end defun + + +@defun make-pi-element tag body + @defun pi-element? x + @end defun + + @defun pi-tag pi + @end defun + + @defun pi-body pi + @end defun +@end defun diff --git a/doc/ref/general/util-config.texi b/doc/ref/general/util-config.texi new file mode 100644 index 00000000..2e197bcc --- /dev/null +++ b/doc/ref/general/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/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/general/util-object.texi b/doc/ref/general/util-object.texi new file mode 100644 index 00000000..ceac2f2a --- /dev/null +++ b/doc/ref/general/util-object.texi @@ -0,0 +1,86 @@ +@node define-type +@section Yet Another Object System + +@defmac define-type (name type-parameters ...) fields ... +Introduce a new type. + +Each field is either a symbol, or a list where the first element is a +symbol, and the remaining elements are alternating keywords and +values, as per @ref{Field Parameters}. All fields are optional by +default, but can be made non-optional through its type parameter. + +The example below creates a new type called @var{type}, with a custom +printer which always displays the string ``TYPE''. It has two fields, +@var{x}, which must be an integer, and @var{y}, which can have any +type, but gets the value ``Hello'' in none is given. +@example +(define-type (type #:printer (lambda (r p) (display "TYPE" p))) + (x #:type integer?) + (y #:default "Hello")) +@end example +@end defmac + +@subsection Type Parameters + +@deffn {Type Parameter} constructor (λ (primitive-constructor type-validator)) +Use a custom constructor for the type. The given procedure is called +with two values: +@itemize +@item the types primitive (and usually hidden) constructor, +which takes as many arguments as there are fields, in the order given +in define-type, and +@item the type validator procedure, which also takes all arguments, +but instead either returns an undefined value if everything is fine, +or throws @code{'wrong-type-arg} otherwise. +@end itemize +The procedure should then return a new procedure, which will be bound +as the constructor for the type. Note that default values are current +disregarded with custom constructors. + +A custom constructor for the type above might look like +@example +(lambda (primitive-constructor type-check) + (lambda* (#:key x y) + (type-check x y) + (primitive-constructor x y))) +@end example +@end deffn + +@deffn {Type Parameter} printer (λ (record port)) +Use a custom printer for the type. +@end deffn + +@subsection Field Parameters +@anchor{Field Parameters} + +@deffn {Field Parameter} default value +Value the field should get if not given. +@end deffn + +@deffn {Field Parameter} type type-clause +A type predicate that the field must obey. See @ref{type-clause} for details. +@end deffn + +@subsection Introduced Bindings + +Define type introduces a number procedures. (@var{<name>} should be +replaced with whatever was given as @var{name} to define-type. + +@defun @var{<name>} [kv-args ...] +Type constructor. Takes key-value arguments. Where the keys are the +names of the fields. +@end defun + +@defun @var{<name>}? x +Type predicate. +@end defun + +And for each field @var{<field>}: + +@defun @var{<field>} object [value] +Accessor for the given filed. +Returns the current value if called with only an object, and returns a +new object with @var{field} set to @var{value} if called with two values. + +The updating version checks the type if #:type was given on creation. +@end defun diff --git a/doc/ref/general/util-path.texi b/doc/ref/general/util-path.texi new file mode 100644 index 00000000..ba78a828 --- /dev/null +++ b/doc/ref/general/util-path.texi @@ -0,0 +1,73 @@ +@node Path Utilities +@section Path Utilities + +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 path paths ... +Joins all strings into a path, squeezing duplicated delimiters, but +ensuring that all delimiters that are needed are there. + +Note that delimiters embedded inside the string, which aren't first or +last in a substring (or are the only thing in a string) are +kept. Meaning that +@example +(path-append "/" "hello") ⇒ "/hello" +(path-append "/usr/local/bin" "cmd") ⇒ "/usr/local/bin/cmd" +@end example +@end defun + + +@defun path-join lst +@lisp +(apply path-append lst) +@end lisp +@end defun + + +@defun path-split path +Splits path into a list of components. +The first component will be @code{""} if path is absolute. +@end defun + + +@defun filename-extension filename +Returns the extension of the filename without a leading period, or the +empty string if none exists. + +@example +(filename-extension "file.tar.gz") +⇒ "gz" +@end example +@end defun + +@defun realpath path +Equivalent of realpath(3). Absolute file names are returned as is, +while relative filenames gets expanded to absolute filenames. +@end defun + +@defun relative-to base path +Returns @var{path} as a relative path relative to @var{base}. + +base must be non-empty +@example +(relative-to "/some" "/some/path") +;; ⇒ "path" + +(relative-to "/some" "/other/path/") +;; ⇒ "../path" + +(relative-to "/a/b/c" "/a/b") +;; ⇒ "/a/b" +@end example + +@end defun diff --git a/doc/ref/general/util-type.texi b/doc/ref/general/util-type.texi new file mode 100644 index 00000000..104b00b3 --- /dev/null +++ b/doc/ref/general/util-type.texi @@ -0,0 +1,62 @@ +@node Type utilities +@section Type utilities + +Provided by the module @code{(hnh util type)} + +@subsection Type Clauses +@anchor{type-clause} +@cindex type-clause + +Type clauses are an effective way of writing compound predicates +without explicitly mentioning the variable at all steps. + +The simplest type predicate is a single symbol, which is directly +called on the object: +@example +predicate? ⇒ (predicate? x) +@end example + +Otherwise, if the predicate is a list then the variable is spliced +into the argument list in the first position: +@example +(proc args ...) ⇒ (proc x args ...) +@end example + +The two primitives @code{and} and @code{or} are also available, which +both take an arbitrary number of predicates, and calls them in order, +with Scheme's usual short-circuiting rules. +@footnote{@code{and} and @code{or} doesn't have to be primitives, but +we would otherwise have one hell of a namespace conflict} + +@defmac list-of variable type-clause +Checks if @var{variable} is a list, and that every element satisfies type-clause. +@end defmac + +@defmac pair-of variable car-type-clause cdr-type-clause +Check if @var{variable} is a cons-pair, and that the car satisfies +@var{car-type-clause}, and that the cdr satisfies @var{cdr-type-clause}. +@end defmac + +@subsection Deffinitions + +@defmac build-validator-body variable type-clause +``Entry point'' of type clauses. Inserts variable into the +type-clause, returning something ready to be passed along the eval (or +rather, spliced into another macro). + +Also used if new ``primitives'' are to be added, such as list-of. +@end defmac + +@defmac typecheck variable type-clause [procedure-name=(current-procedure-name)] +Checks @var{variable} against @var{type-clause}, and raises +@code{'wrong-type-argument} if it fails. @var{procedure-name} is used +as the calling procedure for @code{scm-error}. + +Useful at the start of procedures. +@end defmac + + +@defmac current-procedure-name +Returns the current procedure name as a symbol, or @code{#f} if not found. +@end defmac + diff --git a/doc/ref/general/util.texi b/doc/ref/general/util.texi new file mode 100644 index 00000000..1d6a4e7a --- /dev/null +++ b/doc/ref/general/util.texi @@ -0,0 +1,374 @@ +@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)}. + +@defmac define-syntax [stx] +Extends the default syntax from the default +@lisp +(define-syntax @r{<name>} (λ (stx) body ...)) +@end lisp +To also allow +@lisp +(define-syntax (@r{<name>} stx) body ...) +@end lisp +@end defmac + + +@defmac when pred body ... +@defmacx unless pred body ... +Extends @var{when} and @var{unless} to return @code{'()} on the +false-case (instead of being undefined). +@end defmac + + +@defmac aif condition consequent alternate +@defmacx awhen condition consequent ... +Equivalent to the standard @var{if} and @var{when}@footnote{Actually +our extra specialized @var{when}}, but binds the return of +@var{condition} in the variable @var{it}. +@end defmac + + +@defmac for key in collection body ... +@defmacx for (key ...) in collection body ... +Syntactic sugar over @code{map}. +@example +(for x in collection + body ...) +@end example +expands into +@example +(map (lambda (x) body ...) collection) +@end example + +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 + + +@defmac print-and-return expr +Prints @var{expr}, and then returns it. +Only evaluates @var{expr} once. +@end defmac + + +@defun swap f +@math{swap (λ (x y) body ...) ⇔ λ (y x) body ...} +@end defun + +@defmac set! key value ... +@defmacx set! key = proc ... +@defmacx set! key = (op args ...) ... +Extends @var{set!} to allow multiple forms in one, also introduces the +cases: +@lisp +(set! x = f) ⇔ (set! x (f x)) +(set! x = (+ 1) ⇔ (set! x (+ x 1)) +@end lisp +@end defmac + +@defmac set/r! key value ... +See @var{set!}, but also returns the final value. +@end defmac + +@defmac label name proc +Equivalent to +@lisp +(letrec ((name proc)) + proc) +@end lisp +@end defmac + + +@defun sort* items comperator [get=identity] +@defunx sort*! items comperator [get=identity] +A sort more similar to Python's. Applies @var{get} to each item before +calling @var{comperator} on them. + +@var{sort*!} may modify the input list. +@end defun + + +@defun find-extreme items [<=<] [access=identity] +Returns 2 values, the most extreme value, as compared by @var{<} after +calling @var{access} on each element, along with the remaining values +in an undefined order. + +Should be faster than @var{car+cdr} ∘ @var{sort*}. +@end defun + +@defun find-min list [access=identity] +@defunx find-max list [access=identity] +See @var{find-extreme} +@end defun + +@defun filter-sorted proc list +@c TODO document me +@end defun + +@defun != args ... +@lisp +(define != (negate =)) +@end lisp +@end defun + +@defun init+last list +Returns two values: everything except the last element of @var{list}, +and the last element of @var{list}. +@end defun + +@defun take-to lst n +Equivalent to @var{take}, but return everything (instead of crash) if +n > (length lst). +@end defun + +@defun string-take-to str n +Same as @var{take-to}, but for strings +@end defun + + +@defun string-first +@defunx string-last +Returns the first and last character of a string respectivly +@end defun + + +@defun as-symb s +Returns @code{(string->symbol s)} if @var{s} is a string, @var{s} otherwise. +@end defun + +@defun enumerate lst +Returns a list of lists, where the @var{car} is the index in the list, +and the @var{cadr} is the corresponding element of the original list +@end defun + + +@defun unval proc [n=0] +Takes a procedure returning multiple values, and returns a function +which takes the same arguments as the original procedure, but only +returns one of the procedures. Which procedure can be sent as an +additional parameter. +@end defun + + +@defun flatten lst +Takes an arbitrarily nested list, and flattens it to a depth 1 list +@end defun + + +@defmac let-lazy forms body ... +Syntactically equivalent to a regular @var{let}, but wraps each variable +in @var{forms} in @var{delay}, while it finds each instance of that +variable in body and wraps in in @var{force}. +@end defmac + + +@defun map/dotted proc dotted-list +Like @var{map}, but also works for improper lists. +@end defun + + +@defun assq-merge a b +@c TODO +@end defun + +@defun kvlist->assq +Given a flat list where each odd element (counting from 1) is a +keyword, and each even element is any value, return these as a list of +pairs of symbols and values. + +@lisp +(kvlist->assq '(#:a 1 #:b "Hello")) +⇒ ((a . 1) + (b . "Hello")) +@end lisp +@end defun + +@defun assq-limit alist [number=1] +@c TODO document +@end defun + +@defun group-by proc lst +Calls @var{proc} on each element in @var{lst}, and return a +association list which @code{(proc e)} as its keys, and all elements +which mapped to that value. + +The values returned by @var{proc} are compared as per @code{equal?}. +@end defun + +@defun split-by lst element +Split a list into sub-lists on @var{element} +@lisp +(split-by '(0 1 2 3 4 2 5 6) 2) +⇒ ((0 1) (3 4) (5 6)) +@end lisp +@end defun + + +@defun span-upto count predicate list +Simar to span from srfi-1, but never takes more than +@var{count} items. Can however still take less. +@example +(span-upto 2 char-numeric? (string->list "123456")) +⇒ (#\1 #\2) +⇒ (#\3 #\4 #\5 #\6) +(span-upto 2 char-numeric? (string->list "H123456")) +⇒ () +⇒ (#\H #\1 #\2 #\3 #\4 #\5 #\6) +@end example +@end defun + + +@defun cross-product args ... +Returns the cross product between all given lists. Each pair will be a +list, whose indices matches the order of the inputs +@end defun + +@defun string-flatten tree +Given an arbitary tree, do a pre-order traversal, appending all strings. + +Non-strings are converted to strings, and also appended. +@end defun + +@defun intersperse item list +Inserts @var{item} between each element in @var{list}. +@end defun + + +@defun insert-ordered item collection [<] +Inserts @var{item} into @var{collection}, such that collection +remainins sorted if it was sorted beforehand. +@end defun + + +@defmac -> item forms ... +@defmacx ->> item forms ... +Applies each form onto item, from left to right. +A form can either by a symbol, which is the applied directly, or a +list, in which case @var{->} inserts item as the second argument +(after the operand), and @var{->>} inserts it last. +@end defmac + + +@defmac set (accessor object) value +@defmacx set (accessor object) = (operation args ...) +See @xref{SRFI-9 Records,,,guile} +@end defmac + +@defmac set-> object (accessor value) rest ... +@defmacx set-> object (accessor = (operator args)) rest ... +Wrapper around @var{set}, but applies transformations from left to +right, similar to @var{->}. +@end defmac + + +@defmac and=>> value procedures ... +Chained application of @code{and=>}, so applies each procedure from +left to right, stopping when one return @code{#f}. +@end defmac + +@defun downcase-symbol +Converts a symbol to lower case. +@end defun + + +@defun group list chunk-size +Splits @var{list} into sub-lists of size @var{chunk-size}. +Requires that @math{chunk-size|(length list)} +@end defun + + +@defun iterate proc until base +Repeatedly applies @var{proc} to @var{base}, until @var{until} is +satisfied. +@end defun + +@defun valued-map proc lists ... +Applies a procedure which returns multiple values to each element of a +list, and returns all values returned from all procedure calls. +@example +(define (± x) (values x (- x))) +(valued-map ± '(1 2)) +⇒ 1 +⇒ -1 +⇒ 2 +⇒ -2 +@end example +@end defun + + +@defun assoc-ref-all alist key +@defunx assq-ref-all alist key +@defunx assv-ref-all alist key +Equivalent to assoc-ref (and family), but works on association lists with +non-unique keys, returning all mathing records (instead of just the first). +@lisp +(assoc-ref-all '((a . 1) (b . 2) (a . 3)) 'a) +⇒ (1 3) +@end lisp +@end defun + + +@defun vector-last v +Returns the last element of @var{v}. +@end defun + +@defun ->string any +Converts @var{any} to a string, as per @var{display}. +@end defun + + +@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 +Run @var{thunk} with the locale @var{category} temporarily set to +@var{locale}. +@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. + +@var{Symbol} can also be on the form @code{(pre-unwind @var{symbol})}, +then @code{with-throw-handler} is used instead of @code{catch}. +@end defmac + +@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. + +@code{uniqx} also takes @var{comp}, which is sholud be a binary +procedure returning if the elements are equal. +@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/general/webdav.texi b/doc/ref/general/webdav.texi new file mode 100644 index 00000000..a495c945 --- /dev/null +++ b/doc/ref/general/webdav.texi @@ -0,0 +1,301 @@ +@node WebDAV +@section WebDAV + +For a complete view of WebDAV, please see @cite{RFC4918 (HTTP +Extensions for Web Distributed Authoring and Versioning (WebDAV))}, +but in short, and specifc for this implementation. + +A DAV tree consists of resources, which are analogous to files and +directories. A resource is referenced by its href. + +Each resources is either a collection and have children, or have +content. Parts of this implementation allows a collection to also have +contents, while other does not. The standard doesn't seem to mind +either way. + +Each resource also has a set of properties, modelling metadata and +extra data about the resource. + +@emph{href}'s are internally represented as lists of strings, where the +root element ``/'' is an empty list, and all other cases are mapped +like: +@example +"/a/b" ⇒ '("a" "b") +@end example + +@emph{resources} are GOOPS objects, which the base class +@code{<resource>}. + +The user (of the library) is assumed to designate one resource +instance as the root of the resource tree. All other resources are +then added as (grand-)children to that resource. Each resource has a +field @var{name}, which is the normative name used when searching by +name in the tree@footnote{This means that one resource can't easily +exist at multiple points in the tree}. + +@emph{properties} are split into live and dead properties, where live +properties have extra handling by the server, while dead properties +are simply carried along after the end-user put them on a resource. + +Live properties are handled through GOOPS methods. + +Dead properties are (by default) stored directly inside each resource. + +@node WebDAV Properties +@subsection Properties + +@itemize +@item @code{(calp webdav property)} +@item @code{(calp webdav propfind)} +@end itemize + +@subsubsection Default Live Properties + +@deftp {GOOPS method} creationdate +@end deftp + +@deftp {GOOPS method} displayname +@end deftp + +@deftp {GOOPS method} getcontentlanguage +@end deftp + +@deftp {GOOPS method} getcontentlength +@end deftp + +@deftp {GOOPS method} getcontenttype +@end deftp + +@deftp {GOOPS method} getetag +@end deftp + +@deftp {GOOPS method} getlastmodified +@end deftp + +@deftp {GOOPS method} lockdiscovery +@end deftp + +@deftp {GOOPS method} resourcetype +@end deftp + +@deftp {GOOPS method} supportedlock +@end deftp + + +@node WebDAV Resources +@subsection Resources + +@deftp {GOOPS class} <resource> +Base type for all WebDAV resources. + +The base class shouldn't be directly instanciated. + + @defun resource? x + Is the given object a <resource>, or decendant? + @end defun +@end deftp + +@deftp {GOOPS method} name resource +The name of a resource is the local part of a href. +@end deftp + +@deftp {GOOPS method} children resource +All direct children of a resource, as a list. +@end deftp + +@defun add-child! parent child [#:overwrite?] [#:collection?=(is-collection? child)] +Adds a resource as a child of another resource. + +Before adding the resource to the parents child set, +@code{(setup-new-resource! child parent)} is called. If +@var{collection?} is true, then +@code{(setup-new-collection! child parent)} is also called. + +If @var{overwrite?} is present, then the parent will be checked for a +child which already has that name, and take action accordingly. +It will return one of: @code{'replaced} if a resource already existed +with that name, but it has been replaced, @code{'collision}, if the +old one was kept, and @code{'created} if the new resource was added +without collisions. + +If @var{overwrite?} is absent then the method always returns @var{'created}. +@end defun + +@defun add-resource! resource name content +Creates a new resource with the given name, and make it a child of +@var{self}. Setting its initial content to @var{content}. + +Calls @code{add-resource!}, so the same book-keeping procedures are called. +@c TODO Document throw +@c TODO Document return +@end defun + +@defun add-collection! resource name +Similar to @code{add-resource!} but the created resource is instead a collection. +@end defun + +@deftp {GOOPS method} setup-new-resource! (self <resource>) (parent <resource>) +Book-keeping procedure called by @code{add-resource!} on @emph{all} +added resources. + +Base implementation in a no-op. +@end deftp + +@deftp {GOOPS method} setup-new-collection! (self <resource>) (parent <resource>) +Book-keeping procedure called by @code{add-resource!} if +@var{collection?} is true. + +Base implementation is a no-op. +@end deftp + +@deftp {GOOPS method} is-collection? resource +Is the given resource a collection. + +The base implementation simply checks if the resource has any children. +@end deftp + +@deftp {GOOPS method} content resource +@deftpx {GOOPS method} set-content! resource content +Get and set the content of a given resource. @var{content}s type can +be anything that the given resource type accepts. Overrides of this +procedure should preferably save its contents properly. +@end deftp + +@c + +@defun get-property resource xml-tag +@defunx get-live-property resource xml-tag +@defunx get-dead-property resource xml-tag +@end defun + + +@defun set-property resource xml-el +@defunx set-property! resource xml-el +@defunx set-dead-property resource xml-el +@defunx set-dead-property! resource xml-el +@defunx set-live-property resource xml-el +@defunx set-live-property! resource xml-el +@end defun + + +@defun remove-property resource xml-tag +@defunx remove-property! resource xml-tag +@defunx remove-dead-property resource xml-tag +@defunx remove-dead-property! resource xml-tag +@defunx remove-live-property resource xml-tag +@defunx remove-live-property! resource xml-tag +@end defun + +@c + +@deftp {GOOPS method} copy-resource (resource <resource>) include-children? [name] +Create a new resource which looks as similar as possible to the given +resource. The new resource will have the same (GOOPS) class as the +source, displayname, contentlanguage and all dead properties are +transfered, other live properties are currently not explicitly +transfered (but probably still transfered implicitly). + +The new resources name is @var{name} if given, and the name of the +original resource otherwise. + +If @var{include-children?} is true then a deep copy is performed, +otherwise no children are copied, and the resulting resource will be a +leaf node. + +Content is copied verbatim. + +@b{NOTE} currently no helper method is called, which means that extra +resources held by the resource object can't be copied. +For example, FILE can't create a copy (but it also shouldn't do that +here, but rathen when the element is ``mounted'' into the tree). +@end deftp + +@c + +@defun lookup-resource root-resource path +@end defun + + +@defun all-resources-under resource [prefix='()] +Returns the given resource, and all its children in a flat list. + +Currently depth first, but that might change. +The root resource is however guaranteed to be first. +@end defun + +@c + +@c TODO + make-live-property + live-property? + property-getter + + property-setter-generator + property-remover-generator + + prepare-update-properties + + live-properties + dead-properties + + webdav-properties + + +@node WebDAV Resource Types +@subsection Resource Types + +@subsubsection @code{(calp webdav resource base)} + +Implementation of @code{(calp webdav resource)}. Exists to possibly +avoid dependency loops. + +@subsubsection @code{(calp webdav resource calendar)} +@subsubsection @code{(calp webdav resource file)} + +Resources backed by the file system. + +@defun file-resource? x +@end defun + +@deftp {GOOPS method} children <file-resource> +@end deftp + +@deftp {GOOPS method} is-collection? <file-resource> +@end deftp + +@deftp {GOOPS method} creationdate <file-resource> +Retrived directly from the file through @command{stat -c %W $@{filename@}}. +@end deftp + +@deftp {GOOPS method} content <file-resource> +@deftpx {GOOPS method} set-content! <file-resource> data +Directly interfaced with the file. + +Data can't be retrieved for collections, and will always be +returned as a bytevector for non-collections. + +Data can be set either as a string or a bytevector. When a string is +used Guile's current encoding will be used. +@end deftp + +@subsubsection @code{(calp webdav resource virtual)} + +@node WebDAV Utilities +@subsection Utilities +@defun xml-element-hash-key xml-tag +Given an xml tag object @ref{xml-tag}, return a suitable key for +@code{hash-ref} and family. + +These key objects should preferably not be carried around for +long. Prefer to keep the @emph{real} xml-tag object, and only call +this while directly referencing the hash table. +@end defun + +@defun href->string href +HREF's are represented as lists of strings. The root resource (``/'') +is the empty list. +@end defun + +@defun string->href string +Return a href list back into a string. A leading slash will always be added. +@end defun 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/general/zic.texi b/doc/ref/general/zic.texi new file mode 100644 index 00000000..5af36fd3 --- /dev/null +++ b/doc/ref/general/zic.texi @@ -0,0 +1,135 @@ +@node Timespec +@section Timespec + +Specifiers of times, including their offset from some origin, and what +kind they are. + +Refer to zic(8) and the AT field of rules. + +@defun make-timespec time sign type + +@defun timespec? x +@end defun + +@defun timspec-time timespec +Should be a time object. +@end defun + +@defun timspec-sign timespec +@code{'+} or @code{'-} +@end defun + +@defun timspec-type timespec +char +@end defun +@end defun + +@defun timespec-zero +The ``empty'' timespec. +@end defun + +@defun timespec-add specs ... +@end defun + +@defun parse-time-spec string [suffixes='(#\s #\w #\u #\g #\z)] +More or less follows the pattern @code{-?[0-9]@{2@}(:[0-9]@{2@})@{0,2@}[swugz]}. +@end defun + + +@node Zone Info Compiler +@section Zone Info Compiler + +@defun read-zoneinfo ports-or-filenames +Takes a (possibly mixed) list of ports and filenames, and calls +@code{parse-zic-file} on each of them. +@end defun + +@c @defun parse-zic-file port +@c @end defun + +@defun zoneinfo? +@end defun + +@defun get-zone zoneinfo name +Takes a zoneinfo object, and a name as a string (probably something +like ``Europe/Stockholm''), and returns a list of zone-entries. +@end defun + +@defun get-rule zoneinfo name +Gets a list of rule objects, sorted in chronological order. +@var{name} is a symbol. +@end defun + +@defun rule->dtstart rule +Returns the first time a given rule happens. +@end defun + +@defun rule->rrule rule +Converts a given zoneinfo rule into a recurrence rule, of all times +that change occurs. +@end defun + +@defun zone-format fmt-string arg +A special case of format, which handles the format strings containing +``%s'' and ``%z''. +@end defun + + + +@defun make-rule name from to in on at save letters + +See zic(8). + +@defun rule? +@end defun + +@defun rule-name +@end defun + +@defun rule-from +@end defun + +@defun rule-to +@end defun + +@c @defun rule-type +@c @end defun + +@defun rule-in +@end defun + +@defun rule-on +@end defun + +@defun rule-at +@end defun + +@defun rule-save +@end defun + +@defun rule-letters +@end defun + +@end defun + + +@defun make-zone-entry stdoff rule format until + +See zic(8). + +@defun zone-entry? +@end defun + +@defun zone-entry-stdoff +@end defun + +@defun zone-entry-rule +@end defun + +@defun zone-entry-format +@end defun + +@defun zone-entry-until +@end defun +@end defun + |