CROSSBOW(5) File Formats Manual (urm) CROSSBOW(5)

crossbow-outfmtOutput format reference

crossbow outfmt -f format -o output_mode [...]

Feeds that are registered for monitoring with crossbow-add(1) are individually associated to an output mode that determines how new (stories, articles, etc) are handled by crossbow-fetch(1).

The default output mode is called print and consists in printing to stdout(3) all the properties of the item. The pretty mode also prints on stdout(3), but allows the user to define a custom textual representation in place of the default one. The last two modes, subproc and pipe, correspond to two flavours of parametric subprocess execution.

All output modes, except for print, require a format string as an additional parameter. A format string can contain a number of placeholders, that are expanded with the properties of each handled item. The syntax of placeholders resembles the printf(3) function, with some differences and simplifications:

The interpretation of the format string depends on the output mode.

If the output mode is pretty, the format string is treated as a template for the textual representation of each item. The placeholders are expanded with the string representation of the corresponding properties (listed below), and the resulting string is printed to stdout(3).

If the output mode is subproc or pipe, the format string is split on white-space into an array of tokens, and the placeholders are expanded for each of them. The obtained array is interpreted as a command line, with the first token being the command to execute, and the subsequent being the arguments. For security reasons the command line is not parsed by a shell interpeter.

Quotation is currently not supported, thus literal white-spaces must be individually escaped by backslash characters ("\").

Please mind security when using the subproc and pipe modes. The invocation of a shell interpreter as subcommand is especially discouraged, as a specially crafted feed item might result in remote command execution.

Follows a list of the supported placeholders, and the corresponding fields of a struct mrss_item_t data type (see library “libmrss”). Each field correspond to one property of a feed item:

%a
author
%am
author_email
%au
author_uri
%cm
contributor_email
%co
contributor
%cm
contributor_email
%cu
contributor_uri
%cr
copyright
%ct
copyright_type
%d
description
%dt
description_type
%en
enclosure
%el
enclosure_length
%et
enclosure_type
%eu
enclosure_url
%g
guid
%gp
guid_isPermaLink
%l
link
%pd
pubDate
%sr
source
%su
source_url
%t
title
%tt
title_type

The following extra placeholders are also available for each item:

%fi
The string identifying, in crossbow(1), the feed this item belongs to.
%ft
The feed title, as reported by the feed XML. It corresponds to is the field of the struct mrss_t data type. (see library “libmrss”).
%n
A per-feed six digit incremental number. This value is set to zero when the feed is initially registered via crossbow-set(1), and gets incremented by one for every new feed item.

This is an important security feature: the value of this number is not controlled by the feed, thus it can be used safely as filename. See crossbow-cookbook(7).

The value is padded with zero to make lexicographical order trivial. Increment happens even when the execution of a subprocess fails, so that the same value is never used twice.

The language recognized by the output format parser allows the placeholders to be composed by multiple characters. While this feature makes it easier to have mnemonic placeholders (such as "%a" for "Author" and "%am" for "Author eMail"), it introduces some additional edge cases.

The zero-width break sequence ("\:") has been introduced to cover a case of ambiguity which can be easily explained by means of an example.

Let's consider the case in which both "%x" and "%xn" are valid placeholders. In such case it would get impossible to express the expansion of "%x" followed by a literal "n", as the sequence "%x\n" would be rendered as the expansion of "%x" followed by a new-line, while "%xn" would be rendered as the expansion of "%xn".

The behaviour is summarized by the following table, where expresses the expansion of the "%x" placeholder into the string representation of the corresponding , and the "." operator expresses string concatenation.

"%x"
expand(x)
"%xn"
expand(xn)
"%x\m"
expand(x) . "m"
"%x\n"
expand(x) . "\n"
"%x\:n"
expand(x) . "n"

By supplying crossbow-fetch(1) with the -d flag, it is possible to test the configuration to work as intended without marking new items as seen. The -D flag can be used simultaneously to prevent the execution of sub-commands in case the feed is configured with the subproc or pipe output modes.

When verifying the correctness of a feed configuration, it might be useful to restrict the fetch operation to the such feed by means of the -i flag:

$ crossbow fetch -i some-feed

See crossbow-cookbook(7) for a collection of short recipes.

crossbow(1), crossbow-del(1), crossbow-fetch(1), crossbow-query(1), crossbow-set(1)

Giovanni Simoni <dacav@fastmail.com>

July 11, 2020