From bf3b96030781b5e682b79d4f0220b8da44430ffb Mon Sep 17 00:00:00 2001 From: Tiffany Bennett Date: Fri, 29 Mar 2024 19:15:53 -0700 Subject: [PATCH] Better packaging (#158) I want rink to adhere slightly better to conventions on Linux. - Adds man pages for the CLI and for the config file format, using asciidoc. - Updates the bundling functionality. It doesn't make sense to bundle these files when building a distro package, they should go in `/usr/share`. - Adds a makefile with good defaults for distro packages. The asciidoc files will likely become the new source of truth for rink's documentation. There is no way to make PRs to github wikis, so this might be for the best anyway. Currently rink is packaged on arch, nix, and void linux. --- Makefile | 59 ++++ PACKAGING.md | 46 +++ cli/Cargo.toml | 4 + cli/src/config.rs | 35 ++- core/Cargo.toml | 4 +- core/src/helpers.rs | 26 +- docs/rink-dates.5.adoc | 119 +++++++ docs/rink-defs.5.adoc | 278 +++++++++++++++++ docs/rink.1.adoc | 70 +++++ docs/rink.5.adoc | 153 +++++++++ docs/rink.7.adoc | 685 +++++++++++++++++++++++++++++++++++++++++ rink-js/Cargo.toml | 2 +- rink-js/src/lib.rs | 2 +- 13 files changed, 1456 insertions(+), 27 deletions(-) create mode 100644 Makefile create mode 100644 PACKAGING.md create mode 100644 docs/rink-dates.5.adoc create mode 100644 docs/rink-defs.5.adoc create mode 100644 docs/rink.1.adoc create mode 100644 docs/rink.5.adoc create mode 100644 docs/rink.7.adoc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1f426d1 --- /dev/null +++ b/Makefile @@ -0,0 +1,59 @@ +SHELL = /bin/sh + +CARGO := cargo +FETCHFLAGS := --locked +CARGOFLAGS := --release --locked --offline --no-default-features +ASCIIDOCTOR := asciidoctor +MANFLAGS := -b manpage -D build +HTMLFLAGS := -D build -a toc=left -a toclevels=3 -a sectlinks +INSTALL := install + +prefix := /usr/local +DESTDIR := $(prefix) +bindir := $(DESTDIR)/bin +datarootdir := $(DESTDIR)/share +datadir := $(datarootdir) +mandir := $(datarootdir)/man +man1dir := $(mandir)/man1 +man5dir := $(mandir)/man5 +man7dir := $(mandir)/man7 +srcdir := . + +RINK_PATH := $(prefix)/share/rink +export RINK_PATH + +all: bin man + +fetch: + $(CARGO) fetch $(FETCHFLAGS) + +bin: + $(CARGO) build $(CARGOFLAGS) -p rink + +test: + $(CARGO) test $(CARGOFLAGS) --all + +man: + $(ASCIIDOCTOR) $(MANFLAGS) $(srcdir)/docs/rink.1.adoc + $(ASCIIDOCTOR) $(MANFLAGS) $(srcdir)/docs/rink.5.adoc + $(ASCIIDOCTOR) $(MANFLAGS) $(srcdir)/docs/rink.7.adoc + $(ASCIIDOCTOR) $(MANFLAGS) $(srcdir)/docs/rink-defs.5.adoc + $(ASCIIDOCTOR) $(MANFLAGS) $(srcdir)/docs/rink-dates.5.adoc + +htmldoc: + $(ASCIIDOCTOR) $(HTMLFLAGS) $(srcdir)/docs/rink.1.adoc + $(ASCIIDOCTOR) $(HTMLFLAGS) $(srcdir)/docs/rink.5.adoc + $(ASCIIDOCTOR) $(HTMLFLAGS) $(srcdir)/docs/rink.7.adoc + $(ASCIIDOCTOR) $(HTMLFLAGS) $(srcdir)/docs/rink-defs.5.adoc + $(ASCIIDOCTOR) $(HTMLFLAGS) $(srcdir)/docs/rink-dates.5.adoc + +install: all + $(INSTALL) -Dm 0755 target/release/rink -t $(bindir) + $(INSTALL) -Dm 0644 $(srcdir)/core/definitions.units -t $(datadir)/rink + $(INSTALL) -Dm 0644 $(srcdir)/core/datepatterns.txt -t $(datadir)/rink + $(INSTALL) -Dm 0644 $(srcdir)/core/currency.units -t $(datadir)/rink + $(INSTALL) -Dm 0644 build/rink.1 -t $(man1dir) + $(INSTALL) -Dm 0644 build/rink.5 -t $(man5dir) + $(INSTALL) -Dm 0644 build/rink.7 -t $(man7dir) + $(INSTALL) -Dm 0644 build/rink-defs.5 -t $(man5dir) + $(INSTALL) -Dm 0644 build/rink-dates.5 -t $(man5dir) diff --git a/PACKAGING.md b/PACKAGING.md new file mode 100644 index 0000000..126de69 --- /dev/null +++ b/PACKAGING.md @@ -0,0 +1,46 @@ +# Distro Packaging + +Requirements: + +- Rust compiler toolchain (stable build) +- `asciidoctor` for building manpages +- `make` + +Rink requires several data files in order to work. By default these are +baked into the binary so that `cargo install` will work, but for distro +packaging these should probably go into `/usr/share` instead. The +makefile will do this automatically. + +## Makefile-based method + +```sh +make fetch +make all prefix=/usr +make install prefix=/usr DESTDIR=$pkgdir +``` + +A makefile is provided for easier packaging. + +Running `make all` will build both the program and the man pages, and +`make install` will install them. + +Note that the makefile accepts _both_ the `prefix` and `DESTDIR` +arguments. `prefix` is where Rink should look for its files, this should +generally be `/usr`. `DESTDIR` is where the files will be copied to upon +running `make install`. + +## Manual packaging + +Build the program using cargo. The RINK_PATH environment variable can be +set to something like `/usr/share/rink` so that rink will look in this +directory for its files. Passing `--no-default-features` will turn off +rink bundling the files into its executable file. + +Build the manpages in `docs/` using asciidoctor. + +1. Install `target/release/rink` -> `/usr/bin/rink`. +2. Install `core/definitions.units` -> + `/usr/share/rink/definitions.units`. +3. Install `core/currency.units` -> `/usr/share/rink/currency.units`. +4. Install `datepatterns.txt` -> `/usr/share/rink/datepatterns.txt`. +5. Install the manpages into the relevant directories. diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 48502c9..a9eb355 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -10,6 +10,10 @@ keywords = ["unit", "math", "conversion", "cli", "tool"] categories = ["command-line-utilities", "mathematics", "science"] edition = "2018" +[features] +default = ["bundle-files"] +bundle-files = ["rink-core/bundle-files"] + [dependencies] clap = "3" dirs = "4" diff --git a/cli/src/config.rs b/cli/src/config.rs index f61a394..095e3bb 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -254,6 +254,21 @@ fn load_live_currency(config: &Currency) -> Result { serde_json::from_str(&contents).wrap_err("Invalid JSON") } +fn try_load_currency(config: &Currency, ctx: &mut Context, search_path: &[PathBuf]) -> Result<()> { + let base = read_from_search_path("currency.units", search_path) + .or_else(|err| CURRENCY_FILE.map(ToOwned::to_owned).ok_or(err)).wrap_err("Rink was not built with a bundled currency.units file, and one was not found in the search path.")?; + + let mut base_defs = gnu_units::parse_str(&base); + let mut live_defs = load_live_currency(config)?; + + let mut defs = vec![]; + defs.append(&mut base_defs.defs); + defs.append(&mut live_defs.defs); + ctx.load(ast::Defs { defs }).map_err(|err| eyre!(err))?; + + Ok(()) +} + pub fn read_config() -> Result { match read_to_string(config_path("config.toml")?) { // Hard fail if the file has invalid TOML. @@ -271,14 +286,17 @@ pub fn load(config: &Config) -> Result { if let Some(config_dir) = dirs::config_dir() { search_path.push(config_dir); } + if let Some(prefix) = option_env!("RINK_PATH") { + search_path.push(prefix.into()); + } // Read definitions.units let units = read_from_search_path("definitions.units", &search_path) - .or_else(|err| DEFAULT_FILE.map(ToOwned::to_owned).ok_or(err).wrap_err("Rink was not built with a bundled definitions file, and one was not found in the search path."))?; + .or_else(|err| DEFAULT_FILE.map(ToOwned::to_owned).ok_or(err).wrap_err("Rink was not built with a bundled definitions.units file, and one was not found in the search path."))?; // Read datepatterns.txt let dates = read_from_search_path("datepatterns.txt", &search_path) - .unwrap_or_else(|_| DATES_FILE.to_owned()); + .or_else(|err| DATES_FILE.map(ToOwned::to_owned).ok_or(err).wrap_err("Rink was not built with a bundled datepatterns.txt file, and one was not found in the search path."))?; let mut ctx = Context::new(); ctx.save_previous_result = true; @@ -288,17 +306,8 @@ pub fn load(config: &Config) -> Result { // Load currency data. if config.currency.enabled { - match load_live_currency(&config.currency) { - Ok(mut live_defs) => { - let mut base_defs = gnu_units::parse_str( - &read_from_search_path("currency.units", &search_path) - .unwrap_or_else(|_| CURRENCY_FILE.to_owned()), - ); - let mut defs = vec![]; - defs.append(&mut base_defs.defs); - defs.append(&mut live_defs.defs); - ctx.load(ast::Defs { defs }).map_err(|err| eyre!(err))?; - } + match try_load_currency(&config.currency, &mut ctx, &search_path) { + Ok(()) => (), Err(err) => { println!("{:?}", err.wrap_err("Failed to load currency data")); } diff --git a/core/Cargo.toml b/core/Cargo.toml index ee3f15b..f9dd317 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -10,8 +10,8 @@ keywords = ["unit", "math", "conversion"] edition = "2018" [features] -default = ["chrono-humanize", "gpl"] -gpl = [] +default = ["chrono-humanize"] +bundle-files = [] [dependencies] num = { version = "0.4.0", features = ["serde"] } diff --git a/core/src/helpers.rs b/core/src/helpers.rs index 4244533..77ee95a 100644 --- a/core/src/helpers.rs +++ b/core/src/helpers.rs @@ -9,13 +9,20 @@ use crate::{ Context, }; -#[cfg(feature = "gpl")] +#[cfg(feature = "bundle-files")] pub static DEFAULT_FILE: Option<&'static str> = Some(include_str!("../definitions.units")); -#[cfg(not(feature = "gpl"))] +#[cfg(not(feature = "bundle-files"))] pub static DEFAULT_FILE: Option<&'static str> = None; -pub static DATES_FILE: &str = include_str!("../datepatterns.txt"); -pub static CURRENCY_FILE: &str = include_str!("../currency.units"); +#[cfg(feature = "bundle-files")] +pub static DATES_FILE: Option<&'static str> = Some(include_str!("../datepatterns.txt")); +#[cfg(not(feature = "bundle-files"))] +pub static DATES_FILE: Option<&'static str> = None; + +#[cfg(feature = "bundle-files")] +pub static CURRENCY_FILE: Option<&'static str> = Some(include_str!("../currency.units")); +#[cfg(not(feature = "bundle-files"))] +pub static CURRENCY_FILE: Option<&'static str> = None; pub fn eval(ctx: &mut Context, line: &str) -> Result { ctx.update_time(); @@ -41,18 +48,17 @@ pub fn one_line(ctx: &mut Context, line: &str) -> Result { } /// Tries to create a context that has core definitions only (contents -/// of definitions.units), will fail if the GPL feature isn't enabled. +/// of definitions.units), will fail if the bundle-files feature isn't enabled. /// Mainly intended for unit testing. pub fn simple_context() -> Result { - let units = match DEFAULT_FILE { - Some(units) => units, - None => return Err("GPL feature not enabled, cannot create simple context.".to_owned()), - }; + let message = "bundle-files feature not enabled, cannot create simple context."; + let units = DEFAULT_FILE.ok_or(message.to_owned())?; let mut iter = gnu_units::TokenIterator::new(&*units).peekable(); let units = gnu_units::parse(&mut iter); - let dates = crate::parsing::datetime::parse_datefile(DATES_FILE); + let dates = DATES_FILE.ok_or(message.to_owned())?; + let dates = crate::parsing::datetime::parse_datefile(dates); let mut ctx = Context::new(); ctx.load(units)?; diff --git a/docs/rink-dates.5.adoc b/docs/rink-dates.5.adoc new file mode 100644 index 0000000..3b15b7e --- /dev/null +++ b/docs/rink-dates.5.adoc @@ -0,0 +1,119 @@ += rink-dates(5) +:manmanual: Rink Manual +:mansource: Rink Manual + +Name +---- + +rink-dates - Rink file format for date patterns + +Synposis +-------- + +Rink allows specifying datetimes using **\#date#** syntax in queries. This +file defines the patterns that are used to try to match the specified +date. + +Description +----------- + +Blank lines are ignored. Lines starting with # are ignored. + +A date pattern is a sequence of keywords which each specify a token to +match. part of the sequence can be wrapped with [] to make it optional. + +The valid keywords are: + +**fullyear**:: + The full 4 digit year, like 2024. Must be exactly 4 digits. + +**shortyear**:: + Shortened 2-digit year, like 24. Must be exactly 2 digits. + +**century**:: + The year with the last 2 digits cut off, like 20. Not the same as + the actual century number (which would be 21). Must be exactly 2 digits. + +**monthnum**:: + The current month number, like 03. Must be exactly 2 digits. + +**day**:: + The current day of the month, like 3. Can be any number of digits. + +**fullday**:: + The current day of the month, like 03. Must be exactly 2 digits. + +**min**:: + The current minute of the hour, like 05. Must be exactly 2 digits. + +**ordinal**:: + The current day of the year, like 083. Must be exactly 3 digits. + +**isoyear**:: + The ISO year, like -0001. Must be exactly 4 digits. ISO year unifies + CE and BCE such that 1BC is year 0, and 2BCE is year -1. + +**unix**:: + Unix timestamp, i.e. the number of 1/86400ths of a day elapsed since + January 1st, 1970. Can be any number of digits. + +**year**:: + The current year, like 2024. Can be any number of digits. + +**adbc**:: + Looks for `ad`, `ce`, `bc`, or `bce` (case insensitive). This allows + specifying dates prior to year 1 CE. + +**hour12**:: + The current hour on a 12-hour clock. Must be exactly 2 digits. + +**hour24**:: + The current hour on a 24-hour clock. Must be exactly 2 digits. + +**meridiem**:: + Looks for `am` or `pm` (case insensitive). This allows specifying + 12-hour time. + +**sec**:: + The current second of the current minute. Must be exactly 2 digits. + Can optionally have a decimal point to specify time smaller than a + second. + +**offset**:: + Matches a timezone offset. This can either be the name of a timezone + like `US/Pacific` or a fixed offset. The fixed offset can either be + in the form +07:00 or +0700. + +**monthname**:: + Matches English month names, case insensitive. Recognizes 3-letter + names (like jan, feb, mar) and full names. + +**weekday**:: + Makes English weekday names, case insensitive. Recognizes 3-letter + names (like mon, tue, wed) and full names. + +**`-`**:: + Matches a literal `-` character. + +**`:`**:: + Matches a literal `:` character. + +` `:: + A single space will match any amount of whitespace. + +**`'`** <__anything__> **`'`**:: + Wrapping text in single quotes will match that text literally. + +Files +----- + +Rink searches the following locations: + +* `./rink/datepatterns.txt` +* `__$XDG_CONFIG_DIR__/rink/datepatterns.txt` +* `/usr/share/rink/datepatterns.txt` + +See also +-------- +xref:rink.1.adoc[rink(1)], xref:rink.5.adoc[rink(5)], +xref:rink.7.adoc[rink(7)], xref:rink-defs.5.adoc[rink-defs(5)] diff --git a/docs/rink-defs.5.adoc b/docs/rink-defs.5.adoc new file mode 100644 index 0000000..ea2c855 --- /dev/null +++ b/docs/rink-defs.5.adoc @@ -0,0 +1,278 @@ += rink-defs(5) +:manmanual: Rink Manual +:mansource: Rink Manual + +Name +---- + +rink-defs - Rink's `definition.units` format + +Description +----------- + +The units database is a textual document containing the definitions of +units, prefixes, base units, quantities, and substances. + +Comments start with `#` and continue to the end of the line. Blank lines +are ignored. Comments can be placed on the same line as units, at the +end. + +[listing] + # This line is a comment + # And so is this + +Units +~~~~~ + +Units are defined with their name and their definition separated by +whitespace. A definition can be broken over multiple lines using `\` if +desired. + +[listing] +foot 12 inch + +Documentation comments are lines starting with `??`. They apply to the +next definition following them. They are shown to end users in Rink when +you query a definition. + +[listing] +?? International yard and pound, since July 1, 1959. +?? Documentation comments can be broken over +?? multiple lines. +foot 12 inch + +Substances +~~~~~~~~~~ + +Substances can represent either a specific object (such as the Earth, or +the Sun), a material such as water or concrete, a chemical molecule, an +element of the periodic table, or an elementary particle. + +A substance has a name, an optional symbol (used for chemical formulas), +and contains a list of properties inside of a {} block. + +Properties can either be "const", which is mainly used for countable +objects such as a particle, or they can be a ratio, such as the density +of a material. + +[listing] +neutron { + mass const neutron_mass 1.00866491588 u + wavelength const neutron_wavelength planck_constant / mass c + magnetic_moment const neutron_moment -0.96623650e-26 J/T +} + +The two syntax variants for properties are: + +[listing] + [name] const [output name] [expression] + [name] [input name] [input expression] / [output name] [output expression] + +Categories +~~~~~~~~~~ + +Units inside the same category will be grouped together in the UI when +doing searches and other operations. A category is started using the +`!category` pragma which takes an identifier (`lower_snake_case`) and a +display name as a string literal. + +[listing] +!category us_survey "US survey measures" + +Base units +~~~~~~~~~~ + +Base units are impossible to define in terms of another unit without +creating a cycle. They represent fundamental physical quantities such as +time, length, temperature, etc. + +The name is a shorthand form which is used when showing dimensionality +(for example, the dimensionality of `acceleration` is `m / s^2`), while +the long form is used for display purposes. + +New base units should only be added when there is a clear value to doing +so. Examples include radians and bits. + +[listing] +?? Equal to the mass of the international prototype of the +?? kilogram. 3rd CGPM (1901, CR, 70). +kg !kilogram + +Quantities +~~~~~~~~~~ + +Quantities are shown in parentheses whenever rink displays a unit. +They're very helpful for dimensional analysis, as it can be hard to +remember that `kg m^2 / s^2` means the physical quantity of energy. + +Quantities are defined similar to units, but the definition starts with +a ? character. Quantities are in a separate namespace from units, so the +only valid names that can be used are the base units as well as other +quantities. + +Unlike units, quantities have no numerical value (not even a value of +1 like SI derived units). + +[listing] +length ? meter +area ? length^2 + +Prefixes +~~~~~~~~ + +Prefixes allow input of units like `gigabytes`, `megameters`, +`kiloseconds` without needing to explicitly define each one in the units +database. Prefixes are always dimensionless. + +These should not be added frequently, only when it's relevant to some +counting system. Examples include power of two byte prefixes (MiB, GiB, +etc.) and Dozenal prefixes. + +Prefixes are split into two types, "long" prefixes and "short" prefixes. +Short prefixes should generally only be 1 letter. Typically, short +prefixes are aliases of their corresponding long prefix. + +Prefixes are defined similar to other units, but the name ends with a +suffix of `-` (long prefixes) or `--` (short prefixes). + +Prefixes use their own namespace. Their definitions can only reference +other prefixes, and not units. + +[listing] +kilo- 1e3 +k-- kilo + +Guidelines +---------- + +These guidelines mainly apply when contributing to the upstream +`definitions.units`. + +The units database should generally be wrapped so that it fits within +80 columns, for ease of reading. Similarly, units definitions should +generally be aligned vertically using spaces. + +Non-trivial units should generally have a documentation comment. This +comment can explain what the unit means, as well as providing a citation +for its value. + +If there are multiple ways to interpret how a unit should be defined, +then mention which interpretation is being used. Unless it's implied by +the name (e.g. `siderealyear`). Examples where units have multiple +interpretations include: + +* Customary units may vary by country, and may even vary depending on + which year in that country. Such as US, British, Australian, and + International definitions of the foot. +* Units that are inherently fuzzy or represent multiple sources. This + may include days (calendar, sidereal), years (calendar, sidereal, + tropical), and others. + +Doc comments should be written in US English. They should have sentence +capitalization and full stops, like this guide is written in. Avoid +run-on sentences. + +External links should include the protocol part (`https://`, `http://`). +They should be wrapped with angle brackets, like ``. + +Dates should be written in a longhand format such as `July 5th, 1982`. +Do not use ambiguous formats like 2/3/99. It's often sufficient to only +state the year. + +Comments in the definitions file are written for the benefit of other +maintainers. They can include explanations for why units are defined a +certain way. They can also state that certain units are part of a group +or set. + +All units should be inside of a `!category` / `!endcategory` block. +Category blocks should also enclose comments related to that category, +and the `!category` pragma should immediately follow the last category's +`!endcategory`. This is to allow the file to be easily browsed using Vim +folds. The display name of a category should be in sentence case, and +should be aligned to the 70th column. + +NAMING +~~~~~~ + +English names should be lowercase without separators. Words may be +separated by underscores when it adds clarity. Examples include `foot`, +`olympiccubit`, `usgallon`. + +If a shorthand is available, it should be added as an alias of the +longer name. Examples include `ft` for `foot`, `B` for `byte`, and `Ω` +for `ohm`. + +[listing] +ft foot + +Some units are most commonly written in a non-Latin script. Use the +non-Latin name as the canonical name, and add an ASCII-based one as an +alias. Examples include `золотник`, `分地`. + +Some units are typically written with a symbol. Treat these similar to +the non-Latin script names. Examples include `π` (Pi), `τ` (Tau). + +Legacy Unicode symbols should only be used as aliases of more standard +names. This includes uncommon symbols such as `㎒` (Unicode symbol for +Megahertz). + +If there are multiple names for a unit, then the one that's most typical +should be the "canonical name". The canonical version should have the +full definition, and the other names should be added as aliases pointing +to the canonical version. Avoid duplicating the definition. + +DEFINITIONS +~~~~~~~~~~~ + +Units should be defined in terms of other related units when possible. +The expression you use to define the unit will be visible to the end +user. For example, a foot is defined as `12 inch` rather than as `304.8 +mm`. This is because there is already a separate entry for `inch` +defined as `2.54 mm`. When displaying a unit's definition, Rink shows +both the original definition as well as the absolute value. So for +`foot` it shows that it's defined as `12 inch` which equals `304.8 +millimeter`. + +Rink can represent arbitrary precision rational numbers. The only +limitation is how much memory is available. As a result, irrational +numbers like Pi or Euler's constant should be defined to at least 20 +digits. + +Universal constants that are measured experimentally should have as many +significant figures as are currently known. For example, if a number is +known to ±0.000003, then it should be listed to 6 digits after the +decimal point. + +Files +----- + +Rink searches for the definitions file in these locations: + +* `./rink/definitions.units` +* `$XDG_CONFIG_DIR/rink/definitions.units` +* `/usr/share/rink/definitions.units` + +When live currency fetching is enabled, Rink also looks for a currency +file in these locations: + +* `./rink/currency.units` +* `$XDG_CONFIG_DIR/rink/currency.units` +* `/usr/share/rink/currency.units` + +History +------- + +Rink's units database was originally based on GNU Units and inherits +much of its syntax from there. + +Notable differences include: + +- Removal of `!locale`, `!set`, `!utf8`, and other pragmas not used by Rink. +- Addition of `!category` and `!endcategory`. +- Addition of documentation comments starting with `??`. +- Addition of substances. + +See also +-------- +xref:rink.1.adoc[rink(1)], xref:rink.5.adoc[rink(5)], +xref:rink.7.adoc[rink(7)], xref:rink-dates.5.adoc[rink-dates(5)] diff --git a/docs/rink.1.adoc b/docs/rink.1.adoc new file mode 100644 index 0000000..52372c1 --- /dev/null +++ b/docs/rink.1.adoc @@ -0,0 +1,70 @@ += rink(1) +:manmanual: Rink Manual +:mansource: Rink Manual + +Name +---- +rink - Unit calculator and dimensional analysis tool + +Synposis +-------- +[verse] +**rink** +**rink** [_EXPR_]... +**rink -f** <__FILE__> +**rink** (**-h** | **-V** | **--config-path**) + +Description +----------- +Rink is a unit conversion and calculation tool which can be used for +both small and simple arithmetic and more complex dimensionality +analysis and other tasks. + +Options +------- +**--config-path**:: + Prints a path to the config file, then exits. + +**-f**:: +**--file** <__file__>:: + Reads expressions from a file, one per line, printing them to stdout + and then exitting. + +**-h**:: +**--help**:: + Print help information and then exits. + +**-V**:: +**--version**:: + Prints the current version and then exits. + +Exit status +------------ + +Returns 0 unless an error prevented rink from starting up. + +Environment +----------- + +**NO_COLORS**:: + If set to a non-empty string, rink will disable colored text + rendering. + +Files +----- +Rink looks for a configuration file in +`$XDG_CONFIG_DIR/rink/config.toml`, see rink(5). + +Rink relies on some data files, which are found using a search path. +See rink-defs(5) and rink-dates(5). + +Bugs +---- + + + +See also +-------- +xref:rink.5.adoc[rink(5)], xref:rink.7.adoc[rink(7)], +xref:rink-defs.5.adoc[rink-defs(5)], +xref:rink-dates.5.adoc[rink-dates(5)] diff --git a/docs/rink.5.adoc b/docs/rink.5.adoc new file mode 100644 index 0000000..9536ab7 --- /dev/null +++ b/docs/rink.5.adoc @@ -0,0 +1,153 @@ += rink(5) +:manmanual: Rink Manual +:mansource: Rink Manual + +Name +---- +rink - TOML configuration file format. + +Description +----------- +Rink's configuration file uses the TOML format. + +Duration types accept common suffixes like `ms`, `s`, `h`, `d`, `y`. +Size types accept suffixes like `MB`. + +Color strings are a set of keywords separated by spaces. The following +keywords are understood: + +*black*, *red*, *green*, *yellow*, *blue*, *purple*, *cyan*, *white*:: + Sets the color to that ANSI color. +*dim*/*dimmed*:: + Uses a dimmed variant of the color instead of the bright variant. +*bold*, *italic*, *underline*/*under*, *strikethrough*:: + Formatting. +*hidden*/*none*:: + Makes the text invisible. +*on*:: + The color keyword after this will apply to the background instead of + the foreground. Example: `black on red`. +*default*/*plain*:: + Results in unstyled text. +integers 0 to 255:: + Extended terminal color palette codes. +*#* <__6 hex letters__>:: + Hex codes can be used to specify truecolor. + Example: `#000000` +*rgb(* <__red__> *,* <__green__> *,* <__blue__> *)*:: + RGB values can be used to specify truecolor. No spaces are allowed. + Example: `rgb(10,10,10)` + +Rink +~~~~ +The `[rink]` section. + +*prompt* = <__string__>:: + The text that will be displayed before the cursor, to hint + interactivity. Should include the space character. + Default: `"> "` + +*long_output* = <__bool__>:: + Breaks lists, such as search results, over multiple lines. Requires + a Unicode-capable terminal. + Default: `false` + +Currency +~~~~~~~~ +The `[currency]` section. + +*enabled* = <__bool__>:: + Currency fetching can be disabled for those that don't want it. + Default: `true` + +*endpoint* = <__url__>:: + Allows pointing to alternate Rink-Web instances, or to any other API + that offers a compatible format. + Default: `"https://rinkcalc.app/data/currency.json"` + +*timeout* = <__duration__>:: + How long to wait for currency fetching before giving up. + Default: `"2s"` + +*cache_duration* = <__duration__>:: + How long to wait before considering the cached currency data stale. + Default: `"1h"` + +Colors +~~~~~~ +The `[colors]` section. + +*enabled* = <__bool__>:: + Set to true to turn on colored output. + Default: `true`, or `false` if the `NO_COLOR` environment variable is set. + +*theme* = <__string__>:: + Sets the active theme. See the THEMES section. + Default: `"default"` + +Themes +~~~~~~ +The `[themes]` section. This section is a dictionary, each theme should be +created as `[themes.my_theme]`. These options are specific to each. + +*plain* = <__color__>:: + Generic text. This will be used often. + Default: `"default"` + +*error* = <__color__>:: + Error messages. + Default: `"red"` + +*unit* = <__color__>:: + The names of units, like `kilogram`. + Default: `"cyan"` + +*quantity* = <__color__>:: + The names of physical quantities, like `length` and `time`. These + are shown in parentheses on every query. + Default: `"dimmed cyan"` + +*number* = <__color__>:: + Numbers that appear in outputs. + Default: `"default"` + +*user_input* = <__color__>:: + Used when rink is quoting user input back, such as in unit not found + errors. + Default: `"bold"` + +*doc_string* = <__color__>:: + Used when rink is showing informational text that's part of the + definition of a unit, like `meter`. + Default: `"italic"` + +*pow* = <__color__>:: + The `^2` in `m/s^2`. + Default: `"default"` + +*prop_name* = <__color__>:: + Names of properties in substances, like the `speed` in `speed of + light`. + Default: `"cyan"` + +*date_time* = <__color__>:: + Date time objects, that can be obtained with the hash notation or + `now`. + Default: `"default"` + +Files +----- +Linux:: + ++__$XDG_CONFIG_DIR__/rink/config.toml++ + +Windows:: + ++__{FOLDERID_RoamingAppData}__\rink\config.toml++ + +macOS:: + ++__$HOME__/Library/Application Support/rink/config.toml++ + +See also +-------- +xref:rink.1.adoc[rink(1)], xref:rink.7.adoc[rink(7)], +xref:rink-defs.5.adoc[rink-defs(5)], +xref:rink-dates.5.adoc[rink-dates(5)] diff --git a/docs/rink.7.adoc b/docs/rink.7.adoc new file mode 100644 index 0000000..4d3e822 --- /dev/null +++ b/docs/rink.7.adoc @@ -0,0 +1,685 @@ += rink(7) +:manmanual: Rink Manual +:mansource: Rink Manual + +Name +---- +rink - Query language documentation + +Synposis +-------- +Rink's query language follows a somewhat natural language style for its +syntax. Many expressions like *3.5 meters to feet* will work without any +modification. This manual is meant for those who want to get a deeper +understanding of the query language. + +Description +----------- + +In order to understand Rink, an understanding of units themselves is +required. Fundamentally, a *unit* is a way of assigning a concrete +value to a specific *quantity* such as length, volume, energy, power, +current, etc. Each *quantity* can be reduced into other quantities +(for example, area is length × length), except for 7 *base units*. + +The 7 *base units* (as well as the physical quantities they represent): + +* meter (length) +* second (time) +* kilogram (mass) +* ampere (current) +* kelvin (temperature) +* mol (amount of substance) +* candela (human-subjective luminous intensity) + +In addition, Rink defines a few non-SI base units: + +* euro (money) +* bit (information) +* radian (angle) +* steradian (solid angle) +* wholenote (musical note length) +* IU (biological activity) + +Each of these quantities is treated as irreducible. The 7 base units +are the foundations of SI, and customary systems as well. (Customary +systems are defined in terms of SI.) + +Every *unit* is composed of two parts: A numerical value, and its +*dimensionality*. The dimensionality is how a unit relates itself to +the *base units*. Each base unit is raised to a certain power to +construct the dimensionality. For example, the dimensionality of the +quantity of acceleration is `length^1` × `time^-2` and then the rest of +the base units are to the 0th power, which is to say that they do not +matter. Two units are considered *conformable* if they have matching +dimensionalities, and they can then be used in conversions. + +Because each unit has a numerical part, it is possible to do normal +math on them*. + +- Adding two units produces a new unit with matching dimensionality. +- Multiplying two units produces a new unit with its dimensionality as + each base unit multiplied together, e.g. velocity (`length time^-1`) * + hertz (`time^-1`) = acceleration (`length time^-2`). +- Dividing two units is like multiplication, but taking away from the + base units. A unit divided by itself is *dimensionless*, it has no + quantity. Normal numbers are dimensionless. + +Because of this, units are essentially a special type of number. As +such, Rink is essentially a calculator which takes dimensionality into +account. + +Weight vs Mass +~~~~~~~~~~~~~~ + +It is important to remember the differences between mass and weight +when working with mass and force units. Here are some tips: + +- Mass doesn't change depending on the amount of gravity, and directly + influences momentum. + +- Weight is the amount of downward force on an object due to gravity. + +- Mass is measured in kilograms or pounds. + +- Weight is measured in newtons, kilogram force (kgf), or pound force + (lbf). + +- When someone says something weighs some amount of kg or lb, they're + saying it has a weight of that number of kgf or lbf. This includes + things like weight on the moon. (Don't correct anyone using this + common figure of speech.) + +- A scale displays an estimate of mass by measuring the force applied + to it divided by its calibrated measurement of the acceleration of + gravity. Its mass estimate would be incorrect on other planets + unless it was recalibrated. You can also think of the displayed + value as being weight in kgf or lbf. + +- You can compute weight by multiplying mass by gravity. Both kgf and + lbf have earth gravity as part of their definition, so when you + multiply kg or lb by gravity you get the same numerical values back, + but with kgf or lbf units. + +Numbers +~~~~~~~ + + > 10.1e2 + 1010 (dimensionless) + > 10 + 10 (dimensionless) + > 0x10 + 16 (dimensionless) + > 0o10 + 8 (dimensionless) + > 0b10 + 2 (dimensionless) + > 9999999999999 + approx. 9.99999e12 (dimensionless) + > 1.001 + 1.001 (dimensionless) + > 1e100 + 1.0e100 (dimensionless) + +Decimal numbers can be written with an integer component, an +after-decimal-point component, and an exponent. Numbers can optionally +have either `U+2009 THIN SPACE` or an underscore (`_`) for digit place +separators. + +The decimal point is always written with a dot (`.`), not a comma or +other marker. If the decimal point is provided, it must be followed by +more digits. (`1.` is not allowed.) + +The exponent starts with an `e`, followed by an integer with an +optional sign. The exponent is shorthand for writing out `* +10^exp`. There can be no spaces within the number other than allowed +digit separators. (`10 e10` is not allowed.) + +Hexadecimal, octal, and binary integers can be written using `0x`, +`0o`, and `0b` prefixes, respectively. These literals do not currently +support decimal points or exponents. + +Numbers can be written with a fraction, and can be written in +scientific notation. `1e24` is short for `1 * 10^24`. + +Arithmetic +~~~~~~~~~~ + + > 3 4 m 5 s + 60 m s + > 3 * 4 m 5 s + 60 m s + +Multiplication can be either by juxtaposition (that is, without any +symbol) or using an explicit * operator. + + > 10 km / 5 m + 2000 (dimensionless) + > 1|2 m + 0.5 m (length) + +There are two division operators, for separate purposes. `/` has lower +precedence than multiplication, and is used mainly for separating two +halves of an entire expression. `|` has higher precedence than +multiplication, and is used mainly for fractions of integers. + + > 1 * 2 + 1 * 2 + 4 (dimensionless) + > 12 meters + 5 feet + 13.524 m (length) + +Addition and subtraction have lower precedence than multiplication and +division. + + > 12 ft^2 + 435483/390625, approx. 1.114836 m^2 (area) + +Powers have higher precedence than multiplication. Both `^` and `**` +can be used. + +Temperature +~~~~~~~~~~~ + + > 12 °C + 285.15 K (temperature) + +Temperature scales are operators with higher precedence than addition, +and lower than multiplication. See the <> +section for more detailed syntax. + +Inline Definitions +~~~~~~~~~~~~~~~~~~ + + > 2000 kcal -> potato = 164 kcal + 500/41, approx. 12.19512 potato (energy) + +An equals expression is one which simultaneously defines a new unit +with the right-hand side, names it using the left-hand side, and then +produces it as its result. This is useful for customizing the output +of the right-hand side of a conversion or converting into things that +don't currently have units such as the amount of calories in a potato. + +Custom base units +~~~~~~~~~~~~~~~~~ + + > 12 'core' hour / 3 'core' -> minutes + 240 minutes (time) + +A unit name which is wrapped in quotation marks will not be checked +for whether it exists when it is evaluated. This means you can wrap +anything in quotes to in effect produce a new *base unit* for the +purposes of a single calculation. This can be useful for doing +calculations in terms of things which are otherwise dimensionless. + +Previous results +~~~~~~~~~~~~~~~~ + + > 100 ohm + 50 ohm + 150 ohm (resistance) + > ANS * 10 mA + 1.5 volt (electrical_potential) + +The result of the previous query can be accessed with `_`, `ans` or +`ANS`, which can be convenient for breaking up calculations into +multiple steps. Note that when rink returns an error occurs, the +previous result is kept. Also, currently only the results of +mathematical expressions are stored, the results for conversions aren't. + +Prefixes +~~~~~~~~ + +Units can be prefixed with SI prefixes as well as a number of non-SI +prefixes, such as: quarter, double, kibi, mebi, ⅞. + +Rink will accept plural unit names as well. + +Conversions +~~~~~~~~~~~ + + > meter -> feet + 3.280839 foot (length) + > 12 °C -> °F + 53.6 °F (temperature) + +Conversions are done with the `->`, `to`, `in` operators. + +The left hand side of the conversion is an arbitrary expression, and +the right hand side is one of: + +- An arbitrary expression +- A temperature scale (celsius, fahrenheit, and several historical + scales) +- A unit list (e.g. `hour;min;sec`) +- A timezone (e.g. `"US/Pacific"`) + +Unit lists +^^^^^^^^^^ + + > 2^17 seconds -> hour;min;sec + 36 hour, 24 minute, 32 s (time) + > 2 km -> mi;ft + 1 mile, 1281.679 foot (length) + > liter -> cup;tbsp;tsp + 4 uscup, 3 ustablespoon, 1.884136 usteaspoon (volume) + +A unit list is a comma- or semicolon- delimited list of units with the +same dimensionality, which can be used for breaking down numbers into +more familiar quantities. + +[#temperature-conversions] +Temperature conversion +^^^^^^^^^^^^^^^^^^^^^^ + + > 12 °C + 285.15 K (temperature) + > 12 degC + 285.15 K (temperature) + > 12 celsius + 285.15 K (temperature) + +Temperature scales in Rink are handled a little specially, because +only Kelvin and Rankine (the absolute zero version of Fahrenheit) +start at absolute zero. As such, they are *operators*, not +units. These operators have looser binding precedence than +multiplication, but tighter than addition. + +Available temperature scales: + +`degC`, `°C`, `celsius`, `℃`:: + **Celsius**, the standard scale in most countries. + +`degF`, `°F`, `fahrenheit`, `℉`:: + **Fahrenheit**, the scale used in households across the United States. + +`degRé`, `°Ré`, `degRe`, `°Re`, `réaumur`, `reaumur`:: + **Réaumur**, A historical scale once used throughout Europe. + +`degRø`, `°Rø`, `degRo`, `°Ro`, `rømer`, `romer`:: + **Romer**, Another historical scale. + +`degN`, `°N`, `degnewton`:: + **Newton**, A historical scale created by Isaac Newton. + +`degDe`, `°De`, `delisle`:: + **Delisle**, A historical scale which, alongside the original + Celsius scale, is reversed from the scales we are used to today. Its + zero point is boiling water, and the freezing point of water is + 150°De. + +Note that these temperature scale measurements are *absolute* +measurements, not *differences*. If you wish to say something like "a +difference of 1°C", then you must use the absolute scale for the scale +you're using. These are: + +- For Celsius, kelvin `K` +- For Fahrenheit, Rankine `degR` +- For Réaumur, `reaumur_absolute` (absolute as in the zero point is absolute zero) +- For Rømer, `romer_absolute` +- For Newton, `newton_absolute` +- For Delisle, `delisle_absolute` + +Numeric base conversion +^^^^^^^^^^^^^^^^^^^^^^^ + + > 1000 -> hex + 3e8 (dimensionless) + > 10000 -> base 36 + 7ps (dimensionless) + > pi meter -> hex meter + approx. 3.243f6a meter (length) + +Base modifiers are specified with `base` followed by a number, +followed by the rest of your conversion. Allowed bases are currently 2 +through 36. There are some special base names which are also +recognized: + +`hex`, `hexadecimal`, `base16`:: + Base 16. + +`oct`, `octal`, `base8`:: + Base 8. + +`bin`, `binary`, `base2`:: + Base 2. + +Digits modifier +^^^^^^^^^^^^^^^ + + > 2^128 -> digits + 340282366920938463463374607431768211456 (dimensionless) + > 1/7 -> digits 50 + 1/7, approx. 0.1428571428571428571428571428571428571428571428571428 (dimensionless) + > googol -> digits + 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (dimensionless) + +Digits modifiers are specified with `digits` optionally followed by a +number, before the base modifier and before the rest of the +conversion. Any number of digits are allowed, but large amounts may +not succeed. + +The function of this modifier is that it forces the entire integer +part to be printed (i.e., scientific notation will *not* be used), and +then it prints an additional *n* digits, using the default if not +specified. + +Trancendental numbers currently cannot be precisely represented, so +asking for many digits of pi or e will produce unsatisfying results. + +Trigonometric and logarithmic functions are currently implemented +using a machine-float fallback, because their results cannot be +precisely represented as finite rationals. Because of this, asking for +many digits of such numbers will also produce unsatisfying results. + +Units for +^^^^^^^^^ + + > units for power + Units for kg m^2 / s^3 (power): VA, airwatt, boilerhorsepower, brhorsepower, + donkeypower, electrichorsepower, horsepower, lusec, mbh, metrichorsepower, + poncelet, sccm, sccs, scfh, scfm, slph, slpm, solarluminosity, + tonrefrigeration, waterhorsepower, watt + +The *units for*, *units of*, and *units* commands will find more units +which match the dimensionality of the one specified. + +Factorization +^^^^^^^^^^^^^ + + > factorize velocity + Factorizations: velocity; frequency length; area viscosity; + acceleration time; length^2 viscosity + > factorize power + Factorizations: power; force velocity; radiant_intensity solid_angle; + area radiosity; length spectral_flux_wavelength; radiation_dose spectral_exposure_frequency; + spectral_irradiance_wavelength volume; temperature thermal_conductance; + energy frequency; current^2 resistance; ... + +Unit factorization is what Rink names the process of finding +quantities which can be multiplied together to produce the original +quantity. This can be useful for discovering new ways to construct a +unit. + +Search +^^^^^^ + + > search milk + Search results: milk (substance), mil (length), mile (length), mill (dimensionless), mi (length) + +Allows you to search for units based on their names, returning up to 5 +results and showing the associated physical quantity of the unit. + +Date and time +~~~~~~~~~~~~~ + + > #jan 01, 1970# + 1970-01-01 00:00:00 +00:00 (46 years ago) + > now - #jan 01, 1970# -> gigaseconds + 1.472083 gigaseconds (time) + > #2016-08-24# + 500 weeks + 2026-03-25 00:00:00 +00:00 (in 9 years) + +In addition to handling units, Rink is also capable of doing some +calculations with dates and times. + +Converting to a timezone: + + > now + 2022-08-08 21:19:56.990897100 -07:00 (now) + > now -> "Europe/London" + 2022-08-09 05:20:03.656075600 BST (now) + +Converting to a fixed offset: + + > now -> +01:00 + 2022-08-09 05:20:30.080703900 +01:00 (now) + +Inputting a time with an offset: + + > #apr 1, 2016 12:00:00 +01:00# + 2016-04-01 12:00:00 +01:00 (6 years ago) + +Substances +~~~~~~~~~~ + + > milk + milk: density = 242 gram -> approx. 236588.2 millimeter^3 + > gallon milk + milk: volume = approx. 3785411.7 millimeter^3; mass = 3.872 kilogram + > egg + egg: USA large egg. mass_shelled = 50 gram; mass_white = 30 gram; + mass_yolk = 18.6 gram; volume = approx. 46824.75 millimeter^3; + volume_white = approx. 29573.52 millimeter^3; + volume_yolk = approx. 17251.22 millimeter^3 + > egg_shelled of kg egg + 20 (dimensionless) + > gallon gasoline -> btu + gasoline: volume = approx. 3785411.7 millimeter^3; energy_HHV = 125000 btu; energy_LHV = 115000 btu + +Substances are how Rink organizes the physical properties of +materials, objects, both countable and uncountable. Each substance has +a name, an associated amount (defaulting to dimensionless 1), and a +set of associated properties. + +Each property maps a named input into a named output and vice versa, +and has a name itself. Countable objects often have properties with an +input being dimensionless, so that you do not need to specify an +amount to extract the property. + +The properties of a substance are accessed with the *of* operator +(<_property_> *of* <_substance_>), which reads a multiplication +expression following it, so you may have to wrap it in parentheses. + +Substances can be used in conversions, and can be added and multiplied +to transform them. Multiplication will change the amount of the +substance you have, so that you can write *kg egg* to specify one +kilogram of eggs. Addition will combine certain properties (currently +only `molar_mass`) to create a new substance entirely. Conversions of +substances allow you to get multiple results simultaneously, for +example if there are multiple different measurements of some property +of the substance available. + +If the result of a calculation results in a substance, Rink will show +all of the properties applicable for the given amount. + +Reference +--------- + +The full list of units is specified in the file `definitions.units` (see +xref:rink-defs.5.adoc[rink-defs(5)]), but a small list of the most +helpful ones will be listed here. It is intended that most units should +be easy to guess the names of. + +SI derived +~~~~~~~~~~ + +- Newton `N` (force) +- Pascal `Pa` (pressure) +- Joule `J` (energy) +- Watt `W` (power) +- Coulomb `C` (charge) +- Volt `V` (electrical potential) +- Ohm (electrical resistance) +- Siemens `S` (electrical conductance) +- Farad `F` (capacitance) +- Weber `Wb` (magnetic flux) +- Henry `H` (inductance) +- Tesla `T` (magnetic flux density) +- Hertz `Hz` (frequency) +- Lumen `lm` (luminous flux) +- Lux `lx` (illuminance) +- Gray `Gy` (radiation dose) +- Katal `kat` (catalytic activity) + +Substances +~~~~~~~~~~ + +Compounds and materials:: + - Water `water` + - Ammonia `ammonia` + - Freon `freon` + - Tissue `tissue` + - Diamond `diamond` + - Graphite `graphite` + - Water ice `ice` + - Asphalt `asphalt` + - Brick `brick` + - Concrete `cocnrete` + - Silica glass `glass_silica` + - Flint glass `glass_flint` + - Pyrex glass `glass_pyrex` + - Gypsum `gypsum` + - Marble `marble` + - Sand `sand` + - Soil `soil` + - Air `air` + +Particles:: + - Electron `electron` + - Proton `proton` + - Neutron `neutron` + - Deuterium nucleus `deuteron` + - Muon `muon` + - Helium nucleus `helion` + - Tau `tauparticle` + - Alpha `alphaparticle` + - Tritium nucleus `triton` + +Celestial bodies:: + - Sun `sun` + - Mercury `mercury_planet` + - Venus `venus` + - Earth `earth` + - Earth's moon `moon` + - Mars `mars` + - Jupiter `jupiter` + - Saturn `saturn` + - Uranus `uranus` + - Neptune `neptune` + - Pluto `pluto` + +Fuels:: + - Crude oil `oil` + - Coal `coal` + - Natural gas `naturalgas` + - Charcoal `charcoal` + - Wood `wood` + - Ethanol `ethanol` + - Diesel `diesel` + - Gasoline `gasoline` + - Heating oil `heating_oil` + - Fuel oil `fueloil` + - Propane `propane` + - Butane `butane` + +Foods:: + - Butter `butter` + - Clarified butter `butter_clarified` + - Cocoa butter `cocoa_butter` + - Vegetable shortening `shortening` + - Vegetable oil `vegetable_oil` + - Olive oil `olive_oil` + - Flour `cakeflour`, `flour`, `breadflour` + - Corn starch `cornstarch` + - Cocoa `dutchcocoa`, `cocoa` + - Heavy cream `heavycream` + - Milk `milk` + - Sour cream `sourcream` + - Molasses `molasses` + - Corn syrup `corrnsyrup` + - Honey `honey` + - Sugar `sugar` + - Powdered sugar `powdered_sugar` + - Brown sugar `brownsugar_light`, `brownsugar_dark` + - Baking powder `baking_powder` + - Salt `salt`, `koshersalt` + - Egg `egg` + +Elements 1 through 118, by name (e.g. `helium`) + +Constants +~~~~~~~~~ + +- Pi `pi` +- Speed of light `c` +- Planck Constant `planck_constant` +- Gravitational Constant `G` +- Avogadro's number `avogadro` +- Gas Constant `gasconstant` +- Boltzmann Constant `boltzmann` +- Earth Gravity `gravity`, `force` +- Earth Atmosphere Density `atm` + +Currencies +~~~~~~~~~~ + +These are only available if live currency fetching is enabled. (See +rink(5).) + +- EU Euro `EUR`, `€` +- US dollar `USD`, `$`, `dollar` +- Japan yen `JPY`, `¥`, `yen` +- Bulgaria lev `BGN` +- Czech koruna `CZK` +- Denmark kroner `DKK` +- UK pound `GBP`, `£` +- Hungary forint `HUF` +- Poland złoty `PLN` +- Romania lei `RON` +- Sweden krona `SEK` +- Switzerland franc `CHF` +- Norway krone `NOK` +- Croatia kuna `HRK` +- Russia ruble `RUB`, `₽` +- Turkey lira `TRY`, `₺` +- Australia dollar `AUD`, `A$` +- Brazil real `BRL`, `R$` +- Canada dollar `CAD`, `C$` +- PRC yuan `CNY` +- Hong Kong dollar `HKD`, `H$` +- Indonesia rupiah `IDR` +- Israel shekel `ILS`, `₪` +- India rupee `INR`, `₹` +- South Korea won `₩` +- Mexico dollar `MXN`, `mex$` +- Malaysia ringgit `MYR` +- New Zealand dollar `NZD`, `NZ$` +- Phillipines piso `PHP`, `₱` +- Singapore dollar `SGD`, `S$` +- Thailand baht `THB`, `฿` +- South Africa rand `ZAR` + +Functions +~~~~~~~~~ + +Currently, all of these result in machine float fallback, because +their results are real numbers that cannot be precisely represented as +rationals. + +- `sqrt(x)`: Square root, √x. +- `exp(x)`: The exponential function, e^x. +- `ln(x)`: The natural logarithm, log_e(x). +- `log(x,y)`: Logarithm in base *y*, log_y(x). +- `log2(x)`: Logarithm in base 2, log_2(x). +- `log10(x)`: Logarithm in base 10, log_10(x). +- `hypot(x,y)`: The length of the hypotenuse of a right-angle triangle + given adjacent edges of length x and y. +- `sin(x)`: The sine function. +- `cos(x)`: The cosine function. +- `tan(x)`: The tangent function. +- `asin(x)`: Inverse sine, or arcsine. +- `acos(x)`: Inverse cosine, or arccosine. +- `atan(x)`: Inverse tangent, or arctangent. +- `atan2(x, y)`: Four-quadrant arctangent, which can be used to + reverse sine+cosine back into an angle. +- `sinh(x)`: Hyperbolic sine. +- `cosh(x)`: Hyperbolic cosine. +- `tanh(x)`: Hyperbolic tangent. +- `asinh(x)`: Inverse hyperbolic sine function. +- `acosh(x)`: Inverse hyperbolic cosine function. +- `atanh(x)`: Inverse hyperbolic tangent function. + +See also +-------- +xref:rink.1.adoc[rink(1)], xref:rink.5.adoc[rink(5)], +xref:rink-defs.5.adoc[rink-defs(5)], +xref:rink-dates.5.adoc[rink-dates(5)] diff --git a/rink-js/Cargo.toml b/rink-js/Cargo.toml index a53802c..a99358f 100644 --- a/rink-js/Cargo.toml +++ b/rink-js/Cargo.toml @@ -17,7 +17,7 @@ default = ["console_error_panic_hook"] [dependencies.rink-core] path = "../core" version = "0.7" -features = ["gpl"] +features = ["bundle-files"] [dependencies] wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } diff --git a/rink-js/src/lib.rs b/rink-js/src/lib.rs index 842b270..0210a36 100644 --- a/rink-js/src/lib.rs +++ b/rink-js/src/lib.rs @@ -92,7 +92,7 @@ impl Context { let mut base_defs = { use rink_core::loader::gnu_units; - let defs = rink_core::CURRENCY_FILE; + let defs = rink_core::CURRENCY_FILE.unwrap(); let mut iter = gnu_units::TokenIterator::new(defs).peekable(); gnu_units::parse(&mut iter) };