diff --git a/.github/workflows/cancel_closed_pr_runs.yml b/.github/workflows/cancel_closed_pr_runs.yml
index 99010d81b..91005de52 100644
--- a/.github/workflows/cancel_closed_pr_runs.yml
+++ b/.github/workflows/cancel_closed_pr_runs.yml
@@ -24,11 +24,11 @@ jobs:
permissions:
actions: write
- runs-on: ubuntu-latest
+ runs-on: ubuntu-26.04
steps:
- name: Harden Runner
- uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
+ uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
diff --git a/.github/workflows/check_amalgamation.yml b/.github/workflows/check_amalgamation.yml
index 8104a20af..253531e40 100644
--- a/.github/workflows/check_amalgamation.yml
+++ b/.github/workflows/check_amalgamation.yml
@@ -19,10 +19,10 @@ permissions:
jobs:
save:
if: github.event_name == 'pull_request'
- runs-on: ubuntu-latest
+ runs-on: ubuntu-26.04
steps:
- name: Harden Runner
- uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
+ uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -46,7 +46,7 @@ jobs:
steps:
- name: Harden Runner
- uses: step-security/harden-runner@ccd8616d44fd3846e67624a50d5aad6d37bf2d25 # v2.22.1
+ uses: step-security/harden-runner@dc2769abcc0fcfbadfc1df54081c1608579ef6b2 # v2.22.2
with:
egress-policy: audit
@@ -163,9 +163,9 @@ jobs:
python3 $GENERATOR --list-tags
TAG_COUNT=$(python3 $GENERATOR --list-tags | wc -l)
- python3 $GENERATOR --abi-tags diag,_dp,_vns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
- grep -q '' $RUNNER_TEMP/abi_tags.natvis
- grep -q '' $RUNNER_TEMP/abi_tags.natvis
+ python3 $GENERATOR --abi-tags diag,_dp,_ns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
+ grep -q '' $RUNNER_TEMP/abi_tags.natvis
+ grep -q '' $RUNNER_TEMP/abi_tags.natvis
test $(grep -c ' B{"empty, or every element is a 2-element
array whose first element is a string?"}
- B -->|"yes"| C{"type_deduction"}
- B -->|"no"| D{"type_deduction"}
+ A(["initializer_list init"]) --> B{{"empty, or every element is a 2-element
array whose first element is a string?"}}
+ B -->|"yes"| C{{"type_deduction"}}
+ B -->|"no"| D{{"type_deduction"}}
C -->|"true"| OBJ["create object"]
- C -->|"false"| E{"manual_type"}
+ C -->|"false"| E{{"manual_type"}}
E -->|"object"| OBJ
E -->|"array"| ARR["create array"]
D -->|"true"| ARR
- D -->|"false"| F{"manual_type"}
+ D -->|"false"| F{{"manual_type"}}
F -->|"array"| ARR
F -->|"object"| ERR["throw type_error.301"]
```
+
Decision flow for an initializer list: hexagons are checks, edge labels are their + outcomes, and rectangles are the resulting value or exception.
+ The rules aim to create the best fit between a C++ initializer list and JSON values. The rationale is as follows: 1. The empty initializer list is written as `#!cpp {}` which is exactly an empty JSON object. @@ -473,12 +476,13 @@ basic_json(basic_json&& other) noexcept; ## See also -- [array](array.md) create a JSON array value, forcing array creation from an initializer list even when it looks like +- [`array`](array.md) - create a JSON array value, forcing array creation from an initializer list even when it looks like an object -- [object](object.md) create a JSON object value, forcing object creation from an initializer list -- [binary](binary.md) create a JSON binary array value -- [operator=](operator=.md) copy assignment operator +- [`object`](object.md) - create a JSON object value, forcing object creation from an initializer list +- [`binary`](binary.md) - create a JSON binary array value +- [`operator=`](operator=.md) - copy assignment operator - [Creating JSON values](../../features/creating_values.md) - the article on creating JSON values +- [Converting values](../../features/conversions.md) - which C++ types can be converted ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/begin.md b/docs/mkdocs/docs/api/basic_json/begin.md index 72583ce57..15ca5bf32 100644 --- a/docs/mkdocs/docs/api/basic_json/begin.md +++ b/docs/mkdocs/docs/api/basic_json/begin.md @@ -7,7 +7,12 @@ const_iterator begin() const noexcept; Returns an iterator to the first element. - +`begin()` points to the first element and `end()` to the position after the last element; +the dashed cell is the past-the-last position, which must not be dereferenced.
## Return value @@ -39,12 +44,12 @@ Constant. ## See also -- [end](end.md) returns an iterator to one past the last element -- [cbegin](cbegin.md) returns a const iterator to the first element -- [rbegin](rbegin.md) returns a reverse iterator to the last element -- [items](items.md) returns an iteration proxy to access keys and values during range-based for loops +- [`end`](end.md) - returns an iterator to one past the last element +- [`cbegin`](cbegin.md) - returns a const iterator to the first element +- [`rbegin`](rbegin.md) - returns a reverse iterator to the last element +- [`items`](items.md) - returns an iteration proxy to access keys and values during range-based for loops - [Iterators](../../features/iterators.md) - the article on iterators -- [basic_json_view::begin](../basic_json_view/begin.md) - the same iteration on a zero-copy view (in document order, +- [`basic_json_view::begin`](../basic_json_view/begin.md) - the same iteration on a zero-copy view (in document order, not sorted by key) ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/binary.md b/docs/mkdocs/docs/api/basic_json/binary.md index b19b0af27..1871c2c8f 100644 --- a/docs/mkdocs/docs/api/basic_json/binary.md +++ b/docs/mkdocs/docs/api/basic_json/binary.md @@ -63,10 +63,11 @@ initialization of a binary array type, for backwards compatibility and so it doe ## See also -- [binary_t](binary_t.md) type for binary values -- [get_binary](get_binary.md) get a reference to the stored binary value -- [is_binary](is_binary.md) return whether the value is binary -- [byte_container_with_subtype](../byte_container_with_subtype/index.md) container for binary values with subtype +- [Binary formats](../../features/binary_formats/index.md) - formats that can store binary values +- [`binary_t`](binary_t.md) - type for binary values +- [`get_binary`](get_binary.md) - get a reference to the stored binary value +- [`is_binary`](is_binary.md) - return whether the value is binary +- [`byte_container_with_subtype`](../byte_container_with_subtype/index.md) - container for binary values with subtype - [Binary Values](../../features/binary_values.md) - the article on binary values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/binary_t.md b/docs/mkdocs/docs/api/basic_json/binary_t.md index da13c22a2..f673335b1 100644 --- a/docs/mkdocs/docs/api/basic_json/binary_t.md +++ b/docs/mkdocs/docs/api/basic_json/binary_t.md @@ -41,7 +41,7 @@ represent a byte array in modern C++. [`byte_container_with_subtype`](../byte_container_with_subtype/index.md) derives directly from it. Its `value_type` must additionally be exactly one byte wide (e.g., `std::uint8_t`/`char`/`std::byte`): the binary serializers (CBOR, MessagePack, BSON, UBJSON) read and write the container's raw bytes via - `reinterpret_cast`, which is only correct for byte-sized elements -- a container like + `reinterpret_cast`, which is only correct for byte-sized elements — a container like `#!cpp std::vector`cbegin()` points to the first element, like `begin()`, and `end()` to the position after +the last element; the dashed cell is the past-the-last position, which must not be dereferenced.
## Return value @@ -38,11 +43,11 @@ Constant. ## See also -- [begin](begin.md) returns an iterator to the first element -- [cend](cend.md) returns a const iterator to one past the last element -- [crbegin](crbegin.md) returns a const reverse iterator to the last element +- [`begin`](begin.md) - returns an iterator to the first element +- [`cend`](cend.md) - returns a const iterator to one past the last element +- [`crbegin`](crbegin.md) - returns a const reverse iterator to the last element - [Iterators](../../features/iterators.md) - the article on iterators -- [basic_json_view::cbegin](../basic_json_view/cbegin.md) - the same iteration on a zero-copy view +- [`basic_json_view::cbegin`](../basic_json_view/cbegin.md) - the same iteration on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md b/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md index 55a7954d5..eb92ce03f 100644 --- a/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md +++ b/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md @@ -15,11 +15,13 @@ error : report a parse error in case of a tag (the `from_cbor` overloads throw a `parse_error` exception by default) ignore -: ignore tags +: ignore tags (also in front of a text string map key) store : store tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are - read as if the tag were ignored. If several tags precede a byte string, only the innermost one is stored. + read as if the tag were ignored. If several tags precede a byte string, only the tag directly in front of it is + stored, and only when it has the form 0xd8..0xdb (a tag 0..23 written as 0xc0..0xd7 is skipped). Tags in front of a + text string map key are skipped. ## Examples @@ -40,8 +42,9 @@ store ## See also -- [from_cbor](from_cbor.md) deserializes a JSON value from CBOR -- [input_format_t](input_format_t.md) the enumeration of supported input formats +- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled +- [`from_cbor`](from_cbor.md) - deserializes a JSON value from CBOR +- [`input_format_t`](input_format_t.md) - the enumeration of supported input formats - [CBOR](../../features/binary_formats/cbor.md) - the article on the CBOR format ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/cend.md b/docs/mkdocs/docs/api/basic_json/cend.md index fb568762a..ea89f43ce 100644 --- a/docs/mkdocs/docs/api/basic_json/cend.md +++ b/docs/mkdocs/docs/api/basic_json/cend.md @@ -6,7 +6,12 @@ const_iterator cend() const noexcept; Returns an iterator to one past the last element. - +`cend()` points to the position after the last element, like `end()`, and `begin()` to +the first element; the dashed cell is the past-the-last position, which must not be dereferenced.
## Return value @@ -38,11 +43,11 @@ Constant. ## See also -- [end](end.md) returns an iterator to one past the last element -- [cbegin](cbegin.md) returns a const iterator to the first element -- [crend](crend.md) returns a const reverse iterator to one before the first element +- [`end`](end.md) - returns an iterator to one past the last element +- [`cbegin`](cbegin.md) - returns a const iterator to the first element +- [`crend`](crend.md) - returns a const reverse iterator to one before the first element - [Iterators](../../features/iterators.md) - the article on iterators -- [basic_json_view::cend](../basic_json_view/cend.md) - the same iteration on a zero-copy view +- [`basic_json_view::cend`](../basic_json_view/cend.md) - the same iteration on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/clear.md b/docs/mkdocs/docs/api/basic_json/clear.md index 92043e978..087cd83f4 100644 --- a/docs/mkdocs/docs/api/basic_json/clear.md +++ b/docs/mkdocs/docs/api/basic_json/clear.md @@ -54,8 +54,9 @@ All iterators, pointers, and references related to this container are invalidate ## See also -- [erase](erase.md) removes elements from a JSON value -- [empty](empty.md) checks whether the JSON value has no elements +- [`erase`](erase.md) - removes elements from a JSON value +- [`empty`](empty.md) - checks whether the JSON value has no elements +- [Modifying values](../../features/modifying_values.md) - the article on modifying values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/contains.md b/docs/mkdocs/docs/api/basic_json/contains.md index c6e2e7d77..65ccca142 100644 --- a/docs/mkdocs/docs/api/basic_json/contains.md +++ b/docs/mkdocs/docs/api/basic_json/contains.md @@ -61,11 +61,18 @@ Strong exception safety: if an exception occurs, the original value stays intact ## Complexity -Logarithmic in the size of the JSON object. +1. Logarithmic in the size of the JSON object. +2. Logarithmic in the size of the JSON object. +3. At most one lookup per reference token of `ptr`, each logarithmic in the size of the container at that level: + O(*n* log *m*) for *n* reference tokens and containers of size at most *m*. +4. Deleted; a call with an integral argument does not compile. ## Notes -- This method always returns `#!cpp false` when executed on a JSON type that is not an object. +- Overloads (1) and (2) always return `#!cpp false` when executed on a JSON type that is not an object. Overload (3) + also works on arrays and on primitive values: the empty JSON pointer resolves in every JSON value (so + `#!cpp json(1).contains(""_json_pointer)` returns `#!cpp true`), and `#!cpp json({1, 2}).contains("/1"_json_pointer)` + returns `#!cpp true`. - This method can be executed on any JSON value type. - Calling this function with an integer argument (for example, `#!cpp contains(0)`) does not compile: such an argument would otherwise implicitly convert to a null `#!cpp const char*` and, from there, cause undefined behavior when @@ -134,9 +141,10 @@ Logarithmic in the size of the JSON object. ## See also -- [find](find.md) find a value in an object -- [count](count.md) returns the number of occurrences of a key -- [basic_json_view::contains](../basic_json_view/contains.md) - the same check on a zero-copy view +- [`find`](find.md) - find a value in an object +- [`count`](count.md) - returns the number of occurrences of a key +- [`basic_json_view::contains`](../basic_json_view/contains.md) - the same check on a zero-copy view +- [Element Access](../../features/element_access/index.md#does-this-key-exist) - how to test whether a key exists ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/count.md b/docs/mkdocs/docs/api/basic_json/count.md index 580b79884..1265fed90 100644 --- a/docs/mkdocs/docs/api/basic_json/count.md +++ b/docs/mkdocs/docs/api/basic_json/count.md @@ -85,9 +85,10 @@ Logarithmic in the size of the JSON object. ## See also -- [find](find.md) find a value in an object -- [contains](contains.md) checks whether a key exists -- [basic_json_view::count](../basic_json_view/count.md) - the same check on a zero-copy view +- [`find`](find.md) - find a value in an object +- [`contains`](contains.md) - checks whether a key exists +- [`basic_json_view::count`](../basic_json_view/count.md) - the same check on a zero-copy view +- [Element Access](../../features/element_access/index.md#does-this-key-exist) - how to test whether a key exists ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/crbegin.md b/docs/mkdocs/docs/api/basic_json/crbegin.md index 545f86044..8365e4d19 100644 --- a/docs/mkdocs/docs/api/basic_json/crbegin.md +++ b/docs/mkdocs/docs/api/basic_json/crbegin.md @@ -6,7 +6,13 @@ const_reverse_iterator crbegin() const noexcept; Returns an iterator to the reverse-beginning; that is, the last element. - +`crbegin()` points to the last element, like `rbegin()`, and `rend()` to the position +before the first element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows +link each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.
## Return value @@ -38,9 +44,9 @@ Constant. ## See also -- [crend](crend.md) returns a const reverse iterator to one before the first element -- [rbegin](rbegin.md) returns a reverse iterator to the last element -- [cbegin](cbegin.md) returns a const iterator to the first element +- [`crend`](crend.md) - returns a const reverse iterator to one before the first element +- [`rbegin`](rbegin.md) - returns a reverse iterator to the last element +- [`cbegin`](cbegin.md) - returns a const iterator to the first element - [Iterators](../../features/iterators.md) - the article on iterators ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/crend.md b/docs/mkdocs/docs/api/basic_json/crend.md index 56cc40c52..12c100d4b 100644 --- a/docs/mkdocs/docs/api/basic_json/crend.md +++ b/docs/mkdocs/docs/api/basic_json/crend.md @@ -7,7 +7,13 @@ const_reverse_iterator crend() const noexcept; Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior. - +`crend()` points to the position before the first element, like `rend()`, and `rbegin()` +to the last element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link +each reverse iterator to the forward iterator it stores, and dashed cells are past-the-last positions.
## Return value @@ -39,9 +45,9 @@ Constant. ## See also -- [crbegin](crbegin.md) returns a const reverse iterator to the last element -- [rend](rend.md) returns a reverse iterator to one before the first element -- [cend](cend.md) returns a const iterator to one past the last element +- [`crbegin`](crbegin.md) - returns a const reverse iterator to the last element +- [`rend`](rend.md) - returns a reverse iterator to one before the first element +- [`cend`](cend.md) - returns a const iterator to one past the last element - [Iterators](../../features/iterators.md) - the article on iterators ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md b/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md index 2c3a50217..9372a286d 100644 --- a/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md +++ b/docs/mkdocs/docs/api/basic_json/default_object_comparator_t.md @@ -32,8 +32,10 @@ The actual comparator used depends on [`object_t`](object_t.md) and can be obtai ## See also -- [object_comparator_t](object_comparator_t.md) the comparator actually used by `object_t` -- [object_t](object_t.md) the type used to store JSON objects +- [`object_comparator_t`](object_comparator_t.md) - the comparator actually used by `object_t` +- [`object_t`](object_t.md) - the type used to store JSON objects +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ObjectType` template parameter +- [Object order](../../features/object_order.md) - preserve the insertion order of keys ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/diff.md b/docs/mkdocs/docs/api/basic_json/diff.md index c4e710a7d..162882cdb 100644 --- a/docs/mkdocs/docs/api/basic_json/diff.md +++ b/docs/mkdocs/docs/api/basic_json/diff.md @@ -2,17 +2,28 @@ ```cpp static basic_json diff(const basic_json& source, - const basic_json& target); + const basic_json& target, + const string_t& path = ""); ``` Creates a [JSON Patch](http://jsonpatch.com) so that value `source` can be changed into the value `target` by calling [`patch`](patch.md) function. -For two JSON values `source` and `target`, the following code always yields `#!cpp true`: +For two JSON values `source` and `target`, the following code yields `#!cpp true`: ```cpp source.patch(diff(source, target)) == target; ``` +The equality holds up to [`operator==`](operator_eq.md), so it has the following exceptions: + +- A value that is not equal to itself cannot round-trip. This applies to `NaN` (also nested in an array or object) and + to [discarded](is_discarded.md) values: `diff` emits a `replace` operation for them. A `NaN` in the patch is + serialized as `#!json null`, so a patch that was dumped and parsed again would set `#!json null`. +- Numbers that compare equal produce no operation, even if their types differ or if one is zero and the other is + negative zero: `diff(1, 1.0)` (integer and floating-point), `diff(1u, 1)` (unsigned and signed integer) and + `diff(0.0, -0.0)` (positive and negative zero) all return `#!json []`. The patched value is then the `source` and + keeps its number type and sign. + ## Parameters `source` (in) @@ -21,6 +32,12 @@ source.patch(diff(source, target)) == target; `target` (in) : JSON value to compare against +`path` (in) +: a prefix that is put verbatim in front of the `path` member of every operation (default: `""`, which addresses the + root of the value). The prefix is neither escaped nor validated: `#!cpp diff(1, 2, "abc")` yields an operation with + the `path` `abc`, which is not a valid JSON Pointer. Use it with a valid JSON Pointer such as `/root` and escape + `~` and `/` in its reference tokens (see [JSON Pointer](../../features/json_pointer.md)). + ## Return value a JSON patch to convert the `source` to `target` @@ -31,11 +48,32 @@ Strong guarantee: `source` and `target` are never modified. ## Complexity -Linear in the lengths of `source` and `target`. +Linear in the total number of values (including nested ones) in `source` and `target`, times the cost of a key-based +object operation (looking up a key in an object): logarithmic for [`json`](../json.md), and linear for +[`ordered_json`](../ordered_json.md) (see [`ordered_map` complexity](../ordered_map.md#complexity)). For +`ordered_json`, diffing two objects with `n` and `m` members therefore takes O((n+m)²) when their keys do not line up +(e.g., a key was added or the keys are in a different order). The size of the patch is proportional to the number of +operations times the length of their paths, so a small change deep inside a value yields a long `path`. ## Notes -Currently, only `remove`, `add`, and `replace` operations are generated. +- Currently, only `remove`, `add`, and `replace` operations are generated. +- The patch is correct, but not guaranteed to be minimal. For instance, `diff([1,2,3], [0,1,2,3])` yields three + `replace` operations and one `add` operation instead of a single insertion. +- Differences between two arrays are reported index by index. Elements that were added at the end of the array are added + with `add` operations on the path `/-` (appended in order), and elements that were removed are removed with `remove` + operations from the highest index down to the lowest, so that the remaining indices stay valid. +- For objects, the operations for the members of `source` come first (`replace`, `remove`, or the operations for nested + values, in the iteration order of `source`), followed by `add` operations for the members that only `target` has. +- For [`ordered_json`](../ordered_json.md), objects with the same keys in a different order are different. As a patch + cannot reorder members, `diff` removes all keys of the `source` object and adds them again in the order of the + `target`. +- If `source` and `target` differ as a whole (e.g., different types), the patch consists of a single `replace` + operation for the root of the value, i.e., with the `path` `""` (or the given `path` prefix). +- The `value` members of the patch hold copies of values of `target`. A [binary](../../features/binary_values.md) value + has no JSON representation: when a patch that contains one is serialized, it becomes an object such as + `#!json {"bytes":[1,3],"subtype":null}`, so a parsed patch no longer holds a binary value (and would set that object + instead). ## Examples @@ -55,11 +93,12 @@ Currently, only `remove`, `add`, and `replace` operations are generated. ## See also -- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) -- [patch](patch.md) applies a JSON Patch -- [patch_inplace](patch_inplace.md) applies a JSON Patch in place -- [merge_patch](merge_patch.md) applies a JSON Merge Patch -- [merge_diff](merge_diff.md) creates a diff as a JSON Merge Patch +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - specification of JSON Patch +- [`patch`](patch.md) - applies a JSON Patch +- [`patch_inplace`](patch_inplace.md) - applies a JSON Patch in place +- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch +- [`merge_diff`](merge_diff.md) - creates a diff as a JSON Merge Patch +- [JSON Patch and Diff](../../features/json_patch.md) - the article on JSON Patch ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/dump.md b/docs/mkdocs/docs/api/basic_json/dump.md index 23c34cd0c..a2fce5536 100644 --- a/docs/mkdocs/docs/api/basic_json/dump.md +++ b/docs/mkdocs/docs/api/basic_json/dump.md @@ -89,9 +89,9 @@ Binary values are serialized as an object containing two keys: ## See also -- [to_string](to_string.md) returns a string representation of a JSON value -- [operator<<](../operator_ltlt.md) serialize to stream -- [`basic_json_view::dump`](../basic_json_view/dump.md) the corresponding function of `basic_json_view`, serializing +- [`to_string`](to_string.md) - returns a string representation of a JSON value +- [`operator<<`](../operator_ltlt.md) - serialize to stream +- [`basic_json_view::dump`](../basic_json_view/dump.md) - the corresponding function of `basic_json_view`, serializing directly from a flat index without building a `basic_json` value - [Serialization](../../features/serialization.md) - the serialization article diff --git a/docs/mkdocs/docs/api/basic_json/emplace.md b/docs/mkdocs/docs/api/basic_json/emplace.md index b1fd856ae..b4c8bb0bb 100644 --- a/docs/mkdocs/docs/api/basic_json/emplace.md +++ b/docs/mkdocs/docs/api/basic_json/emplace.md @@ -63,8 +63,8 @@ Logarithmic in the size of the container, O(log(`size()`)). ## See also -- [emplace_back](emplace_back.md) add a value to an array -- [insert](insert.md) add values to an array/object +- [`emplace_back`](emplace_back.md) - add a value to an array +- [`insert`](insert.md) - add values to an array/object - [Modifying values](../../features/modifying_values.md) - the article on modifying values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/emplace_back.md b/docs/mkdocs/docs/api/basic_json/emplace_back.md index 38a6d5c3d..d6ea4cd01 100644 --- a/docs/mkdocs/docs/api/basic_json/emplace_back.md +++ b/docs/mkdocs/docs/api/basic_json/emplace_back.md @@ -61,8 +61,8 @@ Amortized constant. ## See also -- [operator+=](operator+=.md) add a value to an array/object -- [push_back](push_back.md) add a value to an array/object +- [`operator+=`](operator+=.md) - add a value to an array/object +- [`push_back`](push_back.md) - add a value to an array/object - [Modifying values](../../features/modifying_values.md) - the article on modifying values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/empty.md b/docs/mkdocs/docs/api/basic_json/empty.md index 1f096c956..06b51932d 100644 --- a/docs/mkdocs/docs/api/basic_json/empty.md +++ b/docs/mkdocs/docs/api/basic_json/empty.md @@ -41,7 +41,7 @@ bool empty() const noexcept ## Notes -This function does not return whether a string stored as JSON value is empty -- it returns whether the JSON container +This function does not return whether a string stored as JSON value is empty — it returns whether the JSON container itself is empty which is `#!cpp false` in the case of a string. ## Examples @@ -62,9 +62,9 @@ itself is empty which is `#!cpp false` in the case of a string. ## See also -- [size](size.md) returns the number of elements -- [clear](clear.md) clears the content and resets the value to the default value -- [basic_json_view::empty](../basic_json_view/empty.md) - the same check on a zero-copy view +- [`size`](size.md) - returns the number of elements +- [`clear`](clear.md) - clears the content and resets the value to the default value +- [`basic_json_view::empty`](../basic_json_view/empty.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/end.md b/docs/mkdocs/docs/api/basic_json/end.md index e94ec78a2..13459beb6 100644 --- a/docs/mkdocs/docs/api/basic_json/end.md +++ b/docs/mkdocs/docs/api/basic_json/end.md @@ -7,7 +7,12 @@ const_iterator end() const noexcept; Returns an iterator to one past the last element. - +`end()` points to the position after the last element and `begin()` to the first element; +the dashed cell is the past-the-last position, which must not be dereferenced.
## Return value @@ -39,11 +44,11 @@ Constant. ## See also -- [begin](begin.md) returns an iterator to the first element -- [cend](cend.md) returns a const iterator to one past the last element -- [rend](rend.md) returns a reverse iterator to one before the first element +- [`begin`](begin.md) - returns an iterator to the first element +- [`cend`](cend.md) - returns a const iterator to one past the last element +- [`rend`](rend.md) - returns a reverse iterator to one before the first element - [Iterators](../../features/iterators.md) - the article on iterators -- [basic_json_view::end](../basic_json_view/end.md) - the same iteration on a zero-copy view +- [`basic_json_view::end`](../basic_json_view/end.md) - the same iteration on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/end_pos.md b/docs/mkdocs/docs/api/basic_json/end_pos.md index 95b07297f..7ec88996c 100644 --- a/docs/mkdocs/docs/api/basic_json/end_pos.md +++ b/docs/mkdocs/docs/api/basic_json/end_pos.md @@ -60,8 +60,9 @@ Constant. ## See also -- [start_pos](start_pos.md) to access the start position -- [JSON_DIAGNOSTIC_POSITIONS](../macros/json_diagnostic_positions.md) for an overview of the diagnostic positions +- [`start_pos`](start_pos.md) - to access the start position +- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - overview of the supported conversions +- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/erase.md b/docs/mkdocs/docs/api/basic_json/erase.md index 1782b6162..68eccc5a3 100644 --- a/docs/mkdocs/docs/api/basic_json/erase.md +++ b/docs/mkdocs/docs/api/basic_json/erase.md @@ -204,8 +204,8 @@ Strong exception safety: if an exception occurs, the original value stays intact ## See also -- [clear](clear.md) clears the contents -- [insert](insert.md) add values to an array/object +- [`clear`](clear.md) - clears the contents +- [`insert`](insert.md) - add values to an array/object - [Modifying values](../../features/modifying_values.md) - the article on modifying values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/error_handler_t.md b/docs/mkdocs/docs/api/basic_json/error_handler_t.md index a80f74a55..9dd205e1d 100644 --- a/docs/mkdocs/docs/api/basic_json/error_handler_t.md +++ b/docs/mkdocs/docs/api/basic_json/error_handler_t.md @@ -61,7 +61,7 @@ keep ## See also -- [dump](dump.md) serializes a JSON value, with an `error_handler_t` parameter to configure invalid UTF-8 handling +- [`dump`](dump.md) - serializes a JSON value, with an `error_handler_t` parameter to configure invalid UTF-8 handling - [Handling invalid UTF-8](../../features/serialization.md#handling-invalid-utf-8) - the article on handling invalid UTF-8 ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/exception.md b/docs/mkdocs/docs/api/basic_json/exception.md index 88cf51b1f..7b3209e48 100644 --- a/docs/mkdocs/docs/api/basic_json/exception.md +++ b/docs/mkdocs/docs/api/basic_json/exception.md @@ -40,6 +40,9 @@ classDiagram style json_exception fill:#CCCCFF ``` +Class hierarchy of the library's exceptions; arrows point from a derived class to its +base class, and the highlighted box is `basic_json::exception`.
+ Subclasses: - [`parse_error`](parse_error.md) for exceptions indicating a parse error @@ -80,7 +83,11 @@ constructor. ## See also -[List of exceptions](../../home/exceptions.md) +- [List of exceptions](../../home/exceptions.md) - overview of all exceptions thrown by the library +- [Working Without Exceptions](../../features/no_exceptions.md) - using the library without exceptions +- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value +- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - parsing alternatives that do not throw +- [Debugging](../../home/debugging.md) - debugging aids ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/find.md b/docs/mkdocs/docs/api/basic_json/find.md index 8883dc398..4b2018569 100644 --- a/docs/mkdocs/docs/api/basic_json/find.md +++ b/docs/mkdocs/docs/api/basic_json/find.md @@ -91,10 +91,11 @@ Logarithmic in the size of the JSON object. ## See also -- [count](count.md) returns the number of occurrences of a key -- [contains](contains.md) checks whether a key exists -- [basic_json_view::find](../basic_json_view/find.md) - the same lookup on a zero-copy view (a duplicate key resolves +- [`count`](count.md) - returns the number of occurrences of a key +- [`contains`](contains.md) - checks whether a key exists +- [`basic_json_view::find`](../basic_json_view/find.md) - the same lookup on a zero-copy view (a duplicate key resolves to the first member, whereas `parse()` keeps the last) +- [Element Access](../../features/element_access/index.md#does-this-key-exist) - how to test whether a key exists ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/flatten.md b/docs/mkdocs/docs/api/basic_json/flatten.md index a232a538a..6c52010b8 100644 --- a/docs/mkdocs/docs/api/basic_json/flatten.md +++ b/docs/mkdocs/docs/api/basic_json/flatten.md @@ -58,7 +58,8 @@ Empty objects and arrays are flattened to `#!json null` and will not be reconstr ## See also -- [unflatten](unflatten.md) the reverse function +- [`unflatten`](unflatten.md) - the reverse function +- [JSON Pointer](../../features/json_pointer.md#flatten-unflatten) - the article on JSON Pointer and flattening ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/format_as.md b/docs/mkdocs/docs/api/basic_json/format_as.md index 1d20416c3..3c01bdf03 100644 --- a/docs/mkdocs/docs/api/basic_json/format_as.md +++ b/docs/mkdocs/docs/api/basic_json/format_as.md @@ -86,8 +86,8 @@ std::string format_as(const BasicJsonType& j) ## See also -- [dump](dump.md) -- [std::formatterClass hierarchy of the library's exceptions; arrows point from a derived class to its +base class, and the highlighted box is `basic_json::invalid_iterator`.
+ ## Member functions - **what** - returns explanatory string @@ -66,12 +69,14 @@ classDiagram ## See also -- [`exception`](exception.md) for the base class of all exceptions thrown by the library -- [List of iterator errors](../../home/exceptions.md#iterator-errors) -- [`parse_error`](parse_error.md) for exceptions indicating a parse error -- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type -- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range -- [`other_error`](other_error.md) for exceptions indicating other library errors +- [`exception`](exception.md) - the base class of all exceptions thrown by the library +- [List of iterator errors](../../home/exceptions.md#iterator-errors) - overview of iterator errors (`invalid_iterator`) +- [`parse_error`](parse_error.md) - exceptions indicating a parse error +- [`type_error`](type_error.md) - exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) - exceptions indicating access out of the defined range +- [`other_error`](other_error.md) - exceptions indicating other library errors +- [Exceptions](../../home/exceptions.md) - all exceptions and their error codes +- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_array.md b/docs/mkdocs/docs/api/basic_json/is_array.md index 9f2bfc6fc..cc6ca1469 100644 --- a/docs/mkdocs/docs/api/basic_json/is_array.md +++ b/docs/mkdocs/docs/api/basic_json/is_array.md @@ -36,11 +36,12 @@ Constant. ## See also -- [is_object](is_object.md) checks whether the JSON value is an object -- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object) -- [type](type.md) returns the type of the JSON value -- [array_t](array_t.md) the type used to store JSON arrays -- [basic_json_view::is_array](../basic_json_view/is_array.md) - the same check on a zero-copy view +- [`is_object`](is_object.md) - checks whether the JSON value is an object +- [`is_structured`](is_structured.md) - checks whether the JSON value is structured (array or object) +- [`type`](type.md) - returns the type of the JSON value +- [`array_t`](array_t.md) - the type used to store JSON arrays +- [`basic_json_view::is_array`](../basic_json_view/is_array.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_binary.md b/docs/mkdocs/docs/api/basic_json/is_binary.md index 87bb8b66c..ee52d11de 100644 --- a/docs/mkdocs/docs/api/basic_json/is_binary.md +++ b/docs/mkdocs/docs/api/basic_json/is_binary.md @@ -36,10 +36,11 @@ Constant. ## See also -- [is_primitive](is_primitive.md) checks whether the JSON value is primitive -- [binary_t](binary_t.md) the type used to store binary values -- [get_binary](get_binary.md) returns a reference to the stored binary value -- [basic_json_view::is_binary](../basic_json_view/is_binary.md) - the same check on a zero-copy view +- [Binary values](../../features/binary_values.md) - how binary values and subtypes are handled +- [`is_primitive`](is_primitive.md) - checks whether the JSON value is primitive +- [`binary_t`](binary_t.md) - the type used to store binary values +- [`get_binary`](get_binary.md) - returns a reference to the stored binary value +- [`basic_json_view::is_binary`](../basic_json_view/is_binary.md) - the same check on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_boolean.md b/docs/mkdocs/docs/api/basic_json/is_boolean.md index c7585812c..4f349e551 100644 --- a/docs/mkdocs/docs/api/basic_json/is_boolean.md +++ b/docs/mkdocs/docs/api/basic_json/is_boolean.md @@ -36,9 +36,10 @@ Constant. ## See also -- [boolean_t](boolean_t.md) the type used to store JSON booleans -- [is_primitive](is_primitive.md) checks whether the JSON value is primitive -- [basic_json_view::is_boolean](../basic_json_view/is_boolean.md) - the same check on a zero-copy view +- [`boolean_t`](boolean_t.md) - the type used to store JSON booleans +- [`is_primitive`](is_primitive.md) - checks whether the JSON value is primitive +- [`basic_json_view::is_boolean`](../basic_json_view/is_boolean.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_discarded.md b/docs/mkdocs/docs/api/basic_json/is_discarded.md index 3d434f577..6dcd59675 100644 --- a/docs/mkdocs/docs/api/basic_json/is_discarded.md +++ b/docs/mkdocs/docs/api/basic_json/is_discarded.md @@ -87,8 +87,9 @@ with `allow_exceptions` set to `#!cpp false`: a parse error then yields a discar ## See also -- [basic_json_view::is_discarded](../basic_json_view/is_discarded.md) - the corresponding check on a zero-copy view, +- [`basic_json_view::is_discarded`](../basic_json_view/is_discarded.md) - the corresponding check on a zero-copy view, which is `#!cpp true` if the view refers to no value +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_null.md b/docs/mkdocs/docs/api/basic_json/is_null.md index 3823b96dd..6b7647fe0 100644 --- a/docs/mkdocs/docs/api/basic_json/is_null.md +++ b/docs/mkdocs/docs/api/basic_json/is_null.md @@ -36,11 +36,12 @@ Constant. ## See also -- [is_array](is_array.md) checks whether the JSON value is an array -- [is_object](is_object.md) checks whether the JSON value is an object -- [type](type.md) returns the type of the JSON value -- [value_t](value_t.md) the enumeration of JSON types -- [basic_json_view::is_null](../basic_json_view/is_null.md) - the same check on a zero-copy view +- [`is_array`](is_array.md) - checks whether the JSON value is an array +- [`is_object`](is_object.md) - checks whether the JSON value is an object +- [`type`](type.md) - returns the type of the JSON value +- [`value_t`](value_t.md) - the enumeration of JSON types +- [`basic_json_view::is_null`](../basic_json_view/is_null.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number.md b/docs/mkdocs/docs/api/basic_json/is_number.md index 5db28d3e0..7e4b2fec3 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number.md +++ b/docs/mkdocs/docs/api/basic_json/is_number.md @@ -46,10 +46,12 @@ constexpr bool is_number() const noexcept ## See also -- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number -- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number -- [is_number_float()](is_number_float.md) check if the value is a floating-point number -- [basic_json_view::is_number](../basic_json_view/is_number.md) - the same check on a zero-copy view +- [`is_number_integer()`](is_number_integer.md) - check if the value is an integer or unsigned integer number +- [`is_number_unsigned()`](is_number_unsigned.md) - check if the value is an unsigned integer number +- [`is_number_float()`](is_number_float.md) - check if the value is a floating-point number +- [`basic_json_view::is_number`](../basic_json_view/is_number.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored +- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number_float.md b/docs/mkdocs/docs/api/basic_json/is_number_float.md index c94825b41..6aad56803 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number_float.md +++ b/docs/mkdocs/docs/api/basic_json/is_number_float.md @@ -37,10 +37,12 @@ Constant. ## See also -- [is_number()](is_number.md) check if the value is a number -- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number -- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number -- [basic_json_view::is_number_float](../basic_json_view/is_number_float.md) - the same check on a zero-copy view +- [`is_number()`](is_number.md) - check if the value is a number +- [`is_number_integer()`](is_number_integer.md) - check if the value is an integer or unsigned integer number +- [`is_number_unsigned()`](is_number_unsigned.md) - check if the value is an unsigned integer number +- [`basic_json_view::is_number_float`](../basic_json_view/is_number_float.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored +- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number_integer.md b/docs/mkdocs/docs/api/basic_json/is_number_integer.md index 71e2aba20..16951e092 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number_integer.md +++ b/docs/mkdocs/docs/api/basic_json/is_number_integer.md @@ -37,10 +37,12 @@ Constant. ## See also -- [is_number()](is_number.md) check if the value is a number -- [is_number_unsigned()](is_number_unsigned.md) check if the value is an unsigned integer number -- [is_number_float()](is_number_float.md) check if the value is a floating-point number -- [basic_json_view::is_number_integer](../basic_json_view/is_number_integer.md) - the same check on a zero-copy view +- [`is_number()`](is_number.md) - check if the value is a number +- [`is_number_unsigned()`](is_number_unsigned.md) - check if the value is an unsigned integer number +- [`is_number_float()`](is_number_float.md) - check if the value is a floating-point number +- [`basic_json_view::is_number_integer`](../basic_json_view/is_number_integer.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored +- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md b/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md index 2e94d10d6..832f778c2 100644 --- a/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md +++ b/docs/mkdocs/docs/api/basic_json/is_number_unsigned.md @@ -40,10 +40,12 @@ Constant. ## See also -- [is_number()](is_number.md) check if the value is a number -- [is_number_integer()](is_number_integer.md) check if the value is an integer or unsigned integer number -- [is_number_float()](is_number_float.md) check if the value is a floating-point number -- [basic_json_view::is_number_unsigned](../basic_json_view/is_number_unsigned.md) - the same check on a zero-copy view +- [`is_number()`](is_number.md) - check if the value is a number +- [`is_number_integer()`](is_number_integer.md) - check if the value is an integer or unsigned integer number +- [`is_number_float()`](is_number_float.md) - check if the value is a floating-point number +- [`basic_json_view::is_number_unsigned`](../basic_json_view/is_number_unsigned.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored +- [Number Handling](../../features/types/number_handling.md) - how numbers are stored and converted ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_object.md b/docs/mkdocs/docs/api/basic_json/is_object.md index 2105a28a7..7f7cedea4 100644 --- a/docs/mkdocs/docs/api/basic_json/is_object.md +++ b/docs/mkdocs/docs/api/basic_json/is_object.md @@ -36,11 +36,12 @@ Constant. ## See also -- [is_array](is_array.md) checks whether the JSON value is an array -- [is_structured](is_structured.md) checks whether the JSON value is structured (array or object) -- [type](type.md) returns the type of the JSON value -- [object_t](object_t.md) the type used to store JSON objects -- [basic_json_view::is_object](../basic_json_view/is_object.md) - the same check on a zero-copy view +- [`is_array`](is_array.md) - checks whether the JSON value is an array +- [`is_structured`](is_structured.md) - checks whether the JSON value is structured (array or object) +- [`type`](type.md) - returns the type of the JSON value +- [`object_t`](object_t.md) - the type used to store JSON objects +- [`basic_json_view::is_object`](../basic_json_view/is_object.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_primitive.md b/docs/mkdocs/docs/api/basic_json/is_primitive.md index 70836ecdd..0e24c5073 100644 --- a/docs/mkdocs/docs/api/basic_json/is_primitive.md +++ b/docs/mkdocs/docs/api/basic_json/is_primitive.md @@ -56,13 +56,14 @@ This library extends primitive types to binary types, because binary types are r ## See also -- [is_structured()](is_structured.md) returns whether the JSON value is structured -- [is_null()](is_null.md) returns whether the JSON value is `null` -- [is_string()](is_string.md) returns whether the JSON value is a string -- [is_boolean()](is_boolean.md) returns whether the JSON value is a boolean -- [is_number()](is_number.md) returns whether the JSON value is a number -- [is_binary()](is_binary.md) returns whether the JSON value is a binary array -- [basic_json_view::is_primitive](../basic_json_view/is_primitive.md) - the same check on a zero-copy view +- [`is_structured()`](is_structured.md) - returns whether the JSON value is structured +- [`is_null()`](is_null.md) - returns whether the JSON value is `null` +- [`is_string()`](is_string.md) - returns whether the JSON value is a string +- [`is_boolean()`](is_boolean.md) - returns whether the JSON value is a boolean +- [`is_number()`](is_number.md) - returns whether the JSON value is a number +- [`is_binary()`](is_binary.md) - returns whether the JSON value is a binary array +- [`basic_json_view::is_primitive`](../basic_json_view/is_primitive.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_string.md b/docs/mkdocs/docs/api/basic_json/is_string.md index a1d19c14d..e8ba09d1e 100644 --- a/docs/mkdocs/docs/api/basic_json/is_string.md +++ b/docs/mkdocs/docs/api/basic_json/is_string.md @@ -36,10 +36,11 @@ Constant. ## See also -- [is_primitive](is_primitive.md) checks whether the JSON value is primitive -- [type](type.md) returns the type of the JSON value -- [string_t](string_t.md) the type used to store JSON strings -- [basic_json_view::is_string](../basic_json_view/is_string.md) - the same check on a zero-copy view +- [`is_primitive`](is_primitive.md) - checks whether the JSON value is primitive +- [`type`](type.md) - returns the type of the JSON value +- [`string_t`](string_t.md) - the type used to store JSON strings +- [`basic_json_view::is_string`](../basic_json_view/is_string.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/is_structured.md b/docs/mkdocs/docs/api/basic_json/is_structured.md index a67f2778b..0e150e2c7 100644 --- a/docs/mkdocs/docs/api/basic_json/is_structured.md +++ b/docs/mkdocs/docs/api/basic_json/is_structured.md @@ -54,10 +54,11 @@ Note that though strings are containers in C++, they are treated as primitive va ## See also -- [is_primitive()](is_primitive.md) returns whether JSON value is primitive -- [is_array()](is_array.md) returns whether the value is an array -- [is_object()](is_object.md) returns whether the value is an object -- [basic_json_view::is_structured](../basic_json_view/is_structured.md) - the same check on a zero-copy view +- [`is_primitive()`](is_primitive.md) - returns whether JSON value is primitive +- [`is_array()`](is_array.md) - returns whether the value is an array +- [`is_object()`](is_object.md) - returns whether the value is an object +- [`basic_json_view::is_structured`](../basic_json_view/is_structured.md) - the same check on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/items.md b/docs/mkdocs/docs/api/basic_json/items.md index 025002e07..1316826fc 100644 --- a/docs/mkdocs/docs/api/basic_json/items.md +++ b/docs/mkdocs/docs/api/basic_json/items.md @@ -54,7 +54,7 @@ using element_type = decltype(*j_object.items().begin()); ``` The per-element type (`iteration_proxy_value`) lives in the library's internal `detail` namespace and is -intentionally unspecified as a stable, named type -- `decltype` is the supported way to obtain it, but its exact +intentionally unspecified as a stable, named type — `decltype` is the supported way to obtain it, but its exact name/definition may change between versions. ## Return value @@ -97,10 +97,11 @@ When iterating over an array, `key()` will return the index of the element as st ## See also -- [begin](begin.md) returns an iterator to the first element -- [end](end.md) returns an iterator to one past the last element -- [basic_json_view::items](../basic_json_view/items.md) - the same range on a zero-copy view (`#!cpp const auto`, +- [`begin`](begin.md) - returns an iterator to the first element +- [`end`](end.md) - returns an iterator to one past the last element +- [`basic_json_view::items`](../basic_json_view/items.md) - the same range on a zero-copy view (`#!cpp const auto`, not `#!cpp const auto&`: items are produced on the fly; document order, not sorted; duplicate keys are visited) +- [Iterators](../../features/iterators.md#access-object-keys-during-iteration) - the article on iterating over keys and values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/json_base_class_t.md b/docs/mkdocs/docs/api/basic_json/json_base_class_t.md index 2beed5a22..7fa3ca913 100644 --- a/docs/mkdocs/docs/api/basic_json/json_base_class_t.md +++ b/docs/mkdocs/docs/api/basic_json/json_base_class_t.md @@ -57,7 +57,7 @@ same name. Hidden members remain accessible via [`as_base_class`](as_base_class. ## See also -- [as_base_class](as_base_class.md) - access the custom base class +- [`as_base_class`](as_base_class.md) - access the custom base class - [Template Parameter Requirements](../../features/types/template_parameters.md#custombaseclass) - the requirements for `CustomBaseClass` ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/json_serializer.md b/docs/mkdocs/docs/api/basic_json/json_serializer.md index 011f7d113..7ded9c5fe 100644 --- a/docs/mkdocs/docs/api/basic_json/json_serializer.md +++ b/docs/mkdocs/docs/api/basic_json/json_serializer.md @@ -44,10 +44,11 @@ deserializes. See [Template Parameter Requirements](../../features/types/templat ## See also -- [adl_serializer](../adl_serializer/index.md) the default `json_serializer` -- [get](get.md) explicit type conversion using the `json_serializer`'s `from_json()` method -- [get_to](get_to.md) explicit type conversion into a variable using the `json_serializer`'s `from_json()` method +- [`adl_serializer`](../adl_serializer/index.md) - the default `json_serializer` +- [`get`](get.md) - explicit type conversion using the `json_serializer`'s `from_json()` method +- [`get_to`](get_to.md) - explicit type conversion into a variable using the `json_serializer`'s `from_json()` method - [Arbitrary Type Conversions](../../features/arbitrary_types.md) - the article on converting between JSON values and arbitrary types +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `JSONSerializer` template parameter ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/max_size.md b/docs/mkdocs/docs/api/basic_json/max_size.md index 5896a2afd..39ca2d3f7 100644 --- a/docs/mkdocs/docs/api/basic_json/max_size.md +++ b/docs/mkdocs/docs/api/basic_json/max_size.md @@ -33,7 +33,7 @@ constant complexity. ## Notes -This function does not return the maximal length of a string stored as JSON value -- it returns the maximal number of +This function does not return the maximal length of a string stored as JSON value — it returns the maximal number of string elements the JSON value can store which is `1`. ## Examples @@ -56,9 +56,9 @@ string elements the JSON value can store which is `1`. ## See also -- [size](size.md) returns the number of elements -- [array_t](array_t.md) the type used to store JSON arrays -- [object_t](object_t.md) the type used to store JSON objects +- [`size`](size.md) - returns the number of elements +- [`array_t`](array_t.md) - the type used to store JSON arrays +- [`object_t`](object_t.md) - the type used to store JSON objects ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/merge_diff.md b/docs/mkdocs/docs/api/basic_json/merge_diff.md index b02ac3e54..776b84fb4 100644 --- a/docs/mkdocs/docs/api/basic_json/merge_diff.md +++ b/docs/mkdocs/docs/api/basic_json/merge_diff.md @@ -70,9 +70,10 @@ object operation (looking up a key, or adding one to the patch): logarithmic for ## See also -- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) -- [merge_patch](merge_patch.md) applies a JSON Merge Patch -- [diff](diff.md) creates a diff as a JSON Patch +- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - specification of JSON Merge Patch +- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch +- [`diff`](diff.md) - creates a diff as a JSON Patch +- [JSON Merge Patch](../../features/merge_patch.md) - the article on JSON Merge Patch ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/merge_patch.md b/docs/mkdocs/docs/api/basic_json/merge_patch.md index 1fafb1ece..fe83f6cc3 100644 --- a/docs/mkdocs/docs/api/basic_json/merge_patch.md +++ b/docs/mkdocs/docs/api/basic_json/merge_patch.md @@ -39,13 +39,33 @@ Basic guarantee: if an exception is thrown during the operation, the JSON value ## Complexity -Linear in the lengths of `apply_patch`. +Linear in the total number of values (including nested ones) in `apply_patch`, times the cost of a key-based object +operation (looking up, adding, or erasing a member): logarithmic for [`json`](../json.md), and linear for +[`ordered_json`](../ordered_json.md) (see [`ordered_map` complexity](../ordered_map.md#complexity)). For +`ordered_json`, patching an object that has `n` members with a patch that has `m` members therefore takes O(n·m). The +cost also includes one copy of `apply_patch` (see the notes below). ## Notes -`apply_patch` may be `#!cpp *this` itself or refer to a value contained in `#!cpp *this` (for example, a subobject -returned by `#!cpp (*this)[key]`); it is read as it was when `merge_patch()` was called, before any modification of -`#!cpp *this`. +- `apply_patch` may be `#!cpp *this` itself or refer to a value contained in `#!cpp *this` (for example, a subobject + returned by `#!cpp (*this)[key]`); it is read as it was when `merge_patch()` was called, before any modification of + `#!cpp *this`. To make this possible, the function copies `apply_patch` before it modifies `#!cpp *this`, so the cost + includes one copy of the patch. +- A merge patch uses `#!json null` to remove a member, so it cannot set a member to `#!json null`: applying + `#!json {"a":null}` to `#!json {"a":1}` gives `#!json {}`. +- Arrays are not merged: an array in the patch replaces the target value as a whole, and a `#!json null` inside an + array is kept as an element. `#!json null` members of the target that the patch does not mention are preserved. +- A `#!json null` in the patch only removes a member; it does not prevent the creation of the enclosing objects. + Applying `#!json {"a":{"b":null}}` to `#!json {}` gives `#!json {"a":{}}` (see example 15 in Appendix A of the RFC). +- If `apply_patch` is not an object, it replaces the target as a whole. In particular, a `#!json null` patch turns the + target into `#!json null`. If `apply_patch` is an object and the target is not, the target is first replaced by an + empty object, so applying `#!json {}` to `#!json 1` gives `#!json {}`. +- A merge patch cannot express every change; for example, it cannot reorder array elements or remove a specific array + element. Use [JSON Patch](../../features/json_patch.md) ([RFC 6902](https://tools.ietf.org/html/rfc6902)) for that. + [`merge_diff`](merge_diff.md) has a matching limitation, see its notes. +- A [discarded](is_discarded.md) value is treated like any other non-object value: a discarded + `apply_patch` turns the target into a discarded value, and an object patch replaces a discarded target by an object + as described above. ## Examples @@ -65,9 +85,10 @@ returned by `#!cpp (*this)[key]`); it is read as it was when `merge_patch()` was ## See also -- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) -- [patch](patch.md) apply a JSON patch -- [merge_diff](merge_diff.md) creates a diff as a JSON Merge Patch +- [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396) - specification of JSON Merge Patch +- [`patch`](patch.md) - apply a JSON patch +- [`merge_diff`](merge_diff.md) - creates a diff as a JSON Merge Patch +- [JSON Merge Patch](../../features/merge_patch.md) - the article on JSON Merge Patch ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/meta.md b/docs/mkdocs/docs/api/basic_json/meta.md index 9b1ac2a4e..3f465826d 100644 --- a/docs/mkdocs/docs/api/basic_json/meta.md +++ b/docs/mkdocs/docs/api/basic_json/meta.md @@ -48,8 +48,11 @@ Constant. ## See also -- [**NLOHMANN_JSON_VERSION_MAJOR**/**NLOHMANN_JSON_VERSION_MINOR**/**NLOHMANN_JSON_VERSION_PATCH**](../macros/nlohmann_json_version_major.md) - \- library version information +- [`NLOHMANN_JSON_VERSION_MAJOR`](../macros/nlohmann_json_version_major.md) / + [`NLOHMANN_JSON_VERSION_MINOR`](../macros/nlohmann_json_version_major.md) / + [`NLOHMANN_JSON_VERSION_PATCH`](../macros/nlohmann_json_version_major.md) - library version information +- [Integration](../../integration/index.md) - integrate the library +- [Supported Macros](../../features/macros.md) - guide to all supported macros ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/number_float_t.md b/docs/mkdocs/docs/api/basic_json/number_float_t.md index cf482d6f0..142f3f023 100644 --- a/docs/mkdocs/docs/api/basic_json/number_float_t.md +++ b/docs/mkdocs/docs/api/basic_json/number_float_t.md @@ -84,10 +84,11 @@ Floating-point number values are stored directly inside a `basic_json` type. ## See also -- [number_integer_t](number_integer_t.md) the type used to store JSON integer numbers -- [number_unsigned_t](number_unsigned_t.md) the type used to store JSON unsigned integer numbers -- [is_number_float](is_number_float.md) checks whether the JSON value is a floating-point number +- [`number_integer_t`](number_integer_t.md) - the type used to store JSON integer numbers +- [`number_unsigned_t`](number_unsigned_t.md) - the type used to store JSON unsigned integer numbers +- [`is_number_float`](is_number_float.md) - checks whether the JSON value is a floating-point number - [Number Handling](../../features/types/number_handling.md) - the article on number handling +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the number template parameters ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/number_integer_t.md b/docs/mkdocs/docs/api/basic_json/number_integer_t.md index 6bd18a74b..e8983473e 100644 --- a/docs/mkdocs/docs/api/basic_json/number_integer_t.md +++ b/docs/mkdocs/docs/api/basic_json/number_integer_t.md @@ -80,10 +80,11 @@ Integer number values are stored directly inside a `basic_json` type. ## See also -- [number_unsigned_t](number_unsigned_t.md) the type used to store JSON unsigned integer numbers -- [number_float_t](number_float_t.md) the type used to store JSON floating-point numbers -- [is_number_integer](is_number_integer.md) checks whether the JSON value is a signed integer number +- [`number_unsigned_t`](number_unsigned_t.md) - the type used to store JSON unsigned integer numbers +- [`number_float_t`](number_float_t.md) - the type used to store JSON floating-point numbers +- [`is_number_integer`](is_number_integer.md) - checks whether the JSON value is a signed integer number - [Number Handling](../../features/types/number_handling.md) - the article on number handling +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the number template parameters ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md b/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md index cd8044bd3..232f9f95b 100644 --- a/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md +++ b/docs/mkdocs/docs/api/basic_json/number_unsigned_t.md @@ -82,10 +82,11 @@ Integer number values are stored directly inside a `basic_json` type. ## See also -- [number_integer_t](number_integer_t.md) the type used to store JSON integer numbers -- [number_float_t](number_float_t.md) the type used to store JSON floating-point numbers -- [is_number_unsigned](is_number_unsigned.md) checks whether the JSON value is an unsigned integer number +- [`number_integer_t`](number_integer_t.md) - the type used to store JSON integer numbers +- [`number_float_t`](number_float_t.md) - the type used to store JSON floating-point numbers +- [`is_number_unsigned`](is_number_unsigned.md) - checks whether the JSON value is an unsigned integer number - [Number Handling](../../features/types/number_handling.md) - the article on number handling +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the number template parameters ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/object_comparator_t.md b/docs/mkdocs/docs/api/basic_json/object_comparator_t.md index 7f2982703..0ff780d7d 100644 --- a/docs/mkdocs/docs/api/basic_json/object_comparator_t.md +++ b/docs/mkdocs/docs/api/basic_json/object_comparator_t.md @@ -27,8 +27,10 @@ and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise. ## See also -- [object_t](object_t.md) the type used to store JSON objects -- [default_object_comparator_t](default_object_comparator_t.md) the fallback comparator used when `object_t` has no `key_compare` member type +- [`object_t`](object_t.md) - the type used to store JSON objects +- [`default_object_comparator_t`](default_object_comparator_t.md) - the fallback comparator used when `object_t` has no `key_compare` member type +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ObjectType` template parameter +- [Object order](../../features/object_order.md) - preserve the insertion order of keys ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/object_t.md b/docs/mkdocs/docs/api/basic_json/object_t.md index 66fa9c110..835d7b185 100644 --- a/docs/mkdocs/docs/api/basic_json/object_t.md +++ b/docs/mkdocs/docs/api/basic_json/object_t.md @@ -20,7 +20,7 @@ To store objects in C++, a type is defined by the template parameters described `ObjectType` : the container to store objects. Its template parameters must have the same order and meaning as those of `std::map`; in particular, the third parameter is a comparator. `#!cpp std::unordered_map`, whose third parameter - is a hash function, therefore needs an adapter -- see + is a hash function, therefore needs an adapter — see [Template Parameter Requirements](../../features/types/template_parameters.md#objecttype) for the full list of requirements, an adapter example, and the containers that are known to work. @@ -125,10 +125,12 @@ the object is silently converted as an array of key-value pairs, which is incorr ## See also -- [array_t](array_t.md) the type used to store JSON arrays -- [string_t](string_t.md) the type used to store JSON strings -- [object_comparator_t](object_comparator_t.md) the comparator used to order object keys +- [`array_t`](array_t.md) - the type used to store JSON arrays +- [`string_t`](string_t.md) - the type used to store JSON strings +- [`object_comparator_t`](object_comparator_t.md) - the comparator used to order object keys - [Object Order](../../features/object_order.md) - the article on object key ordering +- [Types](../../features/types/index.md) - how objects are stored +- [Template Parameter Requirements](../../features/types/template_parameters.md) - requirements on the `ObjectType` template parameter ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/operator+=.md b/docs/mkdocs/docs/api/basic_json/operator+=.md index 3aee3f22d..73dc0e260 100644 --- a/docs/mkdocs/docs/api/basic_json/operator+=.md +++ b/docs/mkdocs/docs/api/basic_json/operator+=.md @@ -123,8 +123,9 @@ interpreted as `object_t::value_type` or `std::initializer_listClass hierarchy of the library's exceptions; arrows point from a derived class to its +base class, and the highlighted box is `basic_json::other_error`.
+ ## Member functions - **what** - returns explanatory string @@ -66,12 +69,14 @@ classDiagram ## See also -- [`exception`](exception.md) for the base class of all exceptions thrown by the library -- [List of other errors](../../home/exceptions.md#further-exceptions) -- [`parse_error`](parse_error.md) for exceptions indicating a parse error -- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators -- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type -- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range +- [`exception`](exception.md) - the base class of all exceptions thrown by the library +- [List of other errors](../../home/exceptions.md#further-exceptions) - overview of further errors (`other_error`) +- [`parse_error`](parse_error.md) - exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) - exceptions indicating errors with iterators +- [`type_error`](type_error.md) - exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) - exceptions indicating access out of the defined range +- [Exceptions](../../home/exceptions.md) - all exceptions and their error codes +- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/out_of_range.md b/docs/mkdocs/docs/api/basic_json/out_of_range.md index be579b35d..8e489f3cd 100644 --- a/docs/mkdocs/docs/api/basic_json/out_of_range.md +++ b/docs/mkdocs/docs/api/basic_json/out_of_range.md @@ -41,6 +41,9 @@ classDiagram style json_out_of_range fill:#CCCCFF ``` +Class hierarchy of the library's exceptions; arrows point from a derived class to its +base class, and the highlighted box is `basic_json::out_of_range`.
+ ## Member functions - **what** - returns explanatory string @@ -67,12 +70,15 @@ classDiagram ## See also -- [`exception`](exception.md) for the base class of all exceptions thrown by the library -- [List of out-of-range errors](../../home/exceptions.md#out-of-range) -- [`parse_error`](parse_error.md) for exceptions indicating a parse error -- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators -- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type -- [`other_error`](other_error.md) for exceptions indicating other library errors +- [`exception`](exception.md) - the base class of all exceptions thrown by the library +- [List of out-of-range errors](../../home/exceptions.md#out-of-range) - overview of out-of-range errors + (`out_of_range`) +- [`parse_error`](parse_error.md) - exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) - exceptions indicating errors with iterators +- [`type_error`](type_error.md) - exceptions indicating executing a member function with a wrong type +- [`other_error`](other_error.md) - exceptions indicating other library errors +- [Exceptions](../../home/exceptions.md) - all exceptions and their error codes +- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/parse.md b/docs/mkdocs/docs/api/basic_json/parse.md index a069f2086..cf7a29d95 100644 --- a/docs/mkdocs/docs/api/basic_json/parse.md +++ b/docs/mkdocs/docs/api/basic_json/parse.md @@ -282,15 +282,21 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by ## See also -- [accept](accept.md) - check if the input is valid JSON -- [sax_parse](sax_parse.md) - parse input using the SAX interface -- [operator>>](../operator_gtgt.md) - deserialize from stream +- [`accept`](accept.md) - check if the input is valid JSON +- [`sax_parse`](sax_parse.md) - parse input using the SAX interface +- [`operator>>`](../operator_gtgt.md) - deserialize from stream - [`JSON_STRICT_NUL_HANDLING`](../macros/json_strict_nul_handling.md) - opt in to rejecting a NUL byte in the input instead of treating it as end of input - [`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md) - read a `std::istream` one character at a time - [`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) - read a `FILE*` with the locking stdio functions +- [Parsing](../../features/parsing/index.md) - overview of the parsing functions +- [Comments](../../features/comments.md) - ignore `//` and `/* */` comments while parsing +- [Trailing Commas](../../features/trailing_commas.md) - accept trailing commas in arrays and objects +- [Parser Callbacks](../../features/parsing/parser_callbacks.md) - filter or inspect values while parsing +- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input +- [Parsing Untrusted Input](../../features/parsing/untrusted_input.md) - limits and checks for input you do not control ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/parse_error.md b/docs/mkdocs/docs/api/basic_json/parse_error.md index 0daae8de2..e9b8b1980 100644 --- a/docs/mkdocs/docs/api/basic_json/parse_error.md +++ b/docs/mkdocs/docs/api/basic_json/parse_error.md @@ -43,6 +43,9 @@ classDiagram style json_parse_error fill:#CCCCFF ``` +Class hierarchy of the library's exceptions; arrows point from a derived class to its +base class, and the highlighted box is `basic_json::parse_error`.
+ ## Member functions - **what** - returns explanatory string @@ -75,12 +78,14 @@ or the end of file. This also holds true when reading a byte vector for binary f ## See also -- [`exception`](exception.md) for the base class of all exceptions thrown by the library -- [List of parse errors](../../home/exceptions.md#parse-errors) -- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators -- [`type_error`](type_error.md) for exceptions indicating executing a member function with a wrong type -- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range -- [`other_error`](other_error.md) for exceptions indicating other library errors +- [`exception`](exception.md) - the base class of all exceptions thrown by the library +- [List of parse errors](../../home/exceptions.md#parse-errors) - overview of parse errors (`parse_error`) +- [`invalid_iterator`](invalid_iterator.md) - exceptions indicating errors with iterators +- [`type_error`](type_error.md) - exceptions indicating executing a member function with a wrong type +- [`out_of_range`](out_of_range.md) - exceptions indicating access out of the defined range +- [`other_error`](other_error.md) - exceptions indicating other library errors +- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input +- [Working Without Exceptions](../../features/no_exceptions.md) - error handling when exceptions are disabled ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/parse_event_t.md b/docs/mkdocs/docs/api/basic_json/parse_event_t.md index f8c12eff8..44c372a89 100644 --- a/docs/mkdocs/docs/api/basic_json/parse_event_t.md +++ b/docs/mkdocs/docs/api/basic_json/parse_event_t.md @@ -22,7 +22,12 @@ The parser callback distinguishes the following events: ## Examples - +Each coloured dot marks where the parser reports a `parse_event_t` event while reading +the JSON text on the left; the legend on the right names the event per colour.
??? example @@ -41,8 +46,9 @@ The parser callback distinguishes the following events: ## See also -- [parser_callback_t](parser_callback_t.md) callback function type for the parser -- [parse](parse.md) deserialize from a compatible input +- [`parser_callback_t`](parser_callback_t.md) - callback function type for the parser +- [`parse`](parse.md) - deserialize from a compatible input +- [Parser Callbacks](../../features/parsing/parser_callbacks.md) - filter or inspect values while parsing ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/parser_callback_t.md b/docs/mkdocs/docs/api/basic_json/parser_callback_t.md index 727905e5a..643610cb2 100644 --- a/docs/mkdocs/docs/api/basic_json/parser_callback_t.md +++ b/docs/mkdocs/docs/api/basic_json/parser_callback_t.md @@ -23,7 +23,12 @@ table describes the values of the parameters `depth`, `event`, and `parsed`. | `parse_event_t::array_end` | the parser read `]` and finished processing a JSON array | depth of the parent of the JSON array | the parsed JSON array | | `parse_event_t::value` | the parser finished reading a JSON value | depth of the value | the parsed JSON value | - +Parse events for a small JSON text: each coloured dot marks the position at which the +parser calls the callback, and the legend on the right names the event per colour.
Discarding a value (i.e., returning `#!cpp false`) has different effects depending on the context in which function was called: @@ -58,6 +63,15 @@ called: Whether the JSON value which called the function during parsing should be kept (`#!cpp true`) or not (`#!cpp false`). In the latter case, it is skipped completely, or replaced by `null` if it is the top-level value. +## Notes + +For a `parse_event_t::key` event, `parsed` holds the decoded object name, with the same guarantees as the `val` +parameter of [`json_sax::key`](../json_sax/key.md#notes): all escape sequences are decoded and `\uXXXX` escapes are +stored as UTF-8, so different spellings of the same name yield identical strings; the name is validated completely +before the callback is called, so a name with an invalid escape sequence or ill-formed UTF-8 causes a parse error and +no `key` event; no Unicode normalization or case conversion is applied; and a name that occurs several times in the +same object yields one `key` event per occurrence. + ## Examples ??? example "Example: skip an object key while parsing" @@ -92,8 +106,9 @@ the latter case, it is skipped completely, or replaced by `null` if it is the to ## See also -- [parse](parse.md) deserialize from a compatible input -- [parse_event_t](parse_event_t.md) enumeration of parser events +- [`parse`](parse.md) - deserialize from a compatible input +- [`parse_event_t`](parse_event_t.md) - enumeration of parser events +- [Parser Callbacks](../../features/parsing/parser_callbacks.md) - filter or inspect values while parsing ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/patch.md b/docs/mkdocs/docs/api/basic_json/patch.md index ed26135a9..cd553553e 100644 --- a/docs/mkdocs/docs/api/basic_json/patch.md +++ b/docs/mkdocs/docs/api/basic_json/patch.md @@ -40,7 +40,7 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example: `"array index '-' (3) is out of range"`. - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch - could not be resolved successfully in the current JSON value; example: `"key baz not found"`. + could not be resolved successfully in the current JSON value; example: `"key 'baz' not found"`. - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a reference token of a JSON pointer inside the patch cannot be resolved, e.g., `-` in a "remove" operation or `1a` for an array; example: `"unresolved reference token '-'"`. @@ -53,7 +53,10 @@ Strong guarantee: if an exception is thrown, there are no changes in the JSON va - Throws [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) if a "move" operation's "from" location is a proper prefix of its "path" location. - Throws [`other_error.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was - unsuccessful. + unsuccessful. A "test" operation whose "path" does not exist is unsuccessful, too: the failed lookup is reported as a + failed test, even if the operation has no "value" member (which would otherwise be + [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105)). Which of the two errors is reported for + this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it. ## Complexity @@ -65,6 +68,10 @@ the JSON value, the complexity can usually be neglected. The application of a patch is atomic: Either all operations succeed and the patched document is returned or an exception is thrown. In any case, the original value is not changed: the patch is applied to a copy of the value. +Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one +is kept, see [`object_t`](object_t.md#behavior)), so `#!json {"op": "add", "op": "remove", "path": "/a"}` is a +`remove` operation. + ## Examples ??? example "Example: apply a JSON patch" @@ -98,16 +105,19 @@ is thrown. In any case, the original value is not changed: the patch is applied ## See also -- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) -- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) -- [patch_inplace](patch_inplace.md) applies a JSON Patch without creating a copy of the document -- [merge_patch](merge_patch.md) applies a JSON Merge Patch +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - specification of JSON Patch +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) - specification of JSON Pointer +- [`patch_inplace`](patch_inplace.md) - applies a JSON Patch without creating a copy of the document +- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch +- [JSON Patch and Diff](../../features/json_patch.md) - the article on JSON Patch +- [JSON Pointer](../../features/json_pointer.md) - the addressing scheme used for patch paths ## Version history - Added in version 2.0.0. - Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0. + This includes a `null` parent, which was previously silently converted to an object, in version 3.13.0. - Added [`out_of_range.413`](../../home/exceptions.md#jsonexceptionout_of_range413) and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0. - Added [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper diff --git a/docs/mkdocs/docs/api/basic_json/patch_inplace.md b/docs/mkdocs/docs/api/basic_json/patch_inplace.md index 5b0d501bb..ff65e8dbd 100644 --- a/docs/mkdocs/docs/api/basic_json/patch_inplace.md +++ b/docs/mkdocs/docs/api/basic_json/patch_inplace.md @@ -36,7 +36,7 @@ No guarantees, value may be corrupted by an unsuccessful patch operation. where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example: `"array index '-' (3) is out of range"`. - Throws [`out_of_range.403`](../../home/exceptions.md#jsonexceptionout_of_range403) if a JSON pointer inside the patch - could not be resolved successfully in the current JSON value; example: `"key baz not found"`. + could not be resolved successfully in the current JSON value; example: `"key 'baz' not found"`. - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a reference token of a JSON pointer inside the patch cannot be resolved, e.g., `-` in a "remove" operation or `1a` for an array; example: `"unresolved reference token '-'"`. @@ -49,7 +49,10 @@ No guarantees, value may be corrupted by an unsuccessful patch operation. - Throws [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) if a "move" operation's "from" location is a proper prefix of its "path" location. - Throws [`other_error.501`](../../home/exceptions.md#jsonexceptionother_error501) if "test" operation was - unsuccessful. + unsuccessful. A "test" operation whose "path" does not exist is unsuccessful, too: the failed lookup is reported as a + failed test, even if the operation has no "value" member (which would otherwise be + [`parse_error.105`](../../home/exceptions.md#jsonexceptionparse_error105)). Which of the two errors is reported for + this combination depends on the order in which the operands of a comparison are evaluated, so do not rely on it. ## Complexity @@ -62,6 +65,23 @@ Unlike [`patch`](patch.md), `patch_inplace` applies the operation "in place" and That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception. +Duplicate member names inside an operation object are resolved by the parser before the patch is applied (the last one +is kept, see [`object_t`](object_t.md#behavior)), so `#!json {"op": "add", "op": "remove", "path": "/a"}` is a +`remove` operation. + +The JSON patch may be the JSON value itself (`#!cpp j.patch_inplace(j)`): the operations are then read from a copy of +the patch made before the first operation is applied, so the result is the same as that of +`#!cpp j = j.patch(j)`, and the exception safety is the same as above. + +If [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) is enabled, the same holds for a JSON patch stored inside the +JSON value (e.g., `#!cpp j.patch_inplace(j["patch"])`): it is detected via the parent pointers. + +!!! danger "Undefined behavior" + + Without [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md), the JSON patch must not be a value stored inside the + JSON value (e.g., `#!cpp j.patch_inplace(j["patch"])`), as the operations may change or destroy it while it is + read. Pass a copy (`#!cpp j.patch_inplace(json(j["patch"]))`) or use [`patch`](patch.md) instead. + ## Examples ??? example "Example: apply a JSON patch in place" @@ -96,16 +116,18 @@ function throws an exception. ## See also -- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) -- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) -- [patch](patch.md) applies a JSON Patch -- [merge_patch](merge_patch.md) applies a JSON Merge Patch +- [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902) - specification of JSON Patch +- [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901) - specification of JSON Pointer +- [`patch`](patch.md) - applies a JSON Patch +- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch +- [JSON Patch and Diff](../../features/json_patch.md) - the article on JSON Patch ## Version history - Added in version 3.11.0. - Added [`out_of_range.411`](../../home/exceptions.md#jsonexceptionout_of_range411) and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0. + This includes a `null` parent, which was previously silently converted to an object, in version 3.13.0. - Added [`out_of_range.413`](../../home/exceptions.md#jsonexceptionout_of_range413) and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0. - Added [`out_of_range.414`](../../home/exceptions.md#jsonexceptionout_of_range414) and rejected a "move" operation whose "from" location is a proper @@ -113,3 +135,5 @@ function throws an exception. - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) instead of [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) for a one-character array index that is not a digit (e.g., `/x`) in version 3.13.0, as it already did for longer ones. +- Applying a JSON value as patch to itself (or, with `JSON_DIAGNOSTICS`, to a value stored inside it) no longer results + in undefined behavior in version 3.13.0. diff --git a/docs/mkdocs/docs/api/basic_json/push_back.md b/docs/mkdocs/docs/api/basic_json/push_back.md index f6ed6a426..4bc885277 100644 --- a/docs/mkdocs/docs/api/basic_json/push_back.md +++ b/docs/mkdocs/docs/api/basic_json/push_back.md @@ -119,8 +119,8 @@ throws. ## See also -- [emplace_back](emplace_back.md) add a value to an array -- [operator+=](operator+=.md) add a value to an array/object +- [`emplace_back`](emplace_back.md) - add a value to an array +- [`operator+=`](operator+=.md) - add a value to an array/object - [Modifying values](../../features/modifying_values.md) - the article on modifying values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/rbegin.md b/docs/mkdocs/docs/api/basic_json/rbegin.md index 544b8a643..ea3be945c 100644 --- a/docs/mkdocs/docs/api/basic_json/rbegin.md +++ b/docs/mkdocs/docs/api/basic_json/rbegin.md @@ -7,7 +7,13 @@ const_reverse_iterator rbegin() const noexcept; Returns an iterator to the reverse-beginning; that is, the last element. - +`rbegin()` points to the last element and `rend()` to the position before the first +element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse +iterator to the forward iterator it stores, and dashed cells are past-the-last positions.
## Return value @@ -39,9 +45,9 @@ Constant. ## See also -- [rend](rend.md) returns a reverse iterator to one before the first element -- [crbegin](crbegin.md) returns a const reverse iterator to the last element -- [begin](begin.md) returns an iterator to the first element +- [`rend`](rend.md) - returns a reverse iterator to one before the first element +- [`crbegin`](crbegin.md) - returns a const reverse iterator to the last element +- [`begin`](begin.md) - returns an iterator to the first element - [Iterators](../../features/iterators.md) - the article on iterators ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/rend.md b/docs/mkdocs/docs/api/basic_json/rend.md index 12f68e787..90026fa6c 100644 --- a/docs/mkdocs/docs/api/basic_json/rend.md +++ b/docs/mkdocs/docs/api/basic_json/rend.md @@ -8,7 +8,13 @@ const_reverse_iterator rend() const noexcept; Returns an iterator to the reverse-end; that is, one before the first element. This element acts as a placeholder, attempting to access it results in undefined behavior. - +`rend()` points to the position before the first element and `rbegin()` to the last +element. The upper row is the reversed sequence and the lower row the forward sequence; dashed arrows link each reverse +iterator to the forward iterator it stores, and dashed cells are past-the-last positions.
## Return value @@ -40,9 +46,9 @@ Constant. ## See also -- [rbegin](rbegin.md) returns a reverse iterator to the last element -- [crend](crend.md) returns a const reverse iterator to one before the first element -- [end](end.md) returns an iterator to one past the last element +- [`rbegin`](rbegin.md) - returns a reverse iterator to the last element +- [`crend`](crend.md) - returns a const reverse iterator to one before the first element +- [`end`](end.md) - returns an iterator to one past the last element - [Iterators](../../features/iterators.md) - the article on iterators ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/sax_parse.md b/docs/mkdocs/docs/api/basic_json/sax_parse.md index 60e41e1c7..c3aa92ffb 100644 --- a/docs/mkdocs/docs/api/basic_json/sax_parse.md +++ b/docs/mkdocs/docs/api/basic_json/sax_parse.md @@ -149,12 +149,14 @@ use the same file with stdio functions, but it must not wait for another thread ## See also -- [parse](parse.md) - deserialize from a compatible input -- [accept](accept.md) - check if the input is valid JSON +- [`parse`](parse.md) - deserialize from a compatible input +- [`accept`](accept.md) - check if the input is valid JSON - [`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md) - read a `std::istream` one character at a time - [`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) - read a `FILE*` with the locking stdio functions +- [SAX Interface](../../features/parsing/sax_interface.md) - guide to event-based parsing +- [Large, Streamed, and Partial Input](../../features/parsing/large_and_partial_input.md) - chunked, concatenated, and very large input ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/size.md b/docs/mkdocs/docs/api/basic_json/size.md index 8fe553bd3..5c70d11d0 100644 --- a/docs/mkdocs/docs/api/basic_json/size.md +++ b/docs/mkdocs/docs/api/basic_json/size.md @@ -32,7 +32,7 @@ constant complexity. ## Notes -This function does not return the length of a string stored as JSON value -- it returns the number of elements in the +This function does not return the length of a string stored as JSON value — it returns the number of elements in the JSON value which is `1` in the case of a string. ## Examples @@ -53,9 +53,9 @@ JSON value which is `1` in the case of a string. ## See also -- [empty](empty.md) checks whether the JSON value has no elements -- [max_size](max_size.md) returns the maximum possible number of elements -- [basic_json_view::size](../basic_json_view/size.md) - the same function on a zero-copy view +- [`empty`](empty.md) - checks whether the JSON value has no elements +- [`max_size`](max_size.md) - returns the maximum possible number of elements +- [`basic_json_view::size`](../basic_json_view/size.md) - the same function on a zero-copy view ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/start_pos.md b/docs/mkdocs/docs/api/basic_json/start_pos.md index 19a31df15..fb43fb52b 100644 --- a/docs/mkdocs/docs/api/basic_json/start_pos.md +++ b/docs/mkdocs/docs/api/basic_json/start_pos.md @@ -60,8 +60,9 @@ Constant. ## See also -- [end_pos](end_pos.md) to access the end position -- [JSON_DIAGNOSTIC_POSITIONS](../macros/json_diagnostic_positions.md) for an overview of the diagnostic positions +- [`end_pos`](end_pos.md) - to access the end position +- [`JSON_DIAGNOSTIC_POSITIONS`](../macros/json_diagnostic_positions.md) - overview of the supported conversions +- [Parsing and Exceptions](../../features/parsing/parse_exceptions.md) - handling parse errors and locating them in the input ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/std_formatter.md b/docs/mkdocs/docs/api/basic_json/std_formatter.md index e7e889aee..5afe221f0 100644 --- a/docs/mkdocs/docs/api/basic_json/std_formatter.md +++ b/docs/mkdocs/docs/api/basic_json/std_formatter.md @@ -47,9 +47,9 @@ provides `Class hierarchy of the library's exceptions; arrows point from a derived class to its +base class, and the highlighted box is `basic_json::type_error`.
+ ## Member functions - **what** - returns explanatory string @@ -67,12 +70,14 @@ classDiagram ## See also -- [`exception`](exception.md) for the base class of all exceptions thrown by the library -- [List of type errors](../../home/exceptions.md#type-errors) -- [`parse_error`](parse_error.md) for exceptions indicating a parse error -- [`invalid_iterator`](invalid_iterator.md) for exceptions indicating errors with iterators -- [`out_of_range`](out_of_range.md) for exceptions indicating access out of the defined range -- [`other_error`](other_error.md) for exceptions indicating other library errors +- [`exception`](exception.md) - the base class of all exceptions thrown by the library +- [List of type errors](../../home/exceptions.md#type-errors) - overview of type errors (`type_error`) +- [`parse_error`](parse_error.md) - exceptions indicating a parse error +- [`invalid_iterator`](invalid_iterator.md) - exceptions indicating errors with iterators +- [`out_of_range`](out_of_range.md) - exceptions indicating access out of the defined range +- [`other_error`](other_error.md) - exceptions indicating other library errors +- [Exceptions](../../home/exceptions.md) - all exceptions and their error codes +- [`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) - extended exception messages with the path of the failing value ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/type_name.md b/docs/mkdocs/docs/api/basic_json/type_name.md index d43ed4d71..7af96acfa 100644 --- a/docs/mkdocs/docs/api/basic_json/type_name.md +++ b/docs/mkdocs/docs/api/basic_json/type_name.md @@ -4,7 +4,7 @@ const char* type_name() const noexcept; ``` -Returns the type name as string to be used in error messages -- usually to indicate that a function was called on a +Returns the type name as string to be used in error messages — usually to indicate that a function was called on a wrong JSON type. ## Return value @@ -54,9 +54,10 @@ Constant. ## See also -- [type](type.md) returns the type of the JSON value -- [value_t](value_t.md) the enumeration of JSON types -- [basic_json_view::type_name](../basic_json_view/type_name.md) - the same function on a zero-copy view +- [`type`](type.md) - returns the type of the JSON value +- [`value_t`](value_t.md) - the enumeration of JSON types +- [`basic_json_view::type_name`](../basic_json_view/type_name.md) - the same function on a zero-copy view +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/unflatten.md b/docs/mkdocs/docs/api/basic_json/unflatten.md index 661ffa3e8..8b9f2cbc1 100644 --- a/docs/mkdocs/docs/api/basic_json/unflatten.md +++ b/docs/mkdocs/docs/api/basic_json/unflatten.md @@ -36,9 +36,9 @@ The function can throw the following exceptions: - Throws [`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) if an array index in a key is not a number; example: `"array index 'one' is not a number"` - Throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404) if a level becomes an array - (because one of its keys is `0`) and another key at that level begins with a digit but is not a valid array index - (such as `1a`), or is `-`; example: - `"unresolved reference token '-'"` + (because one of its keys is `0`) and another key at that level is empty (as in `/a/`), is `-`, or begins with a digit + but is not a valid array index (such as `1a`); examples: `"unresolved reference token '-'"`, + `"unresolved reference token ''"` ## Complexity @@ -46,7 +46,7 @@ Linear in the size of the JSON value. ## Notes -Empty objects and arrays are flattened by [`flatten()`](flatten.md) to `#!json null` values and cannot unflattened to +Empty objects and arrays are flattened by [`flatten()`](flatten.md) to `#!json null` values and cannot be unflattened to their original type. A flattened array and a flattened object whose keys are array indices are indistinguishable, because both are @@ -54,7 +54,12 @@ described by the same JSON pointers. A value is therefore restored as an array i reference token `0`, and as an object otherwise: `#!json {"2": 1}` is restored unchanged, whereas `#!json {"0": 1}` is restored as `#!json [1]`. This decision does not depend on the order in which the flattened object is iterated. -Apart from these two cases, for a JSON value `j`, the following is always true: +A third case is an object that has the key `0` next to a key that is not a valid array index: `#!json {"0": 1, "b": 2}` +is flattened to `#!json {"/0": 1, "/b": 2}`, and unflatten treats the level as an array and throws +[`parse_error.109`](../../home/exceptions.md#jsonexceptionparse_error109) because `b` is not a number. (For the keys +`-`, `1a`, or the empty key instead of `b`, it throws [`out_of_range.404`](../../home/exceptions.md#jsonexceptionout_of_range404).) + +Apart from these three cases, for a JSON value `j`, the following is always true: `#!cpp j == j.flatten().unflatten()`. ## Examples @@ -75,7 +80,8 @@ Apart from these two cases, for a JSON value `j`, the following is always true: ## See also -- [flatten](flatten.md) the reverse function +- [`flatten`](flatten.md) - the reverse function +- [JSON Pointer](../../features/json_pointer.md#flatten-unflatten) - the article on JSON Pointer and flattening ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/update.md b/docs/mkdocs/docs/api/basic_json/update.md index d641b38d5..698c68399 100644 --- a/docs/mkdocs/docs/api/basic_json/update.md +++ b/docs/mkdocs/docs/api/basic_json/update.md @@ -153,8 +153,8 @@ contained in `#!cpp *this` (for example, a subobject returned by `#!cpp (*this)[ ## See also -- [insert](insert.md) add values to an array/object -- [merge_patch](merge_patch.md) applies a JSON Merge Patch +- [`insert`](insert.md) - add values to an array/object +- [`merge_patch`](merge_patch.md) - applies a JSON Merge Patch - [Modifying values](../../features/modifying_values.md) - the article on modifying values ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/value.md b/docs/mkdocs/docs/api/basic_json/value.md index aee09a537..1f0bb2a97 100644 --- a/docs/mkdocs/docs/api/basic_json/value.md +++ b/docs/mkdocs/docs/api/basic_json/value.md @@ -45,6 +45,9 @@ This is equivalent to Python's `dict.get(key, default)`. return default_value; } ``` + with one exception: if the JSON value is neither an array nor an object, the function throws + [`type_error.306`](../../home/exceptions.md#jsonexceptiontype_error306) before looking at `ptr`, even for the empty + pointer, whereas `at` returns the value itself for the empty pointer. !!! note "Differences to `at` and `operator[]`" @@ -222,9 +225,11 @@ changes to any JSON value. ## See also -- see [`at`](at.md) for access by reference with range checking -- see [`operator[]`](operator%5B%5D.md) for unchecked access by reference -- [basic_json_view::value](../basic_json_view/value.md) - the same access on a zero-copy view +- [`at`](at.md) - access by reference with range checking +- [`operator[]`](operator%5B%5D.md) - unchecked access by reference +- [`basic_json_view::value`](../basic_json_view/value.md) - the same access on a zero-copy view +- [Access with default value: value](../../features/element_access/default_value.md) - the article on `value` +- [JSON Pointer](../../features/json_pointer.md) - access nested values with a pointer ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/value_t.md b/docs/mkdocs/docs/api/basic_json/value_t.md index 0d63bfdac..e38a27370 100644 --- a/docs/mkdocs/docs/api/basic_json/value_t.md +++ b/docs/mkdocs/docs/api/basic_json/value_t.md @@ -48,6 +48,9 @@ functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_ F --> G[binary] ``` +Arrows point from a type to the next greater type in the ordering used by + `operator<`.
+ !!! note "Types of numbers" There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish @@ -86,11 +89,12 @@ functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_ ## See also -- [type](type.md) return the type of the JSON value -- [type_name](type_name.md) return the type as string -- [operator value_t](operator_value_t.md) return the type of the JSON value -- [is_primitive](is_primitive.md) return whether the type is primitive -- [is_structured](is_structured.md) return whether the type is structured +- [`type`](type.md) - return the type of the JSON value +- [`type_name`](type_name.md) - return the type as string +- [`operator value_t`](operator_value_t.md) - return the type of the JSON value +- [`is_primitive`](is_primitive.md) - return whether the type is primitive +- [`is_structured`](is_structured.md) - return whether the type is structured +- [Types](../../features/types/index.md) - the JSON value types and how they are stored ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/with_t.md b/docs/mkdocs/docs/api/basic_json/with_t.md index 2e8fee663..f98b071d3 100644 --- a/docs/mkdocs/docs/api/basic_json/with_t.md +++ b/docs/mkdocs/docs/api/basic_json/with_t.md @@ -128,8 +128,9 @@ matter. For instance, `nlohmann::json::with_object_tBoxes are the reference tokens in order; dotted arrows show which token each member +function reads, removes, or adds to.
+ The diagram shows the reference tokens of the JSON pointer `/a/b/c`. ## Member types @@ -46,7 +49,7 @@ The diagram shows the reference tokens of the JSON pointer `/a/b/c`. - [(constructor)](json_pointer.md) - [**to_string**](to_string.md) - return a string representation of the JSON pointer -- [**operator string_t**](operator_string_t.md) - return a string representation of the JSON pointer (deprecated) +- [`operator string_t`](operator_string_t.md) - return a string representation of the JSON pointer (deprecated) - [**operator==**](operator_eq.md) - compare: equal - [**operator!=**](operator_ne.md) - compare: not equal - [**operator<=>**](operator_spaceship.md) - compare: 3-way (C++20) @@ -67,7 +70,9 @@ The diagram shows the reference tokens of the JSON pointer `/a/b/c`. ## See also -- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901) +- [RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901) - specification of JSON Pointer +- [JSON Pointer](../../features/json_pointer.md) - the article on JSON Pointer support +- [JSON Patch and Diff](../../features/json_patch.md) - patch paths are JSON pointers ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/json_pointer.md b/docs/mkdocs/docs/api/json_pointer/json_pointer.md index 0fce6f43c..d667da15d 100644 --- a/docs/mkdocs/docs/api/json_pointer/json_pointer.md +++ b/docs/mkdocs/docs/api/json_pointer/json_pointer.md @@ -46,7 +46,7 @@ Linear in the length of `s`. ## See also - [JSON Pointer](../../features/json_pointer.md) - the article on JSON Pointer support -- [operator""_json_pointer](../operator_literal_json_pointer.md) user-defined string literal for JSON pointers +- [`operator""_json_pointer`](../operator_literal_json_pointer.md) - user-defined string literal for JSON pointers ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/operator_eq.md b/docs/mkdocs/docs/api/json_pointer/operator_eq.md index 44cda4354..d7e45c773 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_eq.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_eq.md @@ -109,8 +109,8 @@ tokens. ## See also -- [operator!=](operator_ne.md) compare for inequality -- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20) +- [`operator!=`](operator_ne.md) - compare for inequality +- [`operator<=>`](operator_spaceship.md) - comparison: 3-way (C++20) ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/operator_ne.md b/docs/mkdocs/docs/api/json_pointer/operator_ne.md index 77e6b92c8..827c58e3e 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_ne.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_ne.md @@ -107,8 +107,8 @@ tokens. ## See also -- [operator==](operator_eq.md) compare for equality -- [operator<=>](operator_spaceship.md) comparison: 3-way (C++20) +- [`operator==`](operator_eq.md) - compare for equality +- [`operator<=>`](operator_spaceship.md) - comparison: 3-way (C++20) ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/operator_slash.md b/docs/mkdocs/docs/api/json_pointer/operator_slash.md index e91f8a119..ae01dd599 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_slash.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_slash.md @@ -64,8 +64,9 @@ a new JSON pointer is built from a copy of `lhs`. ## See also -- [operator/=](operator_slasheq.md) append to the end of the JSON pointer -- [push_back](push_back.md) append an unescaped token at the end of the pointer +- [`operator/=`](operator_slasheq.md) - append to the end of the JSON pointer +- [`push_back`](push_back.md) - append an unescaped token at the end of the pointer +- [JSON Pointer](../../features/json_pointer.md) - the article on JSON Pointer support ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md b/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md index 05e8ccbcf..2f2820d4f 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_slasheq.md @@ -18,7 +18,8 @@ json_pointer& operator/=(std::size_t array_idx) ## Parameters `ptr` (in) -: JSON pointer to append +: JSON pointer to append; may be the JSON pointer itself (`#!cpp p /= p`), which then appends a copy of its + reference tokens `token` (in) : reference token to append @@ -63,11 +64,13 @@ json_pointer& operator/=(std::size_t array_idx) ## See also -- [operator/](operator_slash.md) create JSON Pointer by appending -- [push_back](push_back.md) append an unescaped token at the end of the pointer +- [`operator/`](operator_slash.md) - create JSON Pointer by appending +- [`push_back`](push_back.md) - append an unescaped token at the end of the pointer +- [JSON Pointer](../../features/json_pointer.md) - the article on JSON Pointer support ## Version history -1. Added in version 3.6.0. +1. Added in version 3.6.0. Appending a JSON pointer to itself no longer results in undefined behavior in version + 3.13.0. 2. Added in version 3.6.0. Changed type of `token` to `string_t` in version 3.11.0. 3. Added in version 3.6.0. diff --git a/docs/mkdocs/docs/api/json_pointer/operator_spaceship.md b/docs/mkdocs/docs/api/json_pointer/operator_spaceship.md index ffc3f0e93..1c97ce569 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_spaceship.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_spaceship.md @@ -64,8 +64,8 @@ Linear in the number of reference tokens. ## See also -- [operator==](operator_eq.md) compare: equal -- [operator!=](operator_ne.md) compare: not equal +- [`operator==`](operator_eq.md) - compare: equal +- [`operator!=`](operator_ne.md) - compare: not equal ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/operator_string_t.md b/docs/mkdocs/docs/api/json_pointer/operator_string_t.md index 44dde733d..4818f7c5c 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_string_t.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_string_t.md @@ -46,8 +46,8 @@ operator string_t() const ## See also -- [to_string](to_string.md) return a string representation of the JSON pointer -- [string_t](../basic_json/string_t.md) - type for strings +- [`to_string`](to_string.md) - return a string representation of the JSON pointer +- [`string_t`](../basic_json/string_t.md) - type for strings ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/parent_pointer.md b/docs/mkdocs/docs/api/json_pointer/parent_pointer.md index d37889e7e..1cb26c920 100644 --- a/docs/mkdocs/docs/api/json_pointer/parent_pointer.md +++ b/docs/mkdocs/docs/api/json_pointer/parent_pointer.md @@ -12,7 +12,8 @@ Parent of this JSON pointer; in case this JSON pointer is the root, the root its ## Exception safety -No-throw guarantee: this function never throws exceptions. +Strong exception safety: if an exception occurs, the original value stays intact. The function is not `#!cpp noexcept` +and allocates a new JSON pointer, so it can throw `#!cpp std::bad_alloc`; it throws no library exceptions. ## Complexity @@ -36,8 +37,8 @@ Linear in the length of the JSON pointer. ## See also -- [pop_back](pop_back.md) remove the last reference token -- [back](back.md) return the last reference token +- [`pop_back`](pop_back.md) - remove the last reference token +- [`back`](back.md) - return the last reference token ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/pop_back.md b/docs/mkdocs/docs/api/json_pointer/pop_back.md index 6646be44a..07e1f33ce 100644 --- a/docs/mkdocs/docs/api/json_pointer/pop_back.md +++ b/docs/mkdocs/docs/api/json_pointer/pop_back.md @@ -36,9 +36,9 @@ Constant. ## See also -- [back](back.md) return last reference token -- [push_back](push_back.md) append an unescaped token at the end of the pointer -- [parent_pointer](parent_pointer.md) returns the parent of this JSON pointer +- [`back`](back.md) - return last reference token +- [`push_back`](push_back.md) - append an unescaped token at the end of the pointer +- [`parent_pointer`](parent_pointer.md) - returns the parent of this JSON pointer ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/pop_front.md b/docs/mkdocs/docs/api/json_pointer/pop_front.md index 308a3cbdc..ec3d984ec 100644 --- a/docs/mkdocs/docs/api/json_pointer/pop_front.md +++ b/docs/mkdocs/docs/api/json_pointer/pop_front.md @@ -36,8 +36,8 @@ Linear in the number of reference tokens in the `json_pointer`. ## See also -- [front](front.md) return first reference token -- [push_front](push_front.md) append an unescaped token at the start of the pointer +- [`front`](front.md) - return first reference token +- [`push_front`](push_front.md) - append an unescaped token at the start of the pointer ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/push_back.md b/docs/mkdocs/docs/api/json_pointer/push_back.md index f50f10924..c2c950027 100644 --- a/docs/mkdocs/docs/api/json_pointer/push_back.md +++ b/docs/mkdocs/docs/api/json_pointer/push_back.md @@ -39,10 +39,10 @@ Amortized constant. ## See also -- [back](back.md) return last reference token -- [pop_back](pop_back.md) remove the last reference token -- [operator/=](operator_slasheq.md) append to the end of the JSON pointer -- [operator/](operator_slash.md) create JSON Pointer by appending +- [`back`](back.md) - return last reference token +- [`pop_back`](pop_back.md) - remove the last reference token +- [`operator/=`](operator_slasheq.md) - append to the end of the JSON pointer +- [`operator/`](operator_slash.md) - create JSON Pointer by appending ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/push_front.md b/docs/mkdocs/docs/api/json_pointer/push_front.md index 67dd87384..e68516f1c 100644 --- a/docs/mkdocs/docs/api/json_pointer/push_front.md +++ b/docs/mkdocs/docs/api/json_pointer/push_front.md @@ -40,8 +40,8 @@ Linear in the number of reference tokens in the `json_pointer`. ## See also -- [front](front.md) return first reference token -- [pop_front](pop_front.md) remove the first reference token +- [`front`](front.md) - return first reference token +- [`pop_front`](pop_front.md) - remove the first reference token ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/string_t.md b/docs/mkdocs/docs/api/json_pointer/string_t.md index 6808ae540..468c8446a 100644 --- a/docs/mkdocs/docs/api/json_pointer/string_t.md +++ b/docs/mkdocs/docs/api/json_pointer/string_t.md @@ -25,8 +25,8 @@ See [`basic_json::string_t`](../basic_json/string_t.md) for more information. ## See also -- [basic_json::string_t](../basic_json/string_t.md) type used to store JSON strings -- [to_string](to_string.md) return a string representation of the JSON pointer +- [`basic_json::string_t`](../basic_json/string_t.md) - type used to store JSON strings +- [`to_string`](to_string.md) - return a string representation of the JSON pointer ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/to_string.md b/docs/mkdocs/docs/api/json_pointer/to_string.md index b994ff80e..2a3f7f2db 100644 --- a/docs/mkdocs/docs/api/json_pointer/to_string.md +++ b/docs/mkdocs/docs/api/json_pointer/to_string.md @@ -44,8 +44,8 @@ ptr == json_pointer(ptr.to_string()); ## See also -- [operator string_t](operator_string_t.md) return a string representation of the JSON pointer (deprecated) -- [operator<<](../operator_ltlt.md) write a JSON pointer to a stream +- [`operator string_t`](operator_string_t.md) - return a string representation of the JSON pointer (deprecated) +- [`operator<<`](../operator_ltlt.md) - write a JSON pointer to a stream ## Version history diff --git a/docs/mkdocs/docs/api/json_sax/binary.md b/docs/mkdocs/docs/api/json_sax/binary.md index f5310390e..617fd76fc 100644 --- a/docs/mkdocs/docs/api/json_sax/binary.md +++ b/docs/mkdocs/docs/api/json_sax/binary.md @@ -37,7 +37,7 @@ It is safe to move the passed binary value. ## See also -- [sax_parse](../basic_json/sax_parse.md) - SAX parser +- [`sax_parse`](../basic_json/sax_parse.md) - SAX parser - [SAX Interface](../../features/parsing/sax_interface.md) - the SAX interface article - [Binary Values](../../features/binary_values.md) - the article on binary values diff --git a/docs/mkdocs/docs/api/json_sax/boolean.md b/docs/mkdocs/docs/api/json_sax/boolean.md index 89abb67ba..abac5dd38 100644 --- a/docs/mkdocs/docs/api/json_sax/boolean.md +++ b/docs/mkdocs/docs/api/json_sax/boolean.md @@ -33,7 +33,7 @@ Whether parsing should proceed. ## See also -- [sax_parse](../basic_json/sax_parse.md) - SAX parser +- [`sax_parse`](../basic_json/sax_parse.md) - SAX parser - [SAX Interface](../../features/parsing/sax_interface.md) - the SAX interface article ## Version history diff --git a/docs/mkdocs/docs/api/json_sax/end_array.md b/docs/mkdocs/docs/api/json_sax/end_array.md index 7010e7259..599f951e5 100644 --- a/docs/mkdocs/docs/api/json_sax/end_array.md +++ b/docs/mkdocs/docs/api/json_sax/end_array.md @@ -28,8 +28,9 @@ Whether parsing should proceed. ## See also -- [start_array](start_array.md) - the beginning of an array was read -- [sax_parse](../basic_json/sax_parse.md) - SAX parser +- [`start_array`](start_array.md) - the beginning of an array was read +- [`sax_parse`](../basic_json/sax_parse.md) - SAX parser +- [SAX Interface](../../features/parsing/sax_interface.md) - guide to event-based parsing ## Version history diff --git a/docs/mkdocs/docs/api/json_sax/end_object.md b/docs/mkdocs/docs/api/json_sax/end_object.md index aaaec6d22..b5f020dc7 100644 --- a/docs/mkdocs/docs/api/json_sax/end_object.md +++ b/docs/mkdocs/docs/api/json_sax/end_object.md @@ -28,9 +28,10 @@ Whether parsing should proceed. ## See also -- [start_object](start_object.md) - the beginning of an object was read -- [key](key.md) - an object key was read -- [sax_parse](../basic_json/sax_parse.md) - SAX parser +- [`start_object`](start_object.md) - the beginning of an object was read +- [`key`](key.md) - an object key was read +- [`sax_parse`](../basic_json/sax_parse.md) - SAX parser +- [SAX Interface](../../features/parsing/sax_interface.md) - guide to event-based parsing ## Version history diff --git a/docs/mkdocs/docs/api/json_sax/index.md b/docs/mkdocs/docs/api/json_sax/index.md index 084503d92..f3c732ce9 100644 --- a/docs/mkdocs/docs/api/json_sax/index.md +++ b/docs/mkdocs/docs/api/json_sax/index.md @@ -26,6 +26,9 @@ sequenceDiagram P->>H: end_object() ``` +Each arrow is one call from the parser to the SAX handler, from top to bottom in the +order the calls happen.
+ Note `elements` is passed as `#!cpp std::numeric_limitsThe trust boundary: untrusted input enters on the left through the parser, the SAX interface, or the binary readers, and only a value tree reaches the trusted caller on the right.
+ ## Secure design - **Strict parsing.** The parser accepts exactly the JSON grammar of [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259). diff --git a/docs/mkdocs/docs/community/quality_assurance.md b/docs/mkdocs/docs/community/quality_assurance.md index 6c8046964..61ffdff85 100644 --- a/docs/mkdocs/docs/community/quality_assurance.md +++ b/docs/mkdocs/docs/community/quality_assurance.md @@ -4,6 +4,15 @@ Ensuring quality is paramount for this project, particularly because [numerous o depend on it. Each commit to the library undergoes rigorous checks against the following requirements, and any violations will result in a failed build. +The overview shows the checks a change passes on its way from a push or pull request to a release; the sections below +describe each of them. + +The checks grouped by the stage at which they run, from push or pull request through the merge into develop to a release. The badge on each card says whether the check runs on every push or PR, on a schedule, or continuously.
+ ## C++ language compliance and compiler compatibility !!! success "Requirement: Compiler support" diff --git a/docs/mkdocs/docs/community/roadmap.md b/docs/mkdocs/docs/community/roadmap.md index d294bd5f7..343846466 100644 --- a/docs/mkdocs/docs/community/roadmap.md +++ b/docs/mkdocs/docs/community/roadmap.md @@ -91,6 +91,14 @@ Version 4.0 is therefore the sum of these macros: you can try it on the 3.x rele to its 4.0 value and fixing what no longer compiles or behaves differently. Once your code works with all of them, it is ready for version 4.0. +Each macro has a default value in 3.x and a different value in version 4.0. Define the macro to the 4.0 value to try it on the 3.x release train today; version 4.0 makes that value the default: + +Each row is one macro: the 3.x release that added it, its default in 3.x, and its value in version 4.0 (highlighted) or "removed". Versions on the 3.x lane are not to scale.
+ The following macros guard changes that are planned to become the default in version 4.0: | Macro | 3.x default | 4.0 behavior | CMake option | Added | @@ -105,6 +113,8 @@ The following macros guard changes that are planned to become the default in ver | [`JSON_DISABLE_TUPLE_REFERENCE_CONVERSION`](../api/macros/json_disable_tuple_reference_conversion.md) | `0` | `1`: a `basic_json` value can no longer be created from a one-element tuple of a reference to it, such as `std::forward_as_tuple(j)`| [`JSON_DisableTupleReferenceConversion`](../integration/cmake.md#json_disabletuplereferenceconversion) | 3.13.0 | | [`JSON_DELETE_DEPRECATED_FUNCTIONS`](../api/macros/json_delete_deprecated_functions.md) | `0` | removed: the deprecated functions are removed (see below); the `from_*(ptr, len)` overloads stay deleted | [`JSON_DeleteDeprecatedFunctions`](../integration/cmake.md#json_deletedeprecatedfunctions) | 3.13.0 | +Opt-in macros for the version 4.0 behavior. "3.x default" is the value the library uses when the macro is not defined, "Added" is the release that introduced the macro, and – means there is no CMake option.
+ For example, the following makes a 3.x release behave like version 4.0 with respect to these changes: ```cpp @@ -146,6 +156,8 @@ to the `strict` parameter. | Comparing a [`json_pointer`](../api/json_pointer/index.md) with a string via [`operator==`](../api/json_pointer/operator_eq.md) or [`operator!=`](../api/json_pointer/operator_ne.md) | 3.11.2 | [JSON Pointers](../integration/migration_guide.md#json-pointers) | | [`from_bjdata`](../api/basic_json/from_bjdata.md) and [`from_bon8`](../api/basic_json/from_bon8.md) with `(ptr, len)` | 3.13.0 | [Parsing](../integration/migration_guide.md#parsing) | +Deprecated functions, with the release that deprecated each one and the section of the migration guide that shows its replacement.
+ The deprecated legacy comparison of discarded values is controlled by a macro and therefore listed in the table above. New breaking changes will follow the same path: they are added to these tables when they land in a 3.x release. diff --git a/docs/mkdocs/docs/css/brand.css b/docs/mkdocs/docs/css/brand.css new file mode 100644 index 000000000..8f181f78b --- /dev/null +++ b/docs/mkdocs/docs/css/brand.css @@ -0,0 +1,803 @@ +/* nlohmann/json brand for Material for MkDocs (values from brand/kit/tokens.css) */ + +@font-face { + font-family: "Inter"; + src: url("fonts/Inter.woff2") format("woff2"); + font-weight: 100 900; + font-display: swap; +} +@font-face { + font-family: "Inter"; + src: url("fonts/Inter-Italic.woff2") format("woff2"); + font-style: italic; + font-weight: 100 900; + font-display: swap; +} +@font-face { + font-family: "JetBrains Mono"; + src: url("fonts/JetBrainsMono.woff2") format("woff2"); + font-weight: 100 800; + font-display: swap; +} +@font-face { + font-family: "JetBrains Mono"; + src: url("fonts/JetBrainsMono-Italic.woff2") format("woff2"); + font-style: italic; + font-weight: 400; + font-display: swap; +} + +:root { + --md-text-font: "Inter"; + --md-code-font: "JetBrains Mono"; +} + +/* light */ +[data-md-color-scheme="default"] { + --nj-blue: #1747a6; + --nj-blue-deep: #10357d; + --nj-blue-soft: #eaf1fd; + --nj-band: #1747a6; + --nj-red: #d93a3f; + --nj-red-soft: #fdeced; + --nj-string: #b4322a; + --nj-comment: #646d7a; + + --md-primary-fg-color: var(--nj-band); + --md-primary-fg-color--light: #1d55c4; + --md-primary-fg-color--dark: #10357d; + --md-accent-fg-color: var(--nj-blue-deep); + --md-accent-fg-color--transparent: rgba(23, 71, 166, .1); + --md-typeset-a-color: var(--nj-blue); + --md-default-fg-color: #0f1419; + --md-default-fg-color--light: #4a515c; + --md-default-fg-color--lighter: #8a919c; + --md-default-fg-color--lightest: #e3e6eb; + --md-typeset-color: #0f1419; + --md-code-bg-color: #f5f7fa; + --md-code-fg-color: #0f1419; +} + +/* dark */ +[data-md-color-scheme="slate"] { + --nj-blue: #7aa7f5; + --nj-blue-deep: #a9c6f8; + --nj-blue-soft: #16233b; + --nj-band: #173e8c; + --nj-red: #f06a6e; + --nj-red-soft: #3a1c1e; + --nj-string: #f08a7e; + --nj-comment: #8b929e; + + --md-hue: 220; + --md-primary-fg-color: var(--nj-band); + --md-primary-fg-color--light: #163f93; + --md-primary-fg-color--dark: #0c2556; + --md-accent-fg-color: var(--nj-blue-deep); + --md-accent-fg-color--transparent: rgba(122, 167, 245, .12); + --md-typeset-a-color: var(--nj-blue); + --md-default-bg-color: #0f1218; + --md-default-fg-color: #f2f4f7; + --md-default-fg-color--light: #b3b9c4; + --md-default-fg-color--lighter: #7b828e; + --md-default-fg-color--lightest: #272c36; + --md-typeset-color: #f2f4f7; + --md-code-bg-color: #171b23; + --md-code-fg-color: #f2f4f7; + --md-footer-bg-color: #0b0e13; + --md-footer-bg-color--dark: #08090d; +} + +/* syntax colours (all at least 4.5:1 on the code panel in both schemes) */ +[data-md-color-scheme="default"] { + --nj-hl-keyword: #1747a6; + --nj-hl-type: #0d6e72; + --nj-hl-function: #6b3fb8; + --nj-hl-string: #23793a; + --nj-hl-escape: #0f5d2a; + --nj-hl-key: #10357d; + --nj-hl-number: #b04a07; + --nj-hl-preproc: #a3247a; +} +[data-md-color-scheme="slate"] { + --nj-hl-keyword: #7aa7f5; + --nj-hl-type: #4fd1c5; + --nj-hl-function: #c4a3ff; + --nj-hl-string: #7ed491; + --nj-hl-escape: #b2ecc0; + --nj-hl-key: #a9c6f8; + --nj-hl-number: #f5a65b; + --nj-hl-preproc: #f48fc8; +} +.md-typeset .highlight :is(.k, .kd, .kn, .kr, .kp, .kv, .ow) { color: var(--nj-hl-keyword); font-weight: 600; } +.md-typeset .highlight :is(.kt, .nc, .nn, .na) { color: var(--nj-hl-type); } +.md-typeset .highlight :is(.nf, .fm, .nb, .bp) { color: var(--nj-hl-function); } +.md-typeset .highlight :is(.s, .s1, .s2, .sb, .sc, .sd, .sh, .sx, .sr, .ss, .sa, .dl, .cpf) { color: var(--nj-hl-string); } +.md-typeset .highlight :is(.se, .si) { color: var(--nj-hl-escape); font-weight: 600; } +.md-typeset .highlight .nt { color: var(--nj-hl-key); } +.md-typeset .highlight :is(.m, .mi, .mf, .mh, .mo, .mb, .il, .kc) { color: var(--nj-hl-number); } +.md-typeset .highlight .kc { font-weight: 500; } +.md-typeset .highlight .cp { color: var(--nj-hl-preproc); } +.md-typeset .highlight :is(.c, .c1, .cm, .ch, .cs) { color: var(--nj-comment); font-style: italic; } +.md-typeset .highlight :is(.o, .p) { color: var(--md-default-fg-color--light); } +.md-typeset .highlight :is(.n, .nx, .nv, .no, .ni, .nl, .py) { color: var(--md-code-fg-color); } +.md-typeset .highlight .err { color: inherit; background: none; } + +/* typography: Inter with cv11/ss03, bold headlines with negative tracking */ +body { + font-feature-settings: "cv11", "ss03"; +} +.md-typeset { + font-size: .85rem; /* 17 px body */ + line-height: 1.65; +} +.md-typeset h1 { + color: var(--md-typeset-color); + font-weight: 800; + letter-spacing: -.035em; + line-height: 1.1; +} +.md-typeset h2 { + font-weight: 800; + letter-spacing: -.025em; + line-height: 1.15; +} +.md-typeset h3 { + font-weight: 700; + letter-spacing: -.015em; +} +.md-typeset table:not([class]) { + font-variant-numeric: tabular-nums; +} + +/* header and tabs: one blue band with the faint syntax pattern; wordmark instead of the site name. + A veil over the tile keeps the glyphs from running through the navigation text; the hero shows the pattern at full strength. */ +.md-header, .md-tabs { + --nj-veil: linear-gradient(color-mix(in srgb, var(--md-primary-fg-color) 62%, transparent), color-mix(in srgb, var(--md-primary-fg-color) 62%, transparent)); + background-color: var(--md-primary-fg-color); + background-image: var(--nj-veil), url("pattern-on-blue.svg"); + background-size: auto, 160px 160px; + background-position: 0 0, 0 0; +} +.md-tabs { + background-position: 0 0, 0 -48px; /* continue the header's tile */ +} +.md-header__button.md-logo img { + width: auto; + height: 1.5rem; +} +.md-header__topic:first-child .md-ellipsis { /* the wordmark replaces the site name at every width */ + display: none; +} +@media screen and (max-width: 76.234375em) { /* Material hides the header logo here: show the wordmark on phones, too */ + .md-header__button.md-logo { + display: block; + margin: 0 0 0 .2rem; + padding: .4rem .2rem; + } + .md-header__button[for="__drawer"] { + order: -1; + } +} +.md-nav__button.md-logo img { + width: auto; + height: 1.4rem; +} + +/* shapes: 6 px corners on blocks, 4 px on inline code */ +.md-typeset pre > code, .md-typeset .highlight, .md-typeset .highlighttable, +.md-typeset .admonition, .md-typeset details, .md-typeset .tabbed-set, +.md-typeset .grid.cards > ul > li, .md-typeset .md-button { + border-radius: 6px; +} +.md-typeset code { + border-radius: 4px; +} + +/* inline code: the font alone marks it, no grey box; linked code keeps the link colour */ +.md-typeset :not(pre) > code { + padding: 0; + background-color: transparent; + box-shadow: none; + color: inherit; + font-size: .88em; +} +.md-typeset .highlight pre > code, .md-typeset .highlighttable { + border: 1px solid var(--md-default-fg-color--lightest); +} + +/* callouts: 3 px left border; note/info/tip in blue on blue-soft, danger/bug in red on red-soft */ +.md-typeset .admonition, .md-typeset details { + border-width: 0 0 0 3px; + box-shadow: none; + font-size: .8rem; +} +.md-typeset :is(.admonition, details):is(.note, .info, .tip, .abstract, .example, .question) { + border-color: var(--nj-blue); + background-color: var(--nj-blue-soft); +} +.md-typeset :is(.note, .info, .tip, .abstract, .example, .question) > :is(.admonition-title, summary) { + background-color: transparent; +} +.md-typeset :is(.note, .info, .tip, .abstract, .example, .question) > :is(.admonition-title, summary)::before { + background-color: var(--nj-blue); +} +.md-typeset :is(.admonition, details):is(.danger, .bug, .failure) { + border-color: var(--nj-red); + background-color: var(--nj-red-soft); +} +.md-typeset :is(.danger, .bug, .failure) > :is(.admonition-title, summary) { + background-color: transparent; +} +.md-typeset :is(.danger, .bug, .failure) > :is(.admonition-title, summary)::before { + background-color: var(--nj-red); +} + +/* buttons */ +.md-typeset .md-button--primary { + background-color: var(--nj-blue); + border-color: var(--nj-blue); +} + +/* home page hero (overrides/home.html): blue band with the syntax pattern, headline, lead, buttons, code panel */ +.nj-hero { + --nj-hero-to: #123a8a; + color: #fff; + background-color: var(--md-primary-fg-color); + background-image: url("pattern-on-blue.svg"), linear-gradient(160deg, var(--md-primary-fg-color), var(--nj-hero-to)); + background-size: 160px 160px, auto; + background-position: 0 -96px, 0 0; /* continue the tile of header and tabs */ +} +[data-md-color-scheme="slate"] .nj-hero { + --nj-hero-to: #0c2556; +} +.nj-hero__inner { + display: grid; + grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); + gap: 2.4rem; + align-items: center; + padding: 3rem .8rem 3.6rem; +} +.nj-hero__kicker { + display: inline-block; + margin: 0; + padding: .15rem .55rem; + border: 1px solid rgba(255, 255, 255, .35); + border-radius: 4px; + color: #bcd3fb; + font-family: var(--md-code-font-family); + font-size: .65rem; /* 13 px */ + font-weight: 500; + letter-spacing: .02em; +} +.nj-hero__title { + margin: 0 0 .8rem; + color: #fff; + font-size: clamp(1.7rem, 4.2vw, 3.2rem); /* 34-64 px */ + font-weight: 800; + line-height: 1.02; + letter-spacing: -.035em; +} +.nj-hero__title span { + color: #bcd3fb; +} +.nj-hero__lead { + max-width: 22em; + margin: 0 0 2rem; + color: rgba(255, 255, 255, .9); + font-size: clamp(1.1rem, 2.2vw, 1.6rem); /* 22-32 px */ + font-style: italic; + font-weight: 500; + line-height: 1.35; + letter-spacing: -.015em; +} +.nj-hero__actions { + display: flex; + flex-wrap: wrap; + gap: .6rem; + margin: 0; +} +.nj-hero .md-button.nj-hero__button { + margin: 0; + padding: .55em 1.3em; + border: 1px solid rgba(255, 255, 255, .6); + border-radius: 6px; + color: #fff; + font-size: .75rem; + font-weight: 600; +} +.nj-hero .md-button--primary.nj-hero__button { + border-color: #fff; + background-color: #fff; + color: var(--md-primary-fg-color); +} +.nj-hero .md-button.nj-hero__button:is(:hover, :focus) { + border-color: #fff; + background-color: rgba(255, 255, 255, .12); + color: #fff; +} +.nj-hero .md-button--primary.nj-hero__button:is(:hover, :focus) { + background-color: #eaf1fd; + color: var(--md-primary-fg-color); +} +.nj-hero__code { + border-radius: 6px; + background-color: var(--md-code-bg-color); + box-shadow: 0 12px 32px rgba(5, 18, 48, .35); +} +.nj-hero__code pre { + margin: 0; + padding: 1.1rem 1.3rem; + overflow-x: auto; + color: var(--md-code-fg-color); + font-family: var(--md-code-font-family); + font-size: .7rem; /* 14 px */ + line-height: 1.7; +} +.nj-hero__code .nj-k { color: var(--nj-hl-type); } +.nj-hero__code .nj-s { color: var(--nj-hl-string); } +.nj-hero__code .nj-n { color: var(--nj-hl-number); } +.nj-hero__code .nj-c { color: var(--nj-comment); font-style: italic; } +@media screen and (max-width: 59.984375em) { + .nj-hero__inner { + grid-template-columns: minmax(0, 1fr); + gap: 1.8rem; + padding: 2rem .8rem 2.4rem; + } +} +@media screen and (max-width: 29.984375em) { + .nj-hero__code pre { + font-size: .6rem; + } +} + +/* the hero carries the headline: keep the page's h1 for the title and screen readers only */ +body:has(.nj-hero) .md-content__inner > h1 { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; +} + +/* cards: 1 px line border, 6 px corners, blue icon on soft blue, blue border on hover */ +.md-typeset .grid.cards > ul > li { + padding: 1rem 1.1rem; + border: 1px solid var(--md-default-fg-color--lightest); + background-color: var(--md-default-bg-color); + transition: border-color 150ms, box-shadow 150ms, transform 150ms; +} +.md-typeset .grid.cards > ul > li:is(:hover, :focus-within) { + border-color: var(--nj-blue); + box-shadow: 0 6px 18px rgba(23, 71, 166, .12); + transform: translateY(-1px); +} +.md-typeset .grid.cards > ul > li > hr { + display: none; +} +.md-typeset .grid.cards .twemoji.lg { + box-sizing: content-box; + margin-right: .5rem; + padding: .3rem; + border-radius: 6px; + background-color: var(--nj-blue-soft); + color: var(--nj-blue); +} +.md-typeset .grid.cards > ul > li > p:first-child strong { + font-size: .9rem; + font-weight: 700; + letter-spacing: -.01em; +} +.md-typeset .grid.cards > ul > li > p:last-child a { + font-weight: 600; +} +@media (prefers-reduced-motion: reduce) { + .md-typeset .grid.cards > ul > li { transition: none; transform: none !important; } +} + +/* home page: no table of contents, so keep the text at reading width and the cards in three columns */ +body:has(.nj-hero) .md-content { + max-width: 58rem; + margin: 0 auto; +} +@media screen and (min-width: 60em) { + body:has(.nj-hero) .md-typeset .grid.cards { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} + +/* lists: Material's indent, bullets as small blue squares, numbers in the secondary text colour */ +.md-typeset ul:not(.task-list, .md-annotation-list) > li { + position: relative; + list-style: none; +} +.md-typeset ul:not(.task-list, .md-annotation-list) > li::before { + content: ""; + position: absolute; + top: .65em; /* middle of the first line at line-height 1.65 */ + left: -.95em; + width: .36em; + height: .36em; + background-color: var(--nj-blue); +} +.md-typeset ol > li::marker { + color: var(--md-default-fg-color--light); + font-variant-numeric: tabular-nums; +} +.md-typeset .grid.cards > ul > li::before { + display: none; +} + +/* wider page: Material's grid stops at 61rem (1220 px) */ +.md-grid { + max-width: 72rem; /* 1440 px */ +} + +/* tables: full width, 1 px line border with 6 px corners, header row on the panel colour, 15 px text */ +.md-typeset__table { + display: block; /* Material: inline-block, so tables only grow to their content */ +} +.md-typeset table:not([class]) { + display: table; + width: 100%; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 6px; + font-size: .75rem; + line-height: 1.55; +} +.md-typeset table:not([class]) th { + padding: .65em 1em; + border-bottom: 1px solid var(--md-default-fg-color--lightest); + background-color: var(--md-code-bg-color); + color: var(--md-typeset-color); + font-weight: 600; + vertical-align: bottom; +} +.md-typeset table:not([class]) th:first-child { border-top-left-radius: 5px; } +.md-typeset table:not([class]) th:last-child { border-top-right-radius: 5px; } +.md-typeset table:not([class]) td { + padding: .65em 1em; + border-top: 1px solid var(--md-default-fg-color--lightest); +} +.md-typeset table:not([class]) tbody tr:first-child td { + border-top: 0; +} +.md-typeset table:not([class]) tbody tr:hover { + background-color: var(--nj-blue-soft); + box-shadow: none; +} +.md-typeset table:not([class]) td code { + white-space: nowrap; +} +/* numbers and header code stay on one line; a table wider than the screen scrolls sideways instead */ +.md-typeset table:not([class]) :is(td, th):is([align="right"], [style*="right"]), +.md-typeset table:not([class]) th code { + white-space: nowrap; +} +@media screen and (max-width: 44.984375em) { + .md-typeset table:not([class]) { + font-size: .7rem; + } + .md-typeset table:not([class]) :is(th, td) { + padding: .55em .75em; + } +} + +/* more room before headings (Material: h2 1.6em, h3 1.6em, h4-h6 1-1.25em) and at the end of each page (1.2rem) */ +.md-typeset h2 { margin-top: 2.4em; } +.md-typeset h3 { margin-top: 2.2em; } +.md-typeset h2 + h3 { margin-top: .8em; } +.md-typeset :is(h4, h5, h6) { margin-top: 1.8em; } +.md-content__inner { + margin-bottom: 4.8rem; /* 96 px */ +} + +/* Mermaid diagrams: white boxes with a blue outline, grey lines, Inter; shapes and spacing in js/mermaid-brand.js */ +:root > * { + --md-mermaid-font-family: var(--md-text-font-family), sans-serif; + --md-mermaid-edge-color: var(--md-default-fg-color--lighter); + --md-mermaid-node-bg-color: var(--md-default-bg-color); + --md-mermaid-node-fg-color: var(--nj-blue); + --md-mermaid-label-bg-color: var(--md-default-bg-color); + --md-mermaid-label-fg-color: var(--md-default-fg-color); + --md-mermaid-sequence-actor-bg-color: var(--nj-blue-soft); + --md-mermaid-sequence-actor-line-color: var(--md-default-fg-color--lighter); + --md-mermaid-sequence-note-bg-color: var(--md-code-bg-color); + --md-mermaid-sequence-note-border-color: var(--md-default-fg-color--lightest); + --md-mermaid-sequence-number-fg-color: #fff; +} + +/* a diagram wider than the column scrolls sideways (js/mermaid-brand.js stops shrinking it at 80 %) */ +.md-typeset .mermaid { + overflow-x: auto; +} +/* ... and one that is narrower than the column sits in the middle of it */ +.md-typeset .mermaid { + text-align: center; +} + +/* external links (marked by js/external-links.js) get a small "open in new window" icon (Font Awesome + "external-link-alt") in front of them */ +.md-typeset a.nj-external::before { + content: ""; + display: inline-block; + width: .72em; + height: .72em; + margin-right: .3em; + background-color: currentColor; + opacity: .65; + -webkit-mask: var(--nj-external-icon) no-repeat center / contain; + mask: var(--nj-external-icon) no-repeat center / contain; +} +:root { + --nj-external-icon: url('data:image/svg+xml;utf8,'); +} + + +/* ---- polish pass ---- */ + +/* header: a search field that reads as a field on the band, tabs with an active marker, readable GitHub facts */ +.md-header .md-search__form { + border: 1px solid rgba(255, 255, 255, .22); + border-radius: 6px; + background-color: rgba(255, 255, 255, .12); + transition: background-color 150ms, border-color 150ms; +} +.md-header .md-search__form:hover { + border-color: rgba(255, 255, 255, .4); + background-color: rgba(255, 255, 255, .2); +} +.md-search__output { + border-radius: 0 0 6px 6px; + box-shadow: 0 16px 40px rgba(5, 18, 48, .28); +} +.md-search-result__link:focus-visible, .md-search-result__more summary:focus-visible { + outline: 2px solid var(--nj-blue); + outline-offset: -2px; +} +.md-tabs__link { + font-size: .72rem; + font-weight: 500; + opacity: .85; +} +.md-tabs__item--active .md-tabs__link, .md-tabs__link:hover { + opacity: 1; +} +.md-tabs__item--active { + box-shadow: inset 0 -2px 0 #fff; +} +.md-source__facts { + font-size: .62rem; +} + +/* footer: deep brand blue instead of neutral black (the dark scheme keeps its own near-black) */ +[data-md-color-scheme="default"] { + --md-footer-bg-color: #0d2a66; + --md-footer-bg-color--dark: #0a2152; +} +.md-footer-meta .md-copyright, .md-footer-meta .md-copyright a { + color: rgba(255, 255, 255, .72); +} +.md-footer__link { + border-radius: 6px; + transition: background-color 150ms; +} +.md-footer__link:is(:hover, :focus-visible) { + background-color: rgba(255, 255, 255, .08); +} + +/* page title: tighter to the first paragraph; page actions (view/edit source) stay in the background */ +.md-typeset h1 { + margin-bottom: 1rem; +} +.md-content__button { + opacity: .55; + transition: opacity 150ms; +} +.md-content__button:is(:hover, :focus-visible) { + opacity: 1; +} +body:has(.nj-hero) .md-content__button { + display: none; +} + +/* sidebars: bold marker for the current page, rail and marker for the table of contents */ +.md-nav__link--active { + font-weight: 600; +} +.md-nav--secondary > .md-nav__list { + margin-left: -.1rem; + border-left: 1px solid color-mix(in srgb, var(--md-default-fg-color) 16%, transparent); +} +.md-nav--secondary .md-nav__link { + margin-left: -1px; + padding-left: .6rem; + border-left: 2px solid transparent; +} +.md-nav--secondary .md-nav__link--active { + border-left-color: var(--nj-blue); + color: var(--nj-blue); +} +.md-nav--secondary .md-nav__list .md-nav__list { + padding-left: .6rem; +} +.md-nav--secondary .md-nav__title { + font-size: .64rem; + letter-spacing: .04em; + text-transform: uppercase; +} + +/* keyboard focus: one visible ring in the brand blue */ +.md-typeset a:focus-visible, .md-typeset .md-button:focus-visible, .md-typeset summary:focus-visible, +.md-nav__link:focus-visible, .md-tabs__link:focus-visible, .md-top:focus-visible { + outline: 2px solid var(--nj-blue); + outline-offset: 2px; + border-radius: 3px; +} +.md-header :is(a, button, label):focus-visible, .nj-hero a:focus-visible { + outline: 2px solid #fff; + outline-offset: 2px; +} + +/* inline code must not stretch the line box (JetBrains Mono has tall metrics), abbreviations stay quiet */ +.md-typeset :not(pre) > code { + line-height: 1; +} +.md-typeset abbr { + border-bottom-color: var(--md-default-fg-color--lighter); +} +.md-typeset :is(h1, h2, h3, h4, a, .grid.cards > ul > li > p:first-child) abbr { + border-bottom-color: transparent; +} + +/* number railroad diagram: inline SVG (docs/images/json_syntax_number.svg), follows the colour scheme */ +.md-typeset .railroad-wrap, .md-typeset .nj-fig-wrap { + overflow-x: auto; + margin: 1.5rem 0; +} +.md-typeset svg.railroad { + display: block; + width: 100%; + min-width: 36rem; + max-width: 52rem; + margin-inline: auto; + color: var(--md-default-fg-color); + font-family: var(--md-text-font-family), sans-serif; +} +.railroad .rr-t { fill: color-mix(in srgb, var(--md-typeset-a-color) 10%, transparent); stroke: var(--md-typeset-a-color); stroke-width: 2; } +.railroad .rr-track, .railroad .rr-n { stroke: color-mix(in srgb, currentColor 60%, var(--md-default-bg-color)); stroke-opacity: 1; } /* opaque, so overlapping segments do not darken */ +.railroad .rr-n { fill: color-mix(in srgb, currentColor 6%, transparent); stroke-width: 2; } +.railroad .rr-bg { fill: var(--md-default-bg-color); } +.railroad .rr-arrow { fill: currentColor; fill-opacity: .6; } +.railroad text { fill: currentColor; text-anchor: middle; } +.railroad .rr-c { font-family: var(--md-code-font-family), monospace; font-size: 16px; font-weight: 500; } +.railroad .rr-b { font-size: 14.5px; font-weight: 500; } +.railroad .rr-l { font-size: 14px; text-anchor: start; fill-opacity: .6; } +.railroad .rr-name { font-size: 17px; font-weight: 700; fill-opacity: 1; } +/* figures drawn as inline SVG (docs/images/callback_events.svg, range-*.svg): they follow the colour scheme */ +.md-typeset svg.nj-fig { + display: block; + width: 100%; + height: auto; + margin-inline: auto; + color: var(--md-default-fg-color); + font-family: var(--md-text-font-family), sans-serif; +} +.md-typeset svg.nj-fig--range { min-width: 30rem; max-width: 40rem; } +.md-typeset svg.nj-fig--cb { max-width: 30rem; } +.nj-fig { --fg-line: color-mix(in srgb, currentColor 55%, var(--md-default-bg-color)); } +.nj-fig .fg-cell { fill: color-mix(in srgb, var(--md-typeset-a-color) 14%, var(--md-default-bg-color)); stroke: var(--fg-line); stroke-width: 1.5; } +.nj-fig .fg-cell--end { fill: none; stroke-dasharray: 4 3; } +.nj-fig .fg-pill { fill: color-mix(in srgb, var(--md-typeset-a-color) 10%, var(--md-default-bg-color)); stroke: var(--md-typeset-a-color); stroke-width: 1.5; } +.nj-fig .fg-pilltext { fill: var(--md-typeset-a-color); font-family: var(--md-code-font-family), monospace; font-size: 14px; font-weight: 500; text-anchor: middle; } +.nj-fig .fg-arrow { stroke: var(--fg-line); stroke-width: 1.5; fill: none; } +.nj-fig .fg-arrow--dash { stroke-dasharray: 3 3; } +.nj-fig .fg-head { fill: var(--fg-line); } +.nj-fig .fg-note { fill: currentColor; fill-opacity: .7; font-size: 13.5px; text-anchor: middle; } +.nj-fig .fg-note--r { text-anchor: end; } +.nj-fig .fg-note--l { text-anchor: start; } +.nj-fig .fg-h { fill: currentColor; fill-opacity: .7; font-size: 15px; font-weight: 600; } +.nj-fig .fg-code { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 16px; white-space: pre; } +.nj-fig .fg-leg { font-size: 15px; } +.nj-fig { --cb-os: #4eb05a; --cb-oe: #1a6b34; --cb-k: #e5534b; --cb-as: #f0c000; --cb-ae: #b07d00; --cb-v: #1f6fd1; } +[data-md-color-scheme="slate"] .nj-fig { --cb-os: #7ee787; --cb-oe: #2ea043; --cb-k: #ff7b72; --cb-as: #f2cc60; --cb-ae: #c69026; --cb-v: #58a6ff; } +.nj-fig .cb-os { fill: var(--cb-os); } +.nj-fig .cb-oe { fill: var(--cb-oe); } +.nj-fig .cb-k { fill: var(--cb-k); } +.nj-fig .cb-as { fill: var(--cb-as); } +.nj-fig .cb-ae { fill: var(--cb-ae); } +.nj-fig .cb-v { fill: var(--cb-v); } +.md-typeset img[src*="json-light"], .md-typeset img[src*="json-dark"] { + border-radius: 8px; +} +.md-typeset img { + max-width: 100%; + height: auto; +} + +/* home page: content uses the same column as every other page */ +body:has(.nj-hero) .md-content { + max-width: none; + margin: 0; +} +.md-typeset .grid.cards { + width: auto; +} + +/* 404 page (overrides/404.html) */ +.nj-404 { + max-width: 30rem; + padding: 2rem 0 3rem; +} +.nj-404__code { + margin: 0 0 .4rem; + color: var(--nj-blue); + font-family: var(--md-code-font-family); + font-size: .8rem; + font-weight: 500; +} +.md-typeset .nj-404 h1 { + margin-bottom: .8rem; +} +.nj-404 .md-button { + margin: .4rem .4rem 0 0; +} + +/* touch targets and phones */ +@media screen and (max-width: 59.984375em) { + .md-nav__link { + padding-block: .2rem; + } +} +@media screen and (max-width: 29.984375em) { + .md-typeset h1 { + font-size: 1.7em; + } + .md-typeset .highlight pre > code { + font-size: .68rem; + } +} + +/* figure captions: "Figure N." in bold, close to the figure, set in from the text column; figures and tables are + numbered per page, each with its own counter */ +.md-content__inner { counter-reset: nj-figure nj-table; } +.md-typeset :is(.nj-caption, .nj-charts-caption) { + max-width: none; + margin: .3rem 2rem 1.5rem; + font-size: .75rem; + line-height: 1.5; + text-align: left; + color: var(--md-default-fg-color--light); +} +.md-typeset :is(.nj-fig-wrap, .railroad-wrap, .nj-charts-grid-wrap) + :is(.nj-caption, .nj-charts-caption) { margin-top: -1.1rem; } +.md-typeset .nj-charts-grid-wrap + :is(.nj-caption, .nj-charts-caption) { margin-top: .3rem; } +.md-typeset :is(.nj-caption, .nj-charts-caption)::before { + counter-increment: nj-figure; + content: "Figure " counter(nj-figure) ". "; + font-weight: 700; + color: var(--md-default-fg-color); +} +@media screen and (max-width: 44.9375em) { + .md-typeset :is(.nj-caption, .nj-charts-caption) { margin-inline: 1rem; } +} + +/* table captions: "Table N." in bold, directly below the table, in the figure caption style */ +.md-typeset .nj-table-caption { + max-width: none; + margin: .3rem 2rem 1.5rem; + font-size: .75rem; + line-height: 1.5; + text-align: left; + color: var(--md-default-fg-color--light); +} +.md-typeset :is(.md-typeset__scrollwrap, .md-typeset__table) + .nj-table-caption { margin-top: -.4rem; } +.md-typeset .nj-table-caption::before { + counter-increment: nj-table; + content: "Table " counter(nj-table) ". "; + font-weight: 700; + color: var(--md-default-fg-color); +} +@media screen and (max-width: 44.9375em) { + .md-typeset .nj-table-caption { margin-inline: 1rem; } +} diff --git a/docs/mkdocs/docs/css/fig-charts.css b/docs/mkdocs/docs/css/fig-charts.css new file mode 100644 index 000000000..742a70bb7 --- /dev/null +++ b/docs/mkdocs/docs/css/fig-charts.css @@ -0,0 +1,142 @@ +/* figures: charts (docs/images/compile_times.svg, binary_sizes_*.svg, ordered_json_scaling.svg from + scripts/figures/charts.py) and the number literal explorer on features/types/number_handling.md */ + +/* series colours: categorical slots validated for CVD separation on the light and the slate surface */ +.nj-charts, .nj-charts-key { + --nj-charts-c1: #2a78d6; + --nj-charts-c2: #eb6834; + --nj-charts-c3: #1baf7a; + --nj-charts-c4: #eda100; + --nj-charts-c5: #e87ba4; + --nj-charts-c6: #008300; + --nj-charts-ink2: var(--md-default-fg-color--light); + --nj-charts-grid: color-mix(in srgb, currentColor 12%, var(--md-default-bg-color)); + --nj-charts-base: color-mix(in srgb, currentColor 35%, var(--md-default-bg-color)); +} +[data-md-color-scheme="slate"] :is(.nj-charts, .nj-charts-key) { + --nj-charts-c1: #3987e5; + --nj-charts-c2: #d95926; + --nj-charts-c3: #199e70; + --nj-charts-c4: #c98500; + --nj-charts-c5: #d55181; + --nj-charts-c6: #008300; +} +/* concepts: two compilers, two object types */ +.nj-charts { --nj-charts-clang-c: var(--nj-charts-c1); --nj-charts-gcc-c: var(--nj-charts-c2); + --nj-charts-json-c: var(--nj-charts-c1); --nj-charts-ojson-c: var(--nj-charts-c2); } + +.md-typeset svg.nj-charts--compile, .md-typeset svg.nj-charts--scaling { max-width: 26rem; } +.md-typeset svg.nj-charts--sizes { max-width: 26rem; } + +.nj-charts text { fill: currentColor; font-size: 13px; } +.nj-charts .nj-charts-leg { font-size: 13.5px; } +.nj-charts .nj-charts-rowlabel { font-size: 13.5px; font-weight: 500; } +.nj-charts .nj-charts-code { font-family: var(--md-code-font-family), monospace; font-size: 12.5px; } +.nj-charts .nj-charts-sub { fill: var(--nj-charts-ink2); font-weight: 400; } +.nj-charts .nj-charts-fmt { text-anchor: end; font-weight: 400; } +.nj-charts .nj-charts-best { font-weight: 700; } +.nj-charts .nj-charts-panel { font-family: var(--md-code-font-family), monospace; font-size: 14px; font-weight: 600; } +.nj-charts .nj-charts-tick { fill: var(--nj-charts-ink2); font-size: 12px; text-anchor: middle; font-variant-numeric: tabular-nums; } +.nj-charts .nj-charts-tick--l { text-anchor: start; } +.nj-charts .nj-charts-tick--r { text-anchor: end; } +.nj-charts .nj-charts-val { font-size: 12px; font-variant-numeric: tabular-nums; + paint-order: stroke; stroke: var(--md-default-bg-color); stroke-width: 4px; stroke-linejoin: round; } +.nj-charts .nj-charts-factor { fill: var(--nj-charts-ink2); font-size: 12px; font-weight: 600; text-anchor: middle; } +.nj-charts .nj-charts-note { fill: var(--nj-charts-ink2); font-size: 12px; } + +.nj-charts .nj-charts-grid { stroke: var(--nj-charts-grid); stroke-width: 1; } +.nj-charts .nj-charts-zero, .nj-charts .nj-charts-axis { stroke: var(--nj-charts-base); stroke-width: 1.5; } +.nj-charts .nj-charts-ref { stroke: currentColor; stroke-width: 1.5; } + +.nj-charts .nj-charts-c1 { fill: var(--nj-charts-c1); } +.nj-charts .nj-charts-c2 { fill: var(--nj-charts-c2); } +.nj-charts .nj-charts-c3 { fill: var(--nj-charts-c3); } +.nj-charts .nj-charts-c4 { fill: var(--nj-charts-c4); } +.nj-charts .nj-charts-c5 { fill: var(--nj-charts-c5); } +.nj-charts .nj-charts-c6 { fill: var(--nj-charts-c6); } +.nj-charts .nj-charts-dim { fill-opacity: .45; } +.nj-charts .nj-charts-clang { fill: var(--nj-charts-clang-c); } +.nj-charts .nj-charts-gcc { fill: var(--nj-charts-gcc-c); } +.nj-charts polyline.nj-charts-json, .nj-charts line.nj-charts-json { stroke: var(--nj-charts-json-c); stroke-width: 2; fill: none; } +.nj-charts polyline.nj-charts-ojson, .nj-charts line.nj-charts-ojson { stroke: var(--nj-charts-ojson-c); stroke-width: 2; fill: none; } +.nj-charts .nj-charts-json-dot { fill: var(--nj-charts-json-c); stroke: var(--md-default-bg-color); stroke-width: 2; } +.nj-charts .nj-charts-ojson-dot { fill: var(--nj-charts-ojson-c); stroke: var(--md-default-bg-color); stroke-width: 2; } + +/* single wide charts: larger text on phones, where the SVG is scaled down */ +@media screen and (max-width: 44.9375em) { + svg.nj-charts.nj-charts--compile text, svg.nj-charts.nj-charts--scaling text { font-size: 15px; } + svg.nj-charts.nj-charts--compile .nj-charts-code { font-size: 14px; } + svg.nj-charts:is(.nj-charts--compile, .nj-charts--scaling) :is(.nj-charts-tick, .nj-charts-val, .nj-charts-factor, .nj-charts-note) { font-size: 14px; } +} + +/* small multiples: two panels per row, one on narrow screens */ +.md-typeset .nj-charts-grid-wrap { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); + gap: 1rem 2rem; + margin: 1.5rem 0 .5rem; +} +.md-typeset .nj-charts-grid-wrap > .nj-fig-wrap { margin: 0; } + +/* number literal explorer */ +.md-typeset .nj-charts-num-ui { + margin: 1rem 0 .75rem; + padding: .8rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 8px; +} +.md-typeset .nj-charts-num-ui label { display: block; font-weight: 600; font-size: .75rem; margin-bottom: .3rem; } +.md-typeset .nj-charts-num-input { + width: 100%; + box-sizing: border-box; + min-height: 44px; + padding: .4rem .6rem; + font-family: var(--md-code-font-family), monospace; + font-size: .8rem; + color: var(--md-default-fg-color); + background: var(--md-code-bg-color); + border: 1px solid var(--md-default-fg-color--lighter); + border-radius: 6px; +} +.md-typeset .nj-charts-num-input:focus-visible, .md-typeset .nj-charts-num-chip:focus-visible { + outline: 2px solid var(--md-typeset-a-color); + outline-offset: 2px; +} +.md-typeset .nj-charts-num-ui ul.nj-charts-num-chips:not([hidden]) { display: flex; flex-wrap: wrap; gap: .35rem; margin: .6rem 0; padding: 0; list-style: none; } +.md-typeset .nj-charts-num-ui ul.nj-charts-num-chips > li { margin: 0; padding: 0; list-style: none; } +.md-typeset .nj-charts-num-ui ul.nj-charts-num-chips > li::before, .md-typeset .nj-charts-num-ui ul.nj-charts-num-chips > li::marker { content: none; } +.md-typeset .nj-charts-num-chip { + min-height: 44px; + max-width: 100%; + padding: .25rem .6rem; + overflow-wrap: anywhere; + font-family: var(--md-code-font-family), monospace; + font-size: .7rem; + color: var(--md-typeset-a-color); + background: color-mix(in srgb, var(--md-typeset-a-color) 8%, var(--md-default-bg-color)); + border: 1px solid color-mix(in srgb, var(--md-typeset-a-color) 35%, var(--md-default-bg-color)); + border-radius: 6px; + cursor: pointer; + text-align: left; +} +.md-typeset .nj-charts-num-chip[aria-pressed="true"] { + color: var(--md-default-bg-color); + background: var(--md-typeset-a-color); + border-color: var(--md-typeset-a-color); +} +.md-typeset .nj-charts-num-out { + display: grid; + grid-template-columns: max-content 1fr; + gap: .2rem .8rem; + margin: 0; + font-size: .75rem; + overflow-wrap: anywhere; +} +.md-typeset .nj-charts-num-out dt { color: var(--md-default-fg-color--light); margin: 0; } +.md-typeset .nj-charts-num-out dd { margin: 0; } +.md-typeset .nj-charts-num-miss { font-size: .75rem; color: var(--md-default-fg-color--light); margin: 0; } +.md-typeset .nj-charts-num tr.nj-charts-num-hit td { background: var(--md-accent-fg-color--transparent); } + +/* direct line labels replace the legend */ +.nj-charts .nj-charts-name-json { fill: var(--nj-charts-json-c); font-weight: 600; } +.nj-charts .nj-charts-name-ojson { fill: var(--nj-charts-ojson-c); font-weight: 600; } diff --git a/docs/mkdocs/docs/css/fig-exceptions.css b/docs/mkdocs/docs/css/fig-exceptions.css new file mode 100644 index 000000000..a3562f732 --- /dev/null +++ b/docs/mkdocs/docs/css/fig-exceptions.css @@ -0,0 +1,75 @@ +/* figures: exceptions (home/exceptions.md exception map, community/quality_assurance.md pipeline) */ + +/* the generated SVGs hold a wide and a narrow drawing; show one of them */ +.md-typeset svg.nj-exceptions-map--wide, .md-typeset svg.nj-exceptions-qa--wide { max-width: 47.5rem; } +.md-typeset svg.nj-exceptions-map--narrow, .md-typeset svg.nj-exceptions-qa--narrow { display: none; max-width: 24rem; } +@media screen and (max-width: 37.5em) { + .md-typeset svg.nj-exceptions-map--wide, .md-typeset svg.nj-exceptions-qa--wide { display: none; } + .md-typeset svg.nj-exceptions-map--narrow, .md-typeset svg.nj-exceptions-qa--narrow { display: block; } +} + +/* shared */ +.nj-fig { --nj-exceptions-line: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); } +.nj-fig .nj-exceptions-edge { stroke: var(--nj-exceptions-line); stroke-width: 1.5; fill: none; } +.nj-fig .nj-exceptions-tri { fill: var(--md-default-bg-color); stroke: var(--nj-exceptions-line); stroke-width: 1.3; } +.nj-fig .nj-exceptions-box { + fill: color-mix(in srgb, currentColor 4%, var(--md-default-bg-color)); + stroke: color-mix(in srgb, currentColor 30%, var(--md-default-bg-color)); + stroke-width: 1.5; +} +.nj-fig .nj-exceptions-box--fam { + fill: color-mix(in srgb, var(--md-typeset-a-color) 9%, var(--md-default-bg-color)); + stroke: color-mix(in srgb, var(--md-typeset-a-color) 55%, var(--md-default-bg-color)); +} +.nj-fig .nj-exceptions-name { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 14px; font-weight: 600; } +.nj-fig .nj-exceptions-sub { fill: currentColor; fill-opacity: .68; font-size: 12.5px; } + +/* exception map: id chips are links */ +.nj-fig .nj-exceptions-chip rect { + fill: color-mix(in srgb, var(--md-typeset-a-color) 7%, var(--md-default-bg-color)); + stroke: color-mix(in srgb, var(--md-typeset-a-color) 40%, var(--md-default-bg-color)); + stroke-width: 1.2; + transition: fill .15s; +} +.nj-fig .nj-exceptions-chip--named rect { + fill: color-mix(in srgb, var(--md-typeset-a-color) 16%, var(--md-default-bg-color)); + stroke: var(--md-typeset-a-color); +} +.nj-fig .nj-exceptions-id { fill: var(--md-typeset-a-color); font-family: var(--md-code-font-family), monospace; font-size: 13px; font-weight: 600; } +.nj-fig .nj-exceptions-label { fill: currentColor; font-size: 12.5px; font-weight: 500; } +.nj-fig a:hover rect, .nj-fig a:focus-visible rect { + fill: color-mix(in srgb, var(--md-typeset-a-color) 28%, var(--md-default-bg-color)); +} +.nj-fig a:focus { outline: none; } +.nj-fig a:focus-visible rect { stroke: var(--md-typeset-a-color); stroke-width: 2.5; } +.nj-fig a:hover .nj-exceptions-name, .nj-fig a:focus-visible .nj-exceptions-name { text-decoration: underline; } +@media (prefers-reduced-motion: reduce) { + .nj-fig .nj-exceptions-chip rect { transition: none; } +} + +/* quality assurance pipeline */ +.nj-fig { --nj-exceptions-push: var(--md-typeset-a-color); --nj-exceptions-sched: #a86400; --nj-exceptions-cont: #1a7f37; } +[data-md-color-scheme="slate"] .nj-fig { --nj-exceptions-sched: #e3a33b; --nj-exceptions-cont: #56c46e; } +.nj-fig .nj-exceptions-groupbox { + fill: color-mix(in srgb, currentColor 2.5%, var(--md-default-bg-color)); + stroke: color-mix(in srgb, currentColor 22%, var(--md-default-bg-color)); + stroke-width: 1.2; + stroke-dasharray: 5 4; +} +.nj-fig .nj-exceptions-group { fill: currentColor; fill-opacity: .68; font-size: 13px; font-weight: 600; letter-spacing: .02em; } +.nj-fig .nj-exceptions-card .nj-exceptions-box { fill: var(--md-default-bg-color); } +.nj-fig .nj-exceptions-ctitle { fill: currentColor; font-size: 15px; font-weight: 700; } +.nj-fig .nj-exceptions-line { fill: currentColor; fill-opacity: .8; font-size: 12.5px; } +.nj-fig .nj-exceptions-badge { stroke-width: 1.2; } +.nj-fig .nj-exceptions-badgetext { font-size: 11px; font-weight: 600; text-anchor: middle; } +.nj-fig .nj-exceptions-badge--push { fill: color-mix(in srgb, var(--nj-exceptions-push) 12%, var(--md-default-bg-color)); stroke: var(--nj-exceptions-push); } +.nj-fig .nj-exceptions-badge--sched { fill: color-mix(in srgb, var(--nj-exceptions-sched) 12%, var(--md-default-bg-color)); stroke: var(--nj-exceptions-sched); } +.nj-fig .nj-exceptions-badge--cont { fill: color-mix(in srgb, var(--nj-exceptions-cont) 12%, var(--md-default-bg-color)); stroke: var(--nj-exceptions-cont); } +.nj-fig .nj-exceptions-badgetext--push { fill: var(--nj-exceptions-push); } +.nj-fig .nj-exceptions-badgetext--sched { fill: var(--nj-exceptions-sched); } +.nj-fig .nj-exceptions-badgetext--cont { fill: var(--nj-exceptions-cont); } +.nj-fig .nj-exceptions-stage { fill: var(--md-typeset-a-color); } +.nj-fig .nj-exceptions-stagetext { fill: #fff; font-size: 14px; font-weight: 700; text-anchor: middle; } +.nj-fig .nj-exceptions-stagesub { fill: #fff; fill-opacity: .85; font-size: 12px; text-anchor: middle; } +[data-md-color-scheme="slate"] .nj-fig .nj-exceptions-stage { fill: #1747a6; } +.nj-fig .nj-exceptions-qa .fg-head, .nj-exceptions-qa .fg-head { fill: var(--nj-exceptions-line); } diff --git a/docs/mkdocs/docs/css/fig-integration.css b/docs/mkdocs/docs/css/fig-integration.css new file mode 100644 index 000000000..da588e93c --- /dev/null +++ b/docs/mkdocs/docs/css/fig-integration.css @@ -0,0 +1,176 @@ +/* figures: integration */ + +/* namespace name builder (features/namespace.md, js/fig-integration.js) */ +.md-typeset .nj-integration-ns { + --nj-int-line: color-mix(in srgb, currentColor 30%, var(--md-default-bg-color)); + display: block; + width: auto; + max-width: none; + margin: 1.5rem 0; + padding: .9rem 1rem; + text-align: left; + border: 1px solid var(--nj-int-line); + border-radius: 8px; +} +.md-typeset .nj-integration-ns__strip { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + gap: .5rem .15rem; +} +.md-typeset .nj-integration-ns__seg { + display: inline-flex; + flex-direction: column; + align-items: center; + min-width: 0; +} +.md-typeset .nj-integration-ns__seg code { + padding: .25em .5em; + border: 1.5px solid var(--nj-int-line); + border-radius: 6px; + background: var(--md-default-bg-color); + color: var(--md-default-fg-color); + font-size: .8rem; + font-weight: 600; + word-break: normal; +} +.md-typeset .nj-integration-ns__seg small { + max-width: 10rem; + margin-top: .25rem; + color: var(--md-default-fg-color--light); + font-size: .58rem; + line-height: 1.25; + text-align: center; + overflow-wrap: anywhere; +} +.md-typeset .nj-integration-ns__seg--sep code { + border-color: transparent; + padding-inline: .1em; +} +.md-typeset .nj-integration-ns__seg--abi code { + border-color: var(--md-typeset-a-color); + background: color-mix(in srgb, var(--md-typeset-a-color) 12%, var(--md-default-bg-color)); + color: var(--md-typeset-a-color); +} +.md-typeset .nj-integration-ns__seg--tag code { + border-style: dashed; + border-color: var(--md-typeset-a-color); + color: var(--md-typeset-a-color); +} +.md-typeset .nj-integration-ns__seg--ver code { + background: color-mix(in srgb, currentColor 8%, var(--md-default-bg-color)); +} +.md-typeset .nj-integration-ns figcaption { + max-width: none; + margin: .8rem 0 0; + font-size: .75rem; + text-align: left; + color: var(--md-default-fg-color--light); +} +.md-typeset .nj-integration-ns__controls { + margin-top: 1rem; + padding-top: .8rem; + border-top: 1px solid var(--nj-int-line); + font-size: .7rem; +} +.md-typeset .nj-integration-ns__version select { + min-height: 2rem; + margin-left: .3rem; + padding: 0 .4rem; + border: 1px solid var(--nj-int-line); + border-radius: 6px; + background: var(--md-default-bg-color); + color: var(--md-default-fg-color); + font: inherit; +} +.md-typeset .nj-integration-ns__list { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr)); + gap: 0 1rem; + margin: .7rem 0 0; + padding: 0; + border: 0; +} +.md-typeset .nj-integration-ns__list legend { + padding: 0; + margin-bottom: .3rem; + font-weight: 600; +} +.md-typeset .nj-integration-ns__opt { + display: grid; + grid-template-columns: 1.1rem 1fr; + align-items: center; + gap: 0 .55rem; + min-height: 2.2rem; + padding: .15rem 0; + cursor: pointer; +} +.md-typeset .nj-integration-ns__meta { + grid-column: 2; + display: flex; + flex-wrap: wrap; + gap: 0 .45rem; +} +.md-typeset .nj-integration-ns__opt input { + grid-row: 1 / span 2; + width: 1.1rem; + height: 1.1rem; + margin: 0; + accent-color: var(--md-typeset-a-color); +} +.md-typeset .nj-integration-ns__opt input:focus-visible { + outline: 2px solid var(--md-accent-fg-color); + outline-offset: 2px; +} +.md-typeset .nj-integration-ns__opt code { + font-size: .64rem; + overflow-wrap: anywhere; +} +.md-typeset .nj-integration-ns__hint { + color: var(--md-typeset-a-color); + font-family: var(--md-code-font-family); + font-size: .64rem; +} +.md-typeset .nj-integration-ns__since { + color: var(--md-default-fg-color--light); + font-size: .6rem; +} +.md-typeset .nj-integration-ns__opt.is-unavailable { + cursor: not-allowed; + opacity: .5; +} +@media screen and (max-width: 44.984375em) { + .md-typeset .nj-integration-ns__opt { + min-height: 2.75rem; + } +} + +/* roadmap lanes and release timeline (scripts/figures/integration.py, release_timeline.py) */ +.md-typeset svg.nj-fig--lanes { min-width: 44rem; max-width: 46rem; } +.md-typeset svg.nj-fig--timeline { min-width: 44rem; max-width: 52rem; } +.nj-fig .nj-int-lane { fill: color-mix(in srgb, var(--md-typeset-a-color) 10%, var(--md-default-bg-color)); stroke: var(--md-typeset-a-color); stroke-width: 1.5; } +.nj-fig .nj-int-lane--future { fill: none; stroke-dasharray: 6 4; } +.nj-fig .nj-int-lanetext { fill: var(--md-typeset-a-color); font-size: 15px; font-weight: 700; } +.nj-fig .nj-int-text { fill: currentColor; font-size: 13px; } +.nj-fig .nj-int-mute { fill: currentColor; fill-opacity: .7; font-size: 12.5px; } +.nj-fig .nj-int-macro { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 12.5px; } +.nj-fig .nj-int-val { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 13px; font-weight: 600; } +.nj-fig .nj-int-row { fill: color-mix(in srgb, currentColor 4%, var(--md-default-bg-color)); } +.nj-fig .nj-int-track { fill: color-mix(in srgb, currentColor 14%, var(--md-default-bg-color)); stroke: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); stroke-width: 1.2; } +.nj-fig .nj-int-track--on { fill: var(--md-typeset-a-color); stroke: var(--md-typeset-a-color); } +.nj-fig .nj-int-knob { fill: var(--md-default-bg-color); stroke: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); stroke-width: 1.2; } +.nj-fig .nj-int-knob--on { stroke: var(--md-typeset-a-color); } +.nj-fig .nj-int-axis { stroke: color-mix(in srgb, currentColor 45%, var(--md-default-bg-color)); stroke-width: 1.5; } +.nj-fig .nj-int-grid { stroke: color-mix(in srgb, currentColor 14%, var(--md-default-bg-color)); stroke-width: 1; } +.nj-fig .nj-int-minor { fill: var(--md-typeset-a-color); stroke: var(--md-default-bg-color); stroke-width: 1.5; } +.nj-fig .nj-int-patch { fill: var(--md-default-bg-color); stroke: var(--md-typeset-a-color); stroke-width: 1.5; } +.nj-fig .nj-int-major { fill: currentColor; fill-opacity: .7; font-size: 13px; font-weight: 600; } +.nj-fig .nj-int-label { fill: currentColor; font-size: 12px; font-weight: 600; text-anchor: middle; } +.nj-fig .nj-int-year { fill: currentColor; fill-opacity: .7; font-size: 12px; text-anchor: middle; } +.nj-fig .nj-int-leader { stroke: color-mix(in srgb, currentColor 30%, var(--md-default-bg-color)); stroke-width: 1; } +.nj-fig .nj-int-hit { fill: transparent; } + +/* roadmap: value pills (3.x default -> 4.0 value) */ +.nj-fig .nj-int-pill { fill: color-mix(in srgb, currentColor 8%, var(--md-default-bg-color)); stroke: color-mix(in srgb, currentColor 35%, var(--md-default-bg-color)); stroke-width: 1.2; } +.nj-fig .nj-int-pill--v4 { fill: var(--md-typeset-a-color); stroke: var(--md-typeset-a-color); } +.nj-fig .nj-int-val--v4 { fill: var(--md-default-bg-color); } diff --git a/docs/mkdocs/docs/css/fig-jsonview.css b/docs/mkdocs/docs/css/fig-jsonview.css new file mode 100644 index 000000000..89cd3bcc9 --- /dev/null +++ b/docs/mkdocs/docs/css/fig-jsonview.css @@ -0,0 +1,107 @@ +/* figures: jsonview (features/json_view.md; SVGs from scripts/figures/json_view_layout.py, stepper in js/fig-jsonview.js) */ + +/* one colour per concept, the same in every figure: structure (object/array, views) blue, keys navy, strings green, + numbers orange, decoded strings purple, owned edit storage teal, dangling/invalid red */ +.nj-jsonview, .nj-jsonview-cmp { + --jv-struct: var(--nj-blue); + --jv-key: var(--nj-hl-key); + --jv-str: var(--nj-hl-string); + --jv-num: var(--nj-hl-number); + --jv-dec: var(--nj-hl-function); + --jv-own: var(--nj-hl-type); + --jv-bad: var(--nj-red); + --jv-line: color-mix(in srgb, currentColor 55%, var(--md-default-bg-color)); +} +.md-typeset svg.nj-jsonview { min-width: 34rem; max-width: 42rem; } +.nj-jsonview .nj-jsonview-c-struct { --c: var(--jv-struct); } +.nj-jsonview .nj-jsonview-c-key { --c: var(--jv-key); } +.nj-jsonview .nj-jsonview-c-str { --c: var(--jv-str); } +.nj-jsonview .nj-jsonview-c-num { --c: var(--jv-num); } +.nj-jsonview .nj-jsonview-c-dec { --c: var(--jv-dec); } +.nj-jsonview .nj-jsonview-c-own { --c: var(--jv-own); } +.nj-jsonview .nj-jsonview-c-bad { --c: var(--jv-bad); } +.nj-jsonview .nj-jsonview-c-line { --c: var(--jv-line); } + +.nj-jsonview text { fill: currentColor; font-size: 13px; } +.nj-jsonview text[class*="nj-jsonview-c-"] { fill: var(--c); } +.nj-jsonview .nj-jsonview-h { font-size: 15px; font-weight: 600; fill-opacity: .85; } +.nj-jsonview .nj-jsonview-sm2 { font-size: 14px; } +.nj-jsonview .nj-jsonview-note { font-size: 13px; fill-opacity: .75; } +.nj-jsonview .nj-jsonview-strong { font-weight: 600; fill-opacity: 1; } +.nj-jsonview .nj-jsonview-tiny { font-size: 10.5px; fill-opacity: .7; } +.nj-jsonview .nj-jsonview-mono { font-family: var(--md-code-font-family), monospace; font-size: 13px; } +.nj-jsonview .nj-jsonview-sm { font-size: 12px; } +.nj-jsonview .nj-jsonview-xs { font-size: 11px; } +.nj-jsonview .nj-jsonview-muted { fill-opacity: .75; } +.nj-jsonview .nj-jsonview-byte { font-size: 12px; } +.nj-jsonview .nj-jsonview-kind { font-size: 12.5px; font-weight: 700; } + +.nj-jsonview .nj-jsonview-box { fill: var(--md-default-bg-color); stroke: var(--jv-line); stroke-width: 1.5; } +.nj-jsonview .nj-jsonview-heap { fill: color-mix(in srgb, currentColor 7%, var(--md-default-bg-color)); stroke: var(--jv-line); stroke-width: 1.5; stroke-dasharray: 5 3; } +.nj-jsonview .nj-jsonview-ribbon { fill: color-mix(in srgb, currentColor 4%, var(--md-default-bg-color)); stroke: var(--jv-line); stroke-width: 1.2; } +.nj-jsonview .nj-jsonview-span { fill: color-mix(in srgb, var(--c) 18%, var(--md-default-bg-color)); } +.nj-jsonview .nj-jsonview-frame { fill: none; stroke: var(--jv-line); stroke-width: 1.2; stroke-dasharray: 6 4; } +.nj-jsonview .nj-jsonview-store { fill: color-mix(in srgb, var(--jv-own) 6%, var(--md-default-bg-color)); stroke: color-mix(in srgb, var(--jv-own) 55%, var(--md-default-bg-color)); stroke-width: 1.2; stroke-dasharray: 6 4; } +.nj-jsonview .nj-jsonview-node { fill: color-mix(in srgb, var(--c) 12%, var(--md-default-bg-color)); stroke: var(--c); stroke-width: 1.5; } +.nj-jsonview .nj-jsonview-node.nj-jsonview-hot { stroke-width: 3; } +.nj-jsonview .nj-jsonview-node.nj-jsonview-gap { fill: var(--md-default-bg-color); stroke: var(--jv-bad); stroke-dasharray: 4 3; } +.nj-jsonview .nj-jsonview-node.nj-jsonview-free { fill: none; stroke-dasharray: 3 3; } +.nj-jsonview .nj-jsonview-sep { stroke: var(--jv-line); stroke-width: 1; fill: none; } +.nj-jsonview .nj-jsonview-arr { stroke: var(--c); stroke-width: 1.5; fill: none; } +.nj-jsonview .nj-jsonview-dash { stroke-dasharray: 4 3; } +.nj-jsonview .nj-jsonview-head { fill: var(--c); } +.nj-jsonview .nj-jsonview-bar { fill: color-mix(in srgb, var(--jv-struct) 30%, var(--md-default-bg-color)); stroke: var(--jv-struct); stroke-width: 1.2; } +.nj-jsonview .nj-jsonview-bad { + fill: color-mix(in srgb, var(--jv-bad) 20%, var(--md-default-bg-color)); + stroke: var(--jv-bad); stroke-width: 1.2; stroke-dasharray: 4 2; +} +.nj-jsonview .nj-jsonview-evt { stroke: var(--jv-bad); stroke-width: 2; fill: none; } +.nj-jsonview .nj-jsonview-evt--ok { stroke: var(--jv-struct); stroke-dasharray: 4 3; } +.nj-jsonview .nj-jsonview-onbad, .nj-jsonview .nj-jsonview-onok { font-size: 11.5px; fill-opacity: 1; } + +/* the edit stepper: without JS all frames are shown one below the other */ +.nj-jsonview-steps { margin: 1.5rem 0; } +.md-typeset .nj-jsonview-step { display: block; width: 100%; max-width: none; margin: 0 0 1.5rem; } +.nj-jsonview-step > figcaption { + margin: .25rem 0 0; font-size: .75rem; color: var(--md-default-fg-color--light); text-align: left; + max-width: none; +} +.nj-jsonview-step > figcaption code { font-size: .95em; } +.nj-jsonview-step .nj-jsonview-scroll { overflow-x: auto; } +.md-typeset .nj-jsonview-steps.is-enhanced .nj-jsonview-step { display: none; margin: 0; } +.md-typeset .nj-jsonview-steps.is-enhanced .nj-jsonview-step.is-current { display: block; } +.nj-jsonview-controls { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 0 0 .6rem; } +.nj-jsonview-controls button { + min-height: 2.2rem; min-width: 2.2rem; padding: 0 .8rem; + font: inherit; font-size: .7rem; font-weight: 600; cursor: pointer; + color: var(--md-typeset-a-color); background: var(--md-default-bg-color); + border: 1.5px solid var(--md-typeset-a-color); border-radius: .4rem; +} +.nj-jsonview-controls button:hover:not(:disabled) { background: color-mix(in srgb, var(--md-typeset-a-color) 10%, var(--md-default-bg-color)); } +.nj-jsonview-controls button:focus-visible { outline: 2px solid var(--md-accent-fg-color); outline-offset: 2px; } +.nj-jsonview-controls button:disabled { opacity: .45; cursor: default; } +.nj-jsonview-controls button[aria-current="step"], .nj-jsonview-controls button[aria-current="step"]:hover { color: var(--md-default-bg-color); background: var(--md-typeset-a-color); } +.nj-jsonview-controls .nj-jsonview-status { font-size: .7rem; color: var(--md-default-fg-color--light); margin-left: .25rem; } +@media (max-width: 44.9375em) { + .nj-jsonview-controls button { min-height: 44px; min-width: 44px; } +} +@media (prefers-reduced-motion: no-preference) { + .nj-jsonview-steps.is-enhanced .nj-jsonview-step.is-current { animation: nj-jsonview-fade .25s ease-out; } +} +@keyframes nj-jsonview-fade { from { opacity: .3; } to { opacity: 1; } } + +/* json vs ordered_json vs editable document */ +.nj-jsonview-cmp { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem; margin: 1.2rem 0; } +.nj-jsonview-cmp > div { + border: 1px solid var(--md-default-fg-color--lightest); border-radius: .4rem; padding: .5rem .6rem .6rem; + background: var(--md-code-bg-color); min-width: 0; +} +.nj-jsonview-cmp > div.nj-jsonview-cmp--best { border-color: var(--jv-struct); } +.nj-jsonview-cmp .nj-jsonview-cmp-h { font-size: .7rem; font-weight: 600; margin: 0 0 .1rem; } +.nj-jsonview-cmp .nj-jsonview-cmp-v { font-size: .64rem; color: var(--md-default-fg-color--light); margin: 0 0 .4rem; } +.md-typeset .nj-jsonview-cmp pre { margin: 0; font-family: var(--md-code-font-family), monospace; font-size: .68rem; line-height: 1.5; white-space: pre; overflow-x: auto; background: none; color: var(--md-code-fg-color); } +.nj-jsonview-cmp .nj-jsonview-bad { color: var(--jv-bad); font-weight: 600; text-decoration: underline wavy; text-underline-offset: 3px; } +.nj-jsonview-cmp .nj-jsonview-ok { color: var(--jv-own); font-weight: 600; } +@media (max-width: 44.9375em) { + .nj-jsonview-cmp { grid-template-columns: minmax(0, 1fr); } +} diff --git a/docs/mkdocs/docs/css/fig-macros.css b/docs/mkdocs/docs/css/fig-macros.css new file mode 100644 index 000000000..07fdccd41 --- /dev/null +++ b/docs/mkdocs/docs/css/fig-macros.css @@ -0,0 +1,98 @@ +/* figures: macro chooser (js/fig-macros.js) on features/arbitrary_types.md; colours come from the brand + variables in brand.css, which switch with the light/slate scheme */ +.nj-macro-chooser { + --nj-mc-line: color-mix(in srgb, currentColor 18%, var(--md-default-bg-color)); + --nj-mc-panel: color-mix(in srgb, currentColor 3%, var(--md-default-bg-color)); + --nj-mc-ink2: var(--md-default-fg-color--light); + margin: 1.2em 0 1.6em; + font-size: .74rem; +} +.md-typeset .nj-macro-chooser .nj-mc-fallback > :first-child { margin-top: 0; } + +.nj-mc-app { border: 1px solid var(--nj-mc-line); border-radius: .3rem; background: var(--nj-mc-panel); + padding: .9rem; display: grid; grid-template-columns: minmax(0, 1fr); gap: 1rem; } +.nj-mc-form, .nj-mc-out, .nj-mc-editor, .nj-mc-members, .nj-mc-mbody { grid-template-columns: minmax(0, 1fr); } +.nj-mc-form { display: grid; gap: 1rem; margin: 0; } + +/* questions as segmented radio groups */ +.nj-mc-questions { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(14.5rem, 100%), 1fr)); gap: .7rem .9rem; } +.nj-mc-q { border: 0; margin: 0; padding: 0; min-width: 0; } +.nj-mc-q legend { font-weight: 600; padding: 0; margin-bottom: .3rem; font-size: .7rem; } +.nj-mc-seg { display: flex; border: 1px solid var(--nj-mc-line); border-radius: .25rem; overflow: hidden; + background: var(--md-default-bg-color); } +.nj-mc-seg input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; } +.nj-mc-seg label { flex: 1 1 0; display: flex; align-items: center; justify-content: center; text-align: center; + min-height: 2.1rem; padding: .25rem .5rem; cursor: pointer; line-height: 1.25; font-size: .7rem; + color: var(--md-default-fg-color); transition: background-color .15s, color .15s; } +.nj-mc-seg label + input + label { border-left: 1px solid var(--nj-mc-line); } +.nj-mc-seg label:hover { background: var(--nj-blue-soft); } +.nj-mc-seg input:checked + label { background: var(--nj-blue); color: var(--md-default-bg-color); font-weight: 600; } +.nj-mc-seg input:focus-visible + label { outline: 2px solid var(--md-accent-fg-color); outline-offset: -3px; } +.nj-mc-q:disabled .nj-mc-seg { opacity: .45; } +.nj-mc-q:disabled label { cursor: not-allowed; } +.nj-mc-q:disabled label:hover { background: transparent; } +.md-typeset .nj-mc-qnote { margin: .3rem 0 0; font-size: .64rem; line-height: 1.4; color: var(--nj-mc-ink2); } + +/* type editor */ +.nj-mc-editor { display: grid; gap: .6rem; border-top: 1px solid var(--nj-mc-line); padding-top: .9rem; } +.nj-mc-names { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr)); gap: .6rem .9rem; } +.nj-mc-field { display: grid; gap: .2rem; } +.nj-mc-field label { font-weight: 600; font-size: .7rem; } +.nj-mc-field[hidden] { display: none; } +.nj-macro-chooser input[type="text"] { font-family: var(--md-code-font-family), monospace; font-size: .7rem; + min-height: 2.1rem; padding: .2rem .45rem; min-width: 0; width: 100%; box-sizing: border-box; + border: 1px solid var(--nj-mc-line); border-radius: .2rem; background: var(--md-default-bg-color); + color: var(--md-default-fg-color); } +.nj-macro-chooser input[type="text"]:focus { outline: 2px solid var(--md-accent-fg-color); outline-offset: 0; border-color: transparent; } + +.nj-mc-members { display: grid; gap: .35rem; } +.nj-mc-mbody { display: grid; gap: .35rem; } +.nj-mc-mrow { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) 2.2rem; gap: .4rem; align-items: center; } +.nj-mc-custom .nj-mc-mrow { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr) 2.2rem; } +.nj-mc-mrow .nj-mc-keycol { display: none; } +.nj-mc-custom .nj-mc-mrow .nj-mc-keycol { display: block; } +.nj-mc-mhead { font-weight: 600; font-size: .66rem; color: var(--nj-mc-ink2); } +.nj-mc-mhead .nj-mc-keycol[hidden] { display: none; } + +.nj-macro-chooser button { font: inherit; cursor: pointer; border-radius: .2rem; } +.nj-macro-chooser button:focus-visible { outline: 2px solid var(--md-accent-fg-color); outline-offset: 2px; } +.nj-mc-rm { width: 2.2rem; height: 2.1rem; border: 1px solid var(--nj-mc-line); background: var(--md-default-bg-color); + color: var(--nj-mc-ink2); font-size: 1rem; line-height: 1; padding: 0; } +.nj-mc-rm:hover { color: var(--nj-red); border-color: var(--nj-red); } +.nj-mc-add, .nj-mc-copy { justify-self: start; min-height: 2.1rem; padding: .2rem .8rem; font-size: .7rem; font-weight: 600; + border: 1px solid var(--nj-blue); background: var(--md-default-bg-color); color: var(--nj-blue); } +.nj-mc-add:hover, .nj-mc-copy:hover { background: var(--nj-blue-soft); } + +/* output */ +.nj-mc-out { display: grid; gap: .7rem; } +.nj-mc-result { border-left: .2rem solid var(--nj-blue); background: var(--nj-blue-soft); border-radius: 0 .2rem .2rem 0; + padding: .55rem .8rem; } +.nj-mc-result.nj-mc-bad { border-left-color: var(--nj-red); background: var(--nj-red-soft); } +.md-typeset .nj-mc-result p { margin: 0; } +.md-typeset .nj-mc-result p + p { margin-top: .3rem; } +.md-typeset .nj-mc-label { font-size: .64rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--nj-mc-ink2); } +.md-typeset .nj-mc-macro code { font-size: .8rem; font-weight: 600; background: transparent; padding: 0; + overflow-wrap: anywhere; color: var(--md-default-fg-color); } +.md-typeset .nj-mc-why { line-height: 1.5; } +.md-typeset .nj-mc-hints { margin: 0; padding-left: 1.1rem; font-size: .68rem; color: var(--nj-mc-ink2); } +.md-typeset .nj-mc-hints li { margin: 0; } +.nj-mc-hints[hidden], .nj-mc-code[hidden] { display: none; } + +.nj-mc-codebar { display: flex; align-items: center; gap: .6rem; margin-bottom: .3rem; } +.nj-mc-codetitle { font-weight: 600; font-size: .7rem; margin-right: auto; } +.nj-mc-copystatus { font-size: .66rem; color: var(--nj-mc-ink2); } +.md-typeset .nj-mc-code .highlight { margin: 0; } +.md-typeset .nj-mc-code pre { margin: 0; } +.md-typeset .nj-mc-code pre > code { max-height: 34rem; } + +@media (max-width: 44.9375em) { + .nj-mc-app { padding: .7rem; } + .nj-mc-seg label, .nj-macro-chooser input[type="text"], .nj-mc-add, .nj-mc-copy { min-height: 2.75rem; } + .nj-mc-rm { width: 2.75rem; height: 2.75rem; } + .nj-mc-mrow, .nj-mc-custom .nj-mc-mrow { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 2.75rem; } + .nj-mc-custom .nj-mc-mrow .nj-mc-keycol { grid-column: 1 / 3; } + .nj-mc-custom .nj-mc-mhead { display: none; } +} +@media (prefers-reduced-motion: reduce) { + .nj-mc-seg label { transition: none; } +} diff --git a/docs/mkdocs/docs/css/fig-pointer.css b/docs/mkdocs/docs/css/fig-pointer.css new file mode 100644 index 000000000..4f03eabcc --- /dev/null +++ b/docs/mkdocs/docs/css/fig-pointer.css @@ -0,0 +1,459 @@ +/* figures: pointer (features/json_pointer.md, json_patch.md, merge_patch.md; widgets in js/fig-pointer.js) */ + +/* value types: the colours of the code highlighting (brand.css), so a string looks the same everywhere */ +.nj-pointer-walk, .nj-pointer-fl, .nj-patch { + --nj-pointer-s: var(--nj-hl-string); + --nj-pointer-n: var(--nj-hl-number); + --nj-pointer-b: var(--nj-hl-function); + --nj-pointer-line: color-mix(in srgb, var(--md-default-fg-color) 28%, var(--md-default-bg-color)); + --nj-pointer-ok: #23793a; + --nj-pointer-ok-soft: #e6f4ea; +} +[data-md-color-scheme="slate"] :is(.nj-pointer-walk, .nj-pointer-fl, .nj-patch) { + --nj-pointer-ok: #7ed491; + --nj-pointer-ok-soft: #14301d; +} + +/* ---------- pointer walker ---------- */ +.md-typeset .nj-pointer-walk { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 1rem 1.6rem; + margin: 1.5rem 0; + padding: 1rem 1.1rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 6px; + font-size: .75rem; +} +@media screen and (min-width: 45em) { + .md-typeset .nj-pointer-walk--js { + grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); + } + .md-typeset .nj-pointer-walk--js .nj-pointer-panel { order: 2; } +} +.md-typeset .nj-pointer-static { + margin: 0; + color: var(--md-default-fg-color--light); +} +.md-typeset .nj-pointer-walk code { + font-size: .95em; +} + +/* tree: elbow lines drawn by each item (::before up to its row, ::after down to the next sibling) */ +.md-typeset .nj-pointer-walk ul.nj-pointer-tree, +.md-typeset .nj-pointer-walk .nj-pointer-tree ul { + margin: 0; + padding: 0; + list-style: none; +} +.md-typeset .nj-pointer-walk .nj-pointer-tree ul { + padding-left: 1.5rem; +} +.md-typeset .nj-pointer-walk .nj-pointer-tree li { + position: relative; + margin: 0; + padding: 0; + list-style: none; + --nj-pointer-mid: .95rem; +} +.md-typeset .nj-pointer-walk .nj-pointer-tree li::before, +.md-typeset .nj-pointer-walk .nj-pointer-tree li::after { + content: none; +} +.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li::before { + content: ""; + position: absolute; + top: 0; + left: -1rem; + width: .8rem; + height: var(--nj-pointer-mid); + border: 0 solid var(--nj-pointer-line); + border-width: 0 0 2px 2px; + border-bottom-left-radius: 4px; + background: none; +} +.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li:not(:last-child)::after { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: -1rem; + border-left: 2px solid var(--nj-pointer-line); +} +.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li.is-on::before { + z-index: 1; + border-color: var(--md-typeset-a-color); +} +.md-typeset .nj-pointer-walk .nj-pointer-tree ul > li.is-pass::after { + z-index: 1; + border-left-color: var(--md-typeset-a-color); +} + +.md-typeset .nj-pointer-walk .nj-pointer-n { + display: inline-block; + margin: .15rem 0; + padding: .2rem .5rem; + border: 1px solid transparent; + border-radius: 6px; + background: none; + color: var(--md-default-fg-color); + font: inherit; + font-family: var(--md-code-font-family), monospace; + font-size: .95em; + line-height: 1.5; + text-align: left; +} +.md-typeset .nj-pointer-walk button.nj-pointer-n { + cursor: pointer; +} +.md-typeset .nj-pointer-walk button.nj-pointer-n:hover { + border-color: var(--md-default-fg-color--lightest); +} +.md-typeset .nj-pointer-walk :is(button):focus-visible { + outline: 2px solid var(--md-typeset-a-color); + outline-offset: 2px; +} +.nj-pointer-k { color: var(--nj-hl-key); } +.nj-pointer-t { + color: var(--md-default-fg-color--light); + font-family: var(--md-text-font-family), sans-serif; + font-size: .88em; + font-style: italic; +} +.nj-pointer-v--s { color: var(--nj-pointer-s); } +.nj-pointer-v--n { color: var(--nj-pointer-n); } +.nj-pointer-v--b { color: var(--nj-pointer-b); } + +.md-typeset .nj-pointer-walk li.is-on > .nj-pointer-n { + border-color: color-mix(in srgb, var(--md-typeset-a-color) 45%, transparent); +} +.md-typeset .nj-pointer-walk li.is-target > .nj-pointer-n { + border-color: var(--md-typeset-a-color); + background-color: var(--nj-blue-soft); + box-shadow: 0 0 0 1px var(--md-typeset-a-color); +} +/* the value a container pointer identifies includes its subtree */ +.md-typeset .nj-pointer-walk li.is-target li > .nj-pointer-n { + background-color: var(--nj-blue-soft); +} +.md-typeset .nj-pointer-walk li.is-miss > .nj-pointer-n { + border-color: var(--nj-red); + border-style: dashed; +} + +/* panel: pointer bar, result, example pointers */ +.nj-pointer-lbl { + margin: 0 0 .35rem; + color: var(--md-default-fg-color--light); + font-size: .62rem; + font-weight: 600; + letter-spacing: .04em; + text-transform: uppercase; +} +.nj-pointer-lbl span { + font-weight: 500; + letter-spacing: 0; + text-transform: none; +} +.nj-pointer-bar { + display: flex; + flex-wrap: wrap; + margin-bottom: .6rem; +} +.md-typeset .nj-pointer-seg { + margin: 0 -1px 0 0; + padding: .3rem .55rem; + border: 1px solid var(--md-typeset-a-color); + background-color: var(--md-default-bg-color); + color: var(--md-typeset-a-color); + cursor: pointer; + font: inherit; +} +.md-typeset .nj-pointer-seg:first-child { border-radius: 6px 0 0 6px; } +.md-typeset .nj-pointer-seg:last-child { border-radius: 0 6px 6px 0; } +.md-typeset .nj-pointer-seg:only-child { border-radius: 6px; } +.md-typeset .nj-pointer-seg code { color: inherit; font-size: 1em; } +.md-typeset .nj-pointer-seg--root code { color: var(--md-default-fg-color--light); } +.md-typeset .nj-pointer-seg.is-after { + border-color: var(--md-default-fg-color--lighter); + color: var(--md-default-fg-color--light); + border-style: dashed; +} +.md-typeset .nj-pointer-seg[aria-pressed="true"] { + position: relative; + background-color: var(--md-typeset-a-color); + color: var(--md-default-bg-color); +} +.md-typeset .nj-pointer-seg--root[aria-pressed="true"] code { color: inherit; } +.nj-pointer-out { + min-height: 3.2em; + margin-bottom: .9rem; + padding: .5rem .7rem; + border-left: 3px solid var(--md-typeset-a-color); + border-radius: 0 6px 6px 0; + background-color: var(--md-code-bg-color); + line-height: 1.6; + overflow-wrap: anywhere; +} +.md-typeset .nj-pointer-out .nj-pointer-val { color: var(--md-typeset-a-color); font-weight: 600; } +.nj-pointer-out .nj-pointer-note { color: var(--md-default-fg-color--light); } +.nj-pointer-out .nj-pointer-err { color: var(--nj-red); font-weight: 600; } +.nj-pointer-presets { + display: flex; + flex-wrap: wrap; + gap: .35rem; +} +.md-typeset .nj-pointer-chip { + padding: .2rem .5rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 6px; + background-color: var(--md-default-bg-color); + color: var(--md-default-fg-color); + cursor: pointer; + font: inherit; +} +.md-typeset .nj-pointer-chip:hover { border-color: var(--md-typeset-a-color); } +.md-typeset .nj-pointer-chip[aria-pressed="true"] { + border-color: var(--md-typeset-a-color); + background-color: var(--nj-blue-soft); + color: var(--md-typeset-a-color); +} +.md-typeset .nj-pointer-chip code { color: inherit; font-size: 1em; } +@media (pointer: coarse), screen and (max-width: 44.984375em) { + .md-typeset :is(.nj-pointer-seg, .nj-pointer-chip, .nj-patch-btn) { min-height: 44px; min-width: 44px; } + .md-typeset .nj-pointer-walk button.nj-pointer-n { min-height: 40px; } +} + +/* ---------- flatten / unflatten figure (scripts/figures/json_pointer_flatten.py) ---------- */ +.md-typeset svg.nj-pointer-fl { min-width: 28rem; max-width: 44rem; } +.nj-pointer-fl .nj-pointer-fl-edge { fill: none; stroke: var(--fg-line); stroke-width: 1.5; } +.nj-pointer-fl .nj-pointer-fl-link { fill: none; stroke-width: 1.5; stroke-opacity: .75; } +.nj-pointer-fl .nj-pointer-fl-link.nj-pointer-fl--s, .nj-pointer-fl .nj-pointer-fl-dot.nj-pointer-fl--s { stroke: var(--nj-pointer-s); } +.nj-pointer-fl .nj-pointer-fl-link.nj-pointer-fl--n, .nj-pointer-fl .nj-pointer-fl-dot.nj-pointer-fl--n { stroke: var(--nj-pointer-n); } +.nj-pointer-fl .nj-pointer-fl-link.nj-pointer-fl--b, .nj-pointer-fl .nj-pointer-fl-dot.nj-pointer-fl--b { stroke: var(--nj-pointer-b); } +.nj-pointer-fl .nj-pointer-fl-dot { fill: var(--md-default-bg-color); stroke-width: 2; } +.nj-pointer-fl tspan.nj-pointer-fl--s { fill: var(--nj-pointer-s); } +.nj-pointer-fl tspan.nj-pointer-fl--n { fill: var(--nj-pointer-n); } +.nj-pointer-fl tspan.nj-pointer-fl--b { fill: var(--nj-pointer-b); } +.nj-pointer-fl .nj-pointer-fl-k, .nj-pointer-fl .nj-pointer-fl-inner, .nj-pointer-fl .nj-pointer-fl-key { fill: var(--nj-hl-key); } +.nj-pointer-fl .nj-pointer-fl-op { + fill: var(--md-typeset-a-color); + font-family: var(--md-code-font-family), monospace; + font-size: 15px; + font-weight: 600; + text-anchor: middle; +} + +/* ---------- JSON Patch stepper ---------- */ +.md-typeset .nj-patch--js .md-typeset__scrollwrap, +.md-typeset .nj-patch--js > .md-typeset__table, +.md-typeset .nj-patch--js > table { + display: none; +} +.md-typeset .nj-patch-stage { + margin: 1.5rem 0; + padding: 1rem 1.1rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 6px; + font-size: .75rem; +} +.nj-patch-cols { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: 1rem 1.4rem; +} +@media screen and (min-width: 50em) { + .nj-patch-cols { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); } +} +.nj-patch-h { + margin: 0 0 .35rem; + color: var(--md-default-fg-color--light); + font-size: .62rem; + font-weight: 600; + letter-spacing: .04em; + text-transform: uppercase; +} +.nj-patch-doc { + --nj-patch-lh: 1.9rem; + --nj-patch-pad: .5rem; + position: relative; + padding: var(--nj-patch-pad) .6rem var(--nj-patch-pad) 2rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 6px; + background-color: var(--md-code-bg-color); + font-family: var(--md-code-font-family), monospace; + font-size: .95em; +} +.nj-patch-line { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0 .6rem; + min-height: var(--nj-patch-lh); + margin: 0 -.3rem; + padding: 0 .3rem; + border-radius: 4px; + white-space: pre; +} +.nj-patch-code { white-space: pre; } +.nj-patch-k { color: var(--nj-hl-key); } +.nj-patch-s { color: var(--nj-pointer-s); } +.nj-patch-note { + padding: 0 .4rem; + border-radius: 4px; + font-family: var(--md-text-font-family), sans-serif; + font-size: .82em; + font-weight: 600; + white-space: nowrap; +} +.nj-patch-line--add { background-color: var(--nj-pointer-ok-soft); box-shadow: inset 3px 0 0 var(--nj-pointer-ok); } +.nj-patch-line--add .nj-patch-note { color: var(--nj-pointer-ok); } +.nj-patch-line--del { background-color: var(--nj-red-soft); box-shadow: inset 3px 0 0 var(--nj-red); } +.nj-patch-line--del .nj-patch-code { text-decoration: line-through; text-decoration-color: var(--nj-red); text-decoration-thickness: 2px; opacity: .75; } +.nj-patch-line--del .nj-patch-note { color: var(--nj-red); } +.nj-patch-line--mod .nj-patch-note { color: var(--nj-pointer-ok); } +.nj-patch-line--test { background-color: var(--nj-blue-soft); box-shadow: inset 3px 0 0 var(--md-typeset-a-color); } +.nj-patch-line--test .nj-patch-note { color: var(--md-typeset-a-color); } +.nj-patch-ins { padding: .05rem .15rem; border-radius: 3px; background-color: var(--nj-pointer-ok-soft); box-shadow: 0 0 0 1.5px var(--nj-pointer-ok); } +.nj-patch-src { padding: .05rem .15rem; border-radius: 3px; box-shadow: 0 0 0 1.5px var(--md-typeset-a-color); } + +/* move/copy connector in the left gutter: a bracket from the source line to the target line */ +.nj-patch-arc { + position: absolute; + left: .55rem; + width: .8rem; + border: 2px solid var(--md-typeset-a-color); + border-right: 0; + border-radius: 6px 0 0 6px; +} +.nj-patch-arc::after { + content: ""; + position: absolute; + right: -2px; + border: 5px solid transparent; + border-left: 7px solid var(--md-typeset-a-color); +} +.nj-patch-arc--down::after { bottom: -6px; } +.nj-patch-arc--up::after { top: -6px; } + +.md-typeset .nj-patch-ops { + margin: 0; + padding: 0; + list-style: none; + counter-reset: nj-patch; +} +.md-typeset .nj-patch-ops > li { + position: relative; + margin: 0 0 .3rem; + padding: .35rem .5rem .35rem 2rem; + border: 1px solid transparent; + border-radius: 6px; + counter-increment: nj-patch; + line-height: 1.5; +} +.md-typeset .nj-patch-ops > li::before { + content: counter(nj-patch); + position: absolute; + top: .35rem; + left: .6rem; + color: var(--md-default-fg-color--lighter); + font-weight: 600; + font-variant-numeric: tabular-nums; +} +.md-typeset .nj-patch-ops code { font-size: .9em; overflow-wrap: anywhere; } +.md-typeset .nj-patch-ops > li.is-done { opacity: .6; } +.md-typeset .nj-patch-ops > li.is-cur { + border-color: var(--md-typeset-a-color); + background-color: var(--nj-blue-soft); +} +.md-typeset .nj-patch-ops > li.is-cur::before { color: var(--md-typeset-a-color); } +.nj-patch-op { color: var(--nj-hl-keyword); font-weight: 600; } +.nj-patch-path { color: var(--nj-pointer-s); } +.md-typeset .nj-patch-ops > li.is-cur .nj-patch-path { + padding: 0 .15rem; + border-radius: 3px; + background-color: var(--md-typeset-a-color); + color: var(--md-default-bg-color); +} +.nj-patch-ctrl { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: .4rem; + margin-top: .9rem; +} +.md-typeset .nj-patch-btn { + padding: .3rem .9rem; + border: 1px solid var(--md-default-fg-color--lighter); + border-radius: 6px; + background-color: var(--md-default-bg-color); + color: var(--md-default-fg-color); + cursor: pointer; + font: inherit; + font-weight: 600; +} +.md-typeset .nj-patch-btn--primary { + border-color: var(--md-typeset-a-color); + background-color: var(--md-typeset-a-color); + color: var(--md-default-bg-color); +} +.md-typeset .nj-patch-btn:disabled { opacity: .45; cursor: default; } +.md-typeset .nj-patch-btn:focus-visible { outline: 2px solid var(--md-typeset-a-color); outline-offset: 2px; } +.nj-patch-count { + margin-left: auto; + color: var(--md-default-fg-color--light); + font-variant-numeric: tabular-nums; +} +.md-typeset .nj-patch-status { + min-height: 3.2em; + margin: .6rem 0 0; + color: var(--md-default-fg-color--light); +} +@media (prefers-reduced-motion: no-preference) { + .nj-patch-doc--anim :is(.nj-patch-line--add, .nj-patch-line--del, .nj-patch-line--test, .nj-patch-ins, .nj-patch-arc) { + animation: nj-patch-in 450ms ease-out; + } +} +@keyframes nj-patch-in { + from { opacity: 0; transform: translateX(-.4rem); } + to { opacity: 1; transform: none; } +} + +/* ---------- merge patch table ---------- */ +.nj-pointer-mpt { + --nj-pointer-mp-set: var(--nj-hl-keyword); + --nj-pointer-mp-add: #23793a; + --nj-pointer-mp-del: var(--nj-red); + --nj-pointer-mp-rec: var(--nj-hl-function); + --nj-pointer-mp-arr: var(--nj-hl-number); + --nj-pointer-mp-keep: var(--md-default-fg-color--light); +} +[data-md-color-scheme="slate"] .nj-pointer-mpt { --nj-pointer-mp-add: #7ed491; } +.md-typeset .nj-pointer-mpt td { vertical-align: top; } +.md-typeset .nj-pointer-mpt td:first-child { white-space: nowrap; } +.nj-pointer-mp { + display: inline-block; + padding: .05rem .5rem; + border: 1px solid currentColor; + border-radius: 999px; + background-color: color-mix(in srgb, currentColor 10%, var(--md-default-bg-color)); + font-size: .92em; + font-weight: 600; + line-height: 1.5; + white-space: nowrap; +} +.nj-pointer-mp--set { color: var(--nj-pointer-mp-set); } +.nj-pointer-mp--add { color: var(--nj-pointer-mp-add); } +.nj-pointer-mp--del { color: var(--nj-pointer-mp-del); } +.nj-pointer-mp--rec { color: var(--nj-pointer-mp-rec); } +.nj-pointer-mp--arr { color: var(--nj-pointer-mp-arr); } +.nj-pointer-mp--keep { color: var(--nj-pointer-mp-keep); } +.nj-pointer-mp-none { color: var(--md-default-fg-color--light); font-style: italic; } +.md-typeset .nj-pointer-mpt table:not([class]) td code { white-space: normal; } +.md-typeset .nj-pointer-mpt table:not([class]) td:nth-child(-n+2) code { white-space: nowrap; } +/* the result cell takes a tint of the rule's colour */ +.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--set) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-set) 8%, transparent); } +.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--add) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-add) 8%, transparent); } +.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--del) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-del) 8%, transparent); } +.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--rec) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-rec) 8%, transparent); } +.md-typeset .nj-pointer-mpt tr:has(.nj-pointer-mp--arr) td:last-child { background-color: color-mix(in srgb, var(--nj-pointer-mp-arr) 8%, transparent); } diff --git a/docs/mkdocs/docs/css/fig-sax.css b/docs/mkdocs/docs/css/fig-sax.css new file mode 100644 index 000000000..2b8bd645c --- /dev/null +++ b/docs/mkdocs/docs/css/fig-sax.css @@ -0,0 +1,207 @@ +/* figures: sax (SAX event stepper on features/parsing/sax_interface.md, js/fig-sax.js; memory_over_time.svg and + chunk_buffering.svg on features/parsing/large_and_partial_input.md). Event colours are the --cb-* variables of the + parser-callback figure in brand.css, which .nj-fig provides. */ + +/* ---------- stepper ---------- */ +.md-typeset .nj-sax { + display: grid; + grid-template-columns: minmax(0, 1fr); + gap: .9rem 1.4rem; + margin: 1.5rem 0; + padding: 1rem 1.1rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 8px; + background: var(--md-default-bg-color); + font-size: .74rem; +} +@media screen and (min-width: 45em) { + .md-typeset .nj-sax { + grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); + grid-template-areas: "ctl ctl" "text text" "ev state" "status status"; + } + .md-typeset .nj-sax > .nj-sax__controls { grid-area: ctl; } + .md-typeset .nj-sax > .nj-sax__lane--text { grid-area: text; } + .md-typeset .nj-sax > .nj-sax__lane--events { grid-area: ev; } + .md-typeset .nj-sax > .nj-sax__lane--state { grid-area: state; } + .md-typeset .nj-sax > .nj-sax__status { grid-area: status; } +} +.md-typeset .nj-sax p { margin: 0; } +.md-typeset .nj-sax .nj-sax__h { + margin: 0 0 .45rem; + color: var(--md-default-fg-color--light); + font-size: .68rem; + font-weight: 600; + letter-spacing: .02em; +} +.md-typeset .nj-sax .nj-sax__h code { font-size: .95em; } +.md-typeset .nj-sax .nj-sax__text code { + display: inline-block; + max-width: 100%; + overflow-x: auto; + padding: .35rem .6rem; + font-size: .95rem; + white-space: pre; + word-break: normal; +} +.nj-sax .nj-sax-unread { color: var(--md-default-fg-color--light); } +.nj-sax .nj-sax-unread--never { color: var(--md-default-fg-color--lighter); text-decoration: line-through; text-decoration-color: var(--md-default-fg-color--lighter); } +.nj-sax .nj-sax-read { color: var(--md-code-fg-color); } +.nj-sax .nj-sax-tok { border-radius: 3px; box-shadow: inset 0 -3px 0 var(--nj-sax-ev, var(--cb-v)); background: color-mix(in srgb, var(--nj-sax-ev, var(--cb-v)) 22%, transparent); } +.nj-sax .nj-sax-tok--os, .nj-sax .nj-sax-ev--os { --nj-sax-ev: var(--cb-os); } +.nj-sax .nj-sax-tok--oe, .nj-sax .nj-sax-ev--oe { --nj-sax-ev: var(--cb-oe); } +.nj-sax .nj-sax-tok--k, .nj-sax .nj-sax-ev--k { --nj-sax-ev: var(--cb-k); } +.nj-sax .nj-sax-tok--as, .nj-sax .nj-sax-ev--as { --nj-sax-ev: var(--cb-as); } +.nj-sax .nj-sax-tok--ae, .nj-sax .nj-sax-ev--ae { --nj-sax-ev: var(--cb-ae); } +.nj-sax .nj-sax-tok--v, .nj-sax .nj-sax-ev--v { --nj-sax-ev: var(--cb-v); } + +/* event ticker */ +.md-typeset .nj-sax ol.nj-sax__events { + margin: 0; + padding: 0; + list-style: none; + counter-reset: nj-sax; +} +.md-typeset .nj-sax ol.nj-sax__events > li { + position: relative; + margin: 0 0 .2rem; + padding: .12rem .4rem .12rem 2.6rem; + border-radius: 5px; + counter-increment: nj-sax; + line-height: 1.5; +} +.md-typeset .nj-sax ol.nj-sax__events > li::before { + content: counter(nj-sax); + position: absolute; + left: .35rem; + top: .2rem; + width: 1.1rem; + color: var(--md-default-fg-color--lighter); + font-size: .64rem; + font-variant-numeric: tabular-nums; + text-align: right; +} +.md-typeset .nj-sax ol.nj-sax__events > li::after { + content: ""; + position: absolute; + left: 1.75rem; + top: 50%; + width: .55rem; + height: .55rem; + margin-top: -.275rem; + border-radius: 50%; + background: var(--nj-sax-ev); +} +.md-typeset .nj-sax ol.nj-sax__events code { background: none; padding: 0; font-size: .8rem; } +.nj-sax .nj-sax-ev--todo { opacity: .42; } +.nj-sax .nj-sax-ev--skip { opacity: .42; text-decoration: line-through; } +.nj-sax .nj-sax-ev--skip::after { background: var(--md-default-fg-color--lighter) !important; } +.nj-sax .nj-sax-ev--cur { background: color-mix(in srgb, var(--nj-sax-ev) 16%, transparent); } +.md-typeset .nj-sax .nj-sax-ev--false > code::after { + content: " \2192 false"; + color: var(--nj-red); + font-weight: 600; +} + +/* handler state */ +.md-typeset .nj-sax pre.nj-sax__tree { margin: 0 0 .6rem; } +.md-typeset .nj-sax pre.nj-sax__tree > code { padding: .5rem .7rem; font-size: .76rem; line-height: 1.45; } +.nj-sax .nj-sax-hit { border-radius: 3px; background: color-mix(in srgb, var(--nj-blue) 22%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--nj-blue) 55%, transparent); } +.nj-sax .nj-sax-dim { color: var(--md-default-fg-color--lighter); } +.md-typeset .nj-sax .nj-sax__stackh { margin: 0 0 .3rem; color: var(--md-default-fg-color--light); font-size: .66rem; font-weight: 600; } +.md-typeset .nj-sax ol.nj-sax__stack { + display: flex; + flex-direction: column-reverse; + gap: .25rem; + margin: 0 0 .6rem; + padding: 0; + list-style: none; +} +.md-typeset .nj-sax ol.nj-sax__stack > li { + margin: 0; + padding: .2rem .5rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-left: 3px solid var(--nj-blue); + border-radius: 4px; +} +.md-typeset .nj-sax ol.nj-sax__stack > li.nj-sax-dim { border-left-color: var(--md-default-fg-color--lightest); } +.md-typeset .nj-sax ol.nj-sax__stack code { background: none; padding: 0; } +.md-typeset .nj-sax .nj-sax__note { color: var(--md-default-fg-color--light); font-size: .75rem; line-height: 1.5; } +.md-typeset .nj-sax dl.nj-sax__kv { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: .35rem .8rem; + margin: 0 0 .6rem; +} +.md-typeset .nj-sax dl.nj-sax__kv dt { color: var(--md-default-fg-color--light); font-weight: 600; } +.md-typeset .nj-sax dl.nj-sax__kv dd { margin: 0; } + +/* controls */ +.nj-sax .nj-sax__controls { display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: center; } +.nj-sax .nj-sax__btns, .nj-sax .nj-sax__modes { display: flex; flex-wrap: wrap; gap: .35rem; } +.nj-sax .nj-sax__modes { margin-left: auto; } +.md-typeset .nj-sax .nj-sax-btn { + min-height: 2.2rem; + padding: .3rem .8rem; + border: 1px solid color-mix(in srgb, var(--nj-blue) 55%, var(--md-default-bg-color)); + border-radius: 6px; + background: var(--md-default-bg-color); + color: var(--nj-blue); + font: inherit; + font-weight: 600; + cursor: pointer; +} +.md-typeset .nj-sax .nj-sax-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--nj-blue) 10%, var(--md-default-bg-color)); } +.md-typeset .nj-sax .nj-sax-btn--main, .md-typeset .nj-sax .nj-sax-btn[aria-pressed="true"] { + border-color: var(--nj-band); + background: var(--nj-band); + color: #fff; +} +.md-typeset .nj-sax .nj-sax-btn--main:hover:not(:disabled), .md-typeset .nj-sax .nj-sax-btn[aria-pressed="true"]:hover { + background: var(--md-primary-fg-color--light); +} +.md-typeset .nj-sax .nj-sax-btn:disabled { opacity: .4; cursor: default; } +.md-typeset .nj-sax .nj-sax-btn:focus-visible, .nj-sax .nj-sax__stop input:focus-visible { + outline: 2px solid var(--nj-blue); + outline-offset: 2px; +} +.nj-sax .nj-sax__stop { display: inline-flex; gap: .45rem; align-items: center; min-height: 2.2rem; cursor: pointer; } +.nj-sax .nj-sax__stop input { width: 1.05rem; height: 1.05rem; margin: 0; accent-color: var(--nj-red); } +.nj-sax .nj-sax__stop:has(input:disabled) { opacity: .45; cursor: default; } +.md-typeset .nj-sax .nj-sax__status { + padding-top: .6rem; + border-top: 1px solid var(--md-default-fg-color--lightest); + color: var(--md-default-fg-color--light); + font-size: .72rem; + min-height: 2.6em; +} +@media screen and (max-width: 44.984375em) { + .md-typeset .nj-sax { padding: .8rem; } + .md-typeset .nj-sax .nj-sax-btn { min-height: 44px; min-width: 44px; } + .nj-sax .nj-sax__stop { min-height: 44px; } + .nj-sax .nj-sax__modes { margin-left: 0; } +} +@media (prefers-reduced-motion: no-preference) { + .nj-sax .nj-sax__events > li { transition: opacity .2s, background-color .2s; } +} + +/* ---------- static SVG figures ---------- */ +.md-typeset svg.nj-fig--sax-mem { min-width: 34rem; max-width: 40rem; } +.md-typeset svg.nj-fig--sax-buf { min-width: 36rem; max-width: 42rem; } +.nj-fig .nj-sax-axis { fill: none; stroke: var(--fg-line); stroke-width: 1.5; } +.nj-fig .nj-sax-illus { font-style: italic; } +.nj-fig .nj-sax-curve { fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; } +.nj-fig .nj-sax-c-dom { --nj-sax-c: var(--nj-red); } +.nj-fig .nj-sax-c-doc { --nj-sax-c: var(--nj-hl-type); } +.nj-fig .nj-sax-c-cb { --nj-sax-c: var(--nj-hl-number); } +.nj-fig .nj-sax-c-sax { --nj-sax-c: var(--nj-blue); } +.nj-fig .nj-sax-curve.nj-sax-c-doc { stroke-dasharray: 9 5; } +.nj-fig .nj-sax-curve { stroke: var(--nj-sax-c); } +.nj-fig .nj-sax-lab { fill: var(--nj-sax-c); font-size: 14.5px; font-weight: 700; } +.nj-fig .nj-sax-old { fill: color-mix(in srgb, currentColor 10%, var(--md-default-bg-color)); } +.nj-fig .nj-sax-new { fill: color-mix(in srgb, var(--md-typeset-a-color) 18%, var(--md-default-bg-color)); stroke: var(--md-typeset-a-color); stroke-width: 1; } +.nj-fig .nj-sax-buf { fill: currentColor; font-family: var(--md-code-font-family), monospace; font-size: 14px; white-space: pre; } +.nj-fig .nj-sax-sep { stroke: var(--fg-line); stroke-width: 1; stroke-dasharray: 3 3; } +.nj-fig .nj-sax-status { font-size: 14px; font-weight: 600; } +.nj-fig .nj-sax-s-wait { fill: var(--nj-blue); } +.nj-fig .nj-sax-s-ok { fill: var(--nj-hl-string); } +.nj-fig .nj-sax-s-err { fill: var(--nj-red); } diff --git a/docs/mkdocs/docs/css/fonts/Inter-Italic.woff2 b/docs/mkdocs/docs/css/fonts/Inter-Italic.woff2 new file mode 100644 index 000000000..b3530f3f5 Binary files /dev/null and b/docs/mkdocs/docs/css/fonts/Inter-Italic.woff2 differ diff --git a/docs/mkdocs/docs/css/fonts/Inter.woff2 b/docs/mkdocs/docs/css/fonts/Inter.woff2 new file mode 100644 index 000000000..21d9a7f9e Binary files /dev/null and b/docs/mkdocs/docs/css/fonts/Inter.woff2 differ diff --git a/docs/mkdocs/docs/css/fonts/JetBrainsMono-Italic.woff2 b/docs/mkdocs/docs/css/fonts/JetBrainsMono-Italic.woff2 new file mode 100644 index 000000000..d60c270e8 Binary files /dev/null and b/docs/mkdocs/docs/css/fonts/JetBrainsMono-Italic.woff2 differ diff --git a/docs/mkdocs/docs/css/fonts/JetBrainsMono.woff2 b/docs/mkdocs/docs/css/fonts/JetBrainsMono.woff2 new file mode 100644 index 000000000..6b604cec6 Binary files /dev/null and b/docs/mkdocs/docs/css/fonts/JetBrainsMono.woff2 differ diff --git a/docs/mkdocs/docs/css/pattern-on-blue.svg b/docs/mkdocs/docs/css/pattern-on-blue.svg new file mode 100644 index 000000000..1c3c16de3 --- /dev/null +++ b/docs/mkdocs/docs/css/pattern-on-blue.svg @@ -0,0 +1 @@ + diff --git a/docs/mkdocs/docs/examples/bjdata_version_t.cpp b/docs/mkdocs/docs/examples/bjdata_version_t.cpp new file mode 100644 index 000000000..77660a0a1 --- /dev/null +++ b/docs/mkdocs/docs/examples/bjdata_version_t.cpp @@ -0,0 +1,33 @@ +#includeDecision tree for choosing a `NLOHMANN_DEFINE_*` macro: answer the questions from top to bottom; each answer picks one part of the macro name, and the parts are combined in this order. The table below lists the resulting macros.
+ | Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | |------------------------------------------------------------------|------------------------------------------------------------------|------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------| |Macros for classes and structs without a base class. A green check means yes, a red cross means no, and a grey skip sign means the column does not apply, as a macro that only serializes never reads values.
+ For _derived_ classes and structs, use the following macros | Need access to private members | Need only serialization | Allow missing values when de-serializing | macro | @@ -164,12 +168,33 @@ For _derived_ classes and structs, use the following macros |Macros for derived classes and structs, read as Table 1.
+ !!! info "Implementation limits" - The current macro implementations are limited to at most 63 member variables. If you want to serialize/deserialize types with more than 63 member variables, you need to define the `to_json`/`from_json` functions manually. - For the `WITH_NAMES` variants the limit is halved to 31 member variables. +To pick the macro for your own type and get code to start from, answer the questions below. + +Macro chooser: each answer selects one part of the macro name; the generated program defines the type, calls the macro and converts a value to JSON and back. Combinations that no macro supports show the alternative instead of code.
+ ??? example "Example: using the `NLOHMANN_DEFINE_TYPE_*` macros" The `to_json`/`from_json` functions for the `person` struct above can be created with: @@ -250,7 +275,7 @@ For _derived_ classes and structs, use the following macros The `NLOHMANN_DEFINE_TYPE_*`/`NLOHMANN_DEFINE_DERIVED_TYPE_*` macros are generic over any `basic_json` specialization, including `nlohmann::ordered_json`. Simply use `ordered_json` as the target type and members - are serialized in declaration order -- no separate macro or extra code is needed. + are serialized in declaration order — no separate macro or extra code is needed. ```cpp namespace ns { @@ -283,7 +308,7 @@ For _derived_ classes and structs, use the following macros There is currently no `NLOHMANN_DEFINE_TYPE_*`-style macro for types that are not [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible). This is not an - intentional omission of documentation -- no such macro exists yet; see + intentional omission of documentation — no such macro exists yet; see [How can I use `get()` for non-default constructible/non-copyable types?](#how-can-i-use-get-for-non-default-constructiblenon-copyable-types) for the manual pattern to use instead. @@ -299,6 +324,8 @@ flowchart LR B -->|"user specialization replaces the default"| E["user's adl_serializer specialization for T"] ``` +How a conversion between `json` and a type `T` is dispatched: the default `adl_serializer` calls the free `to_json`/`from_json` functions found by argument-dependent lookup, while a user specialization of `adl_serializer` replaces this path.
+ The library uses **JSON Serializers** to convert types to JSON. The default serializer for `nlohmann::json` is `nlohmann::adl_serializer` (ADL means [Argument-Dependent Lookup](https://en.cppreference.com/w/cpp/language/adl)). @@ -438,7 +465,7 @@ For smart pointers, class hierarchies, `std::variant`, and `std::chrono`, see ## Why can't I convert to/from `std::any`? `std::any` is intentionally excluded from `get| JSON | Bytes | Meaning |
|---|---|---|
{ | 8A | object with 4 members |
"id": 300, | 69 64 C4 04 | key: UTF-8 bytes; the string ends at the next byte, which cannot continue a UTF-8 character; value: 2-byte positive integer (lead byte, then a byte below 0x80) |
"id": 300, | 69 64 C4 04 | key: UTF-8 bytes; the string ends at 0xC4, because the byte after it (0x04) is not a UTF-8 continuation byte, so 0xC4 starts an integer; value: 2-byte positive integer (lead byte, then a byte below 0x80) |
"name": "json", | 6E 61 6D 65 FF 6A 73 6F 6E FF | key: UTF-8 bytes; 0xFF terminates the string as another string follows; value: UTF-8 bytes; terminated as a string key follows |
"pi": 3.14, | 70 69 8F 40 09 1E B8 51 EB 85 1F | key: UTF-8 bytes; value: binary64 (IEEE 754, big-endian); its marker also ends "pi" |
"tags": [ | 74 61 67 73 82 | key: UTF-8 bytes; value: array with 2 elements; its marker also ends "tags" |