Escape Recipes

Source: escape.spq

Functions for safely escaping values for CSV, TSV, and shell contexts, plus patterns for safe text ingestion from shell pipelines.


sk_csv_field

Escapes a string for use as a CSV field per RFC 4180. Wraps in double quotes and doubles internal quotes when the value contains commas, quotes, or newlines. Plain values pass through unchanged.

Type: function

Argument Description
s The string to escape
sk_csv_field('plain')
-- => 'plain'

sk_csv_field('hello, world')
-- => quoted and wrapped

Implementation:

fn sk_csv_field(s): (
  grep("[,\"\n]", s)
    ? f"\"{replace(s, "\"", "\"\"")}\""
    : s
)

sk_csv_row

Builds a CSV row from an array of values. Each element is cast to string and escaped with sk_csv_field, then joined with commas.

Type: function

Argument Description
arr Array of values to format as a CSV row

Implementation:

fn sk_csv_row(arr): (
  join([unnest arr | values sk_csv_field(cast(this, <string>))], ",")
)

sk_shell_quote

Wraps a string in POSIX shell single quotes. Internal single quotes are escaped so the result is safe for shell interpolation. Protects against injection of $, backticks, and other shell metacharacters.

Type: function

Argument Description
s The string to quote
sk_shell_quote('hello world')
-- => single-quoted string

sk_shell_quote('has $var')
-- => single-quoted, $ not expanded

Implementation:

fn sk_shell_quote(s): (
  f"'{replace(s, "'", "'\\''")}'"
)

sk_tsv_field

Escapes a value for use in a TSV field. Casts to string, then replaces literal tab and newline characters with their backslash-escaped forms.

Type: function

Argument Description
s The value to escape

Implementation:

fn sk_tsv_field(s): (
  replace(replace(cast(s, <string>), "\t", "\\t"), "\n", "\\n")
)

Shell Patterns for Safe Text Ingestion

The key insight: never interpolate untrusted text into a SuperQL string literal. Pipe raw text through super with -i line and let the serializer handle escaping. These patterns work from any language that can spawn a subprocess.

safe_text_to_record

Pipe raw text into super to build a record without string interpolation.

echo "$text" | super -s -i line -c "values {body: this}" -

safe_text_to_string

Pipe raw text through super to get a properly escaped SUP string literal.

echo "$text" | super -s -i line -c "values this" -

safe_multiline_to_record

Collapse multiline text into a single record field.

echo "$text" | super -s -i line \
  -c 'aggregate s:=collect(this) | values {body: join(s, "\n")}' -

safe_append_to_sup_file

Append a timestamped record with raw text to a .sup file.

echo "$text" | super -s -i line \
  -c "values {ts: now(), body: this}" - >> data.sup

This site uses Just the Docs, a documentation theme for Jekyll.