# How to Write and Read VSV files

A VSV file consists of two types of rows: **header** and **data**. All values in these rows are separated by delimiters.

This is the main idea. The identification of rows and delimiters allows VSV extreme versatility to serve as different types of applications (e.g. list, table, objects, markup, playlist, etc.).

Rows are separated by newline.

Read further to learn how to write (export, create) and to read (import) VSV files.

# Export to VSV (Creating files)

## Creating Header Rows

A header row consists of one or more header field. Each header field is enclosed by any of these double matching bracket types:
[[]] {{}} (()) <<>>
A header row is identified when, ignoring the opening spaces of a row, the first two characters of a row are any consecutive double opening brackets, as listed above.

Distinct header fields may use the same or different brackets types. Different bracket types may be employed on the same header row and across rows.

When exporting to a VSV file, characters that are found within a header field must not be used as enclosing brackets for that field. Choose a bracket not found in that inside text to surround that field.

Any text in a header row that is not within the legal boundaries of a header field is ignored. That includes improper closing of brackets, and text outside the brackets. This side effect may be surreptitiously used as comments for your text file, but should be used with care, in order to be properly rendered by plugins. (That is, a plugin cannot safely interpret if your intent is a comment or an error, a typo.)

### Examples of Header Rows
[[Name]] [[Age]] [[Item]] ((Cost)) {{Date}}
## Creating Data Rows

Data rows (non headers) must be led by an explicit nonspace character, called delimiter. All leading spaces are ignored until a nonspace character is found, which becomes the delimiter for that row.

Values for a data row are placed between two delimiters. The first occurrence of a delimiter on that row is not counted as part of the values. To prevent delimiter-value collision, the delimiter should be a character that is not found in the values' texts of that row.

A null value has zero length, signified by consecutive delimiters with nothing in between them.

A delimiter at the end of the line after the final value is optional, unless the final value is a null value.

Each row may have its own distinct delimiter. A text file may have distinct rows with their own delimiters. Creators can use the same delimiters or mix them for different rows, as long as the desired values on that row are distinguishable (i.e. to prevent delimiter-value collision.)

When exporting to a VSV file, characters that are found in the values of a given row must not be used as delimiter for that row. Choose a character not found in that row's values as the delimiter for that row.

Other things to note:

- Space and newline cannot be used as delimiter. Any other single character may be used.
- Letters and numbers may be used as delimiters, but are not recommended.
- Avoid using header field brackets as data row delimiters. Nevertheless, a single bracket at the beginning of a row should be read as a legal delimiter of a data row. (However, note VON uses single bracket delimiters to denote various container types.)
- Creators may have their own preferred delimiters. Common delimiters to use:
, : | ; * - = @ # % ~ TAB `
### Examples of Data Rows
,A,apple #f#https://ieants.cc/code/vsv/ =Monday=Tuesday=Wednesday=Thursday=Friday=Saturday=Sunday= * Ball game * Stadium * Thursday 2018/04/19 * Seat A124
# Import from VSV (Reading files)

The following rules dictate how plugins and libraries should read and interpret VSV files.

Rows are separated by newline. Leading spaces on each row are discarded and ignored.

After discarding all leading spaces, if the first two characters of a row are identical opening brackets, this is a header row. Else it is a data row.

## Reading Header Rows

Header fields must be enclosed by both an opening and a closing matching double brackets. Any other text on a header row is discarded and ignored.

Header fields in header rows can be matched with regexp. Field names are stored inside matching opening and closing double brackets. A row can have zero or more fields.

## Reading Data Rows

The first nonspace character of a data row is its delimiter. The values of this row are stored between two delimiters or the end of line. A value can have zero length, or null value. There is no value between a line-ending delimiter and end of line (it doesn't count as another value, not even null value).

In code, get the delimiter (the first nonspace character) of the row. Then split the string of the entire row by the delimiter, and store all the data into an array. In PHP, use the explode() function. Likewise, in Javascript, use String.prototype.split(). For other languages, use a regexp to match the values separated by the delimiter.

# Afterthoughts

A VSV file is very legible to both humans and machines. Due to very simple, consistent rules in writing and reading the text.

This means it very easy to write a simple loop or function to capture all the headers and data. No need to create complex tokens and parsers. No extraneous escapes, like double quotes " or angled brackers <> everywhere. No need to make complex tables, like Markdown or Wikitables.

All the data is very easy to access and manipulate once stored into an array. They can be easily converted into other formats and purposes, including HTML lists and tables, programming objects, page markup, playlist, subtitles, site summary syndication, etc. The resulting file size is generally much smaller compared to other popular formats (cf. XML, JSON), and provides much greater versatility, utility, and consistency than CSV.