[![crates.io](https://img.shields.io/crates/v/csvpp.svg)](https://crates.io/crates/csvpp) [![github workflow](https://github.com/patrickomatic/csv-plus-plus/actions/workflows/rust.yml/badge.svg)](https://github.com/patrickomatic/csv-plus-plus/actions) [![dependency status](https://deps.rs/repo/github/patrickomatic/csv-plus-plus/status.svg)](https://deps.rs/repo/github/patrickomatic/csv-plus-plus) [![codecov](https://codecov.io/github/patrickomatic/csv-plus-plus/graph/badge.svg?token=RWNEXNQT91)](https://codecov.io/github/patrickomatic/csv-plus-plus) # csv++ csv++ is a superset of [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) which allows you to author spreadsheets in a text file then compile that to your target spreadsheet (Excel, Google Sheets or even back to CSV). Since csv++ is a superset of CSV any CSV document is valid: ```csvpp Sum,Column 1,Column 2, =5*SUM(B2,C2),,, ``` However you can extract reusable variables and functions by making a code section at the top, separated from the cells with a `---`. Here's the same spreadsheet but extracted out into variables and functions: ```csvpp # you can define variables with `:=` multiplier := 5 # functions look like this and have a single expression as their body fn my_fn(a, b) multiplier * SUM(a, b) --- Sum , Column 1, Column 2, "=my_fn(B2, C2)" , , , ``` One more useful feature is the ability to bind variables to a cell. You can use the `[[`/`]]` syntax on the cell you want to bind it on. ```csvpp fn my_complex_fn(a, b) a * a + SQRT(b) --- Complex function , Column 1 , Column 2 , "=my_complex_fn(a, b)", [[var=a]] , [[var=b]], ``` > **_NOTE:_** The following is just a brief walkthrough, for the full documentation please refer to the [user guide](https://patrickomatic.github.io/csv-plus-plus/language_reference/index.html). ## Fills Another useful feature is to define a range of rows which fill out (either infinitely or by a finite amount) in the compiled spreadsheet. To specify one you use the row-option syntax which is similar to above, you just prefix it with `!`: `![[`/`]]`. ```csvpp Product Name , Quantity , Price per Unit , =SUM(D2:D12) ![[fill=10]] , [[var=quantity]] , [[var=price]] , =quantity * price ``` This will take the second row and repeat it 10 times in the final spreadsheet. If you wanted it to be repeated until the end of the spreadsheet just leave off the `=10` and specify it as `![[fill]]`. ## Variable Scoping The variable scoping semantics are pretty unique because every function call is evaluated relative to the cell where it is used. As you've seen above you can use `[[var=...]]` to bind a variable name to a given cell. As an example of scoping semantics we'll use this csv++ template: ```csvpp foo_from_code_section := 42 --- [[var=bar_outside_fill]] , , , , , ![[fill=2]]bar , [[var=bar_in_fill]] , =bar_in_fill , =bar_outside_fill , =foo_from_code_section, ``` which will compile to: ```csv , , , , bar , , =B2 , =A1 , =42 bar , , =B3 , =A1 , =42 ``` Breaking this down: * `foo_from_code_section` - Is always `42` no matter where it is used. * `bar_in_fill` - Since it is defined within an `![[fill]]`, it's value depends on the final row, which will be `B2` or `B3` * `bar_outside_fill` - Will always be `A1`, pointing to the cell where it was defined. There is no relative aspect to it since it's not defined in an `fill`. ## Importing Code csv++ allows you to import and re-use functions and variables with the `use` statement: #### `my_math_constants.csvpp` ```csvpp pi := 3.14159 e := 2.7182818284 --- ``` #### `main.csvpp` ```csvpp use my_math_constants fn circumference_from_diameter(r) r * 2 * pi fn radius_to_diameter(r) 2 * r fn circumference_from_radius(r) radius_from_diameter(radius_to_diameter(r)) --- Radius ,Circumference , [[var=radius]] ,"=circumference_from_radius(radius)" , ``` ## Formatting You can apply basic cell formatting which will either apply for the entire row or just for individual cells. To apply formatting to individual cells use the `[[`/`]]` syntax: ```csvpp [[text=bold text=underline]]foo,[[fontsize=20]]bar,baz, ``` and here is the same thing using short-hand: ```csvpp [[t=b t=u]]foo,[[fs=20]]bar,baz, ``` To format the entire row you can use `![[`/`]]` at the beginning of the line ```csvpp ![[t=b t=u]]foo,bar,baz, ``` For a full list of formatting features, take a look at the [user guide](https://patrickomatic.github.io/csv-plus-plus/language_reference/index.html) ### Additional Reading * [User Guide](https://patrickomatic.github.io/csv-plus-plus/) * [Installation](https://patrickomatic.github.io/csv-plus-plus/installation.html) * [Examples](https://github.com/patrickomatic/csvpp-examples) * [Changelog](docs/CHANGELOG.md) * [Want to Contribute?](docs/CONTRIBUTING.md) * [csvpp on crates.io](https://crates.io/crates/csvpp)