Compare commits

..
Author SHA1 Message Date
Niels Lohmann 02d05057a5 docs: macro chooser generates adl_serializer for non-default-constructible types
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-26 11:17:22 +01:00
Niels Lohmann 444dba381f docs: add figures, table captions and a macro chooser
- Figures with numbered captions: SAX stepper, json_view layout and edit
  stepper, exception map, JSON pointer and patch walkers, QA pipeline,
  scaling and binary size charts, roadmap lanes, release timeline,
  integration decision tree and namespace builder
- Table captions (nj-table-caption) on 9 pages
- Compile times: modules and PCH charts, filesystem section, re-measured
  Figure 1, links between features/modules.md and compile_times.md
- Interactive macro chooser for features/arbitrary_types.md
- Link check: exclude URLs that answer the plugin with 400/401/419 or are
  dead (customers.md)

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-26 10:42:00 +01:00
Niels Lohmann 44f1bec789 docs: new design for the documentation site
Apply the brand to the Material for MkDocs site: Inter and JetBrains Mono
served by the site (upright and real italic), brand colours, blue header band
with the syntax pattern, wordmark in the header, new home page (hero, cards,
animated feature tour), 404 page, polish for tabs, search, footer, focus
rings, tables and code blocks, and theme features (code copy, previous/next
footer, TOC follow, search suggestions).

Draw the number railroad diagram, the parser callback events and the iterator
illustrations as inline SVGs that follow the light and dark scheme. The
generator scripts are in docs/mkdocs/scripts/figures; the feature slideshow
(json-light.svg, json-dark.svg, replacing json.gif on the home page) is built
by docs/mkdocs/scripts/slideshow. Decision nodes in five flowcharts become
hexagons, which need far less room.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 20:40:26 +01:00
Niels Lohmann 2a56afc714 Fix VS 2015 build of the DOM parser (#5882) (#5916)
- Name std::hash only once the object type has emplace_new_key: VS 2015
  static-asserts on std::hash of a type without one (alt_string) instead of
  reporting a substitution failure (C2338).
- Replace the std::copy calls on frames by loops: VS 2015 reports raw
  pointers handed to std::copy as C4996, an error under /WX.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 12:08:58 +01:00
Niels Lohmann d176d8d61e Exclude single_include from flawfinder scan (#5912)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 12:08:36 +01:00
Niels Lohmann 1cf5492bcd docs: byte layout sections, glossary entries, and QA page update (#5910)
* docs: byte layout sections, glossary, and QA page updates

- Move "Byte layout" of each binary format to its own section before
  "Serialization" and describe the idea of the format.
- Glossary: add LLDB and other terms used throughout the documentation.
- quality_assurance: correct Clang Static Analyzer and CMake entries; add
  CodeQL, Semgrep, Flawfinder, CIFuzz, OpenSSF Scorecard, REUSE, Meson/SwiftPM,
  and reproducibility checks.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* docs: drop unused length colour from CBOR and MessagePack byte layout legends

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 12:08:14 +01:00
Niels Lohmann 330fbead59 Document clang-tidy exclusions, drop unneeded ones, and clean up doc examples (#5909)
* Document clang-tidy exclusions and drop unneeded ones

Re-enable every excluded check in a run of clang-tidy 22 over all tests
and remove the seven that never fire (cert-err58-cpp,
clang-analyzer-webkit.NoUncountedMemberChecker,
cppcoreguidelines-virtual-class-destructor, google-readability-function-size,
hicpp-function-size, hicpp-no-assembler, readability-function-size).

Document the reason for every remaining exclusion at the top of the file.

Exclude in advance the checks that only exist in clang-tidy 23 and are
noise here (bugprone-signed-bitwise, *-explicit-constructor,
readability-trailing-comma, modernize-use-string-view), plus
modernize-use-integer-sign-comparison, which needs C++20 std::cmp_less
and flags deliberate casts.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Fix clang-tidy findings in documentation examples and replace redundant aliases

Apply clang-tidy fixes to the documentation examples:
- performance-avoid-endl: std::endl -> '\n'
- readability-qualified-auto: auto -> auto* / const auto*
- performance-for-range-copy: copy -> const reference
- google-readability-casting: C-style cast -> static_cast

Replace redundant aliases (readability-redundant-qualified-alias) such as
"using json = nlohmann::json;" with "using nlohmann::json;" in the
documentation, README, examples, tests, and benchmarks. Aliases at class
scope and aliases of other types (with_base_class_t etc.) are kept.

No changes to the library or its public API. All changed examples were
compiled and run; their output matches the stored .output files (except
max_size and meta, which depend on the platform and compiler).

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* Format doc examples with the pinned astyle

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 12:07:51 +01:00
Niels Lohmann fe231dc692 docs: write std::chrono durations as unit/value objects; reword a title with escaped quotes (#5911)
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 12:07:32 +01:00
Niels Lohmann ffd4242dc2 Docs: fill documentation gaps found in user questions (#5907)
* Docs: fill documentation gaps found in user questions

Add pages on class-hierarchy/smart-pointer/variant/chrono recipes, working
without exceptions, and large, streamed and partial input. Extend the FAQ
(23 entries, Known bugs first), parse error documentation (empty-input
checklist, line/column, diagnostic positions), element access, conversions,
creating values, ADL troubleshooting, memory, and build/distribution notes.
Add 14 examples with generated output. Correct the statement that parse errors
cannot be recovered from with -fno-exceptions.

The topics come from recurring questions on Stack Overflow, Reddit, Hacker
News, YouTube, and the project's GitHub discussions and issues.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

* docs: declare range-for lists in variables to keep astyle quiet

astyle reformats a braced init list placed directly in a range-for
header; declare the list first so check_amalgamation passes.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>

---------

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
2026-10-25 12:07:13 +01:00
601 changed files with 16263 additions and 5224 deletions

No files matched your search

+36 -7
View File
@@ -1,3 +1,33 @@
# Style or vendor rule sets that do not fit a header-only library:
# altera-*, fuchsia-*, llvmlibc-*, android-cloexec-fopen, boost-use-ranges, llvm-header-guard,
# llvm-include-order, llvm-prefer-static-over-anonymous-namespace, llvm-use-ranges,
# misc-use-anonymous-namespace, google-runtime-float, google-runtime-int, hicpp-signed-bitwise,
# bugprone-signed-bitwise, hicpp-explicit-conversions, google-explicit-constructor,
# cppcoreguidelines-explicit-constructor, misc-explicit-constructor (implicit conversions are the
# API), readability-trailing-comma,
# hicpp-avoid-goto / cppcoreguidelines-avoid-goto, hicpp-no-array-decay,
# hicpp-uppercase-literal-suffix, readability-uppercase-literal-suffix, modernize-use-trailing-return-type.
# Constructs the library needs on purpose (the library supports C++11 and legacy compilers):
# cppcoreguidelines-macro-usage, cppcoreguidelines-avoid-do-while (macros),
# cppcoreguidelines-pro-bounds-*, cppcoreguidelines-pro-type-reinterpret-cast,
# cppcoreguidelines-pro-type-union-access (parsers, serializers, basic_json's value union),
# cppcoreguidelines-avoid-const-or-ref-data-members, cppcoreguidelines-rvalue-reference-param-not-moved,
# cppcoreguidelines-avoid-non-const-global-variables, misc-non-private-member-variables-in-classes,
# misc-no-recursion (value walks are recursive, bounded by detail::recursion_depth_limit()),
# modernize-type-traits, modernize-use-constraints, modernize-use-ranges, modernize-use-std-numbers,
# modernize-use-designated-initializers, modernize-use-nodiscard, modernize-concat-nested-namespaces,
# readability-redundant-typename, readability-redundant-parentheses,
# readability-redundant-access-specifiers, readability-simplify-boolean-expr,
# readability-use-concise-preprocessor-directives, modernize-use-string-view,
# modernize-use-integer-sign-comparison (needs std::cmp_less; the flagged
# static_cast<std::size_t>(end - pos) < n comparisons are deliberate)
# (all need a newer standard or compiler than C++11, or would change macro-generated or
# deliberately explicit code).
# Too noisy to be useful (numeric parsing/formatting code, doctest, tests):
# bugprone-easily-swappable-parameters, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers,
# readability-identifier-length, readability-function-cognitive-complexity, performance-enum-size,
# concurrency-mt-unsafe, misc-confusable-identifiers, misc-include-cleaner (run on its own for
# the consumer headers in cmake/ci.cmake).
# portability-avoid-pragma-once: kept disabled on purpose. #pragma once is accepted
# by every supported compiler, and tools/amalgamate/amalgamate.py strips it from
# single_include, so there is nothing left to fix here.
@@ -10,14 +40,14 @@ Checks: '*,
-android-cloexec-fopen,
-boost-use-ranges,
-bugprone-easily-swappable-parameters,
-cert-err58-cpp,
-clang-analyzer-webkit.NoUncountedMemberChecker,
-bugprone-signed-bitwise,
-concurrency-mt-unsafe,
-cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-avoid-do-while,
-cppcoreguidelines-avoid-goto,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-explicit-constructor,
-cppcoreguidelines-macro-usage,
-cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
@@ -26,19 +56,15 @@ Checks: '*,
-cppcoreguidelines-pro-type-reinterpret-cast,
-cppcoreguidelines-pro-type-union-access,
-cppcoreguidelines-rvalue-reference-param-not-moved,
-cppcoreguidelines-virtual-class-destructor,
-fuchsia-default-arguments-calls,
-fuchsia-default-arguments-declarations,
-fuchsia-overloaded-operator,
-google-explicit-constructor,
-google-readability-function-size,
-google-runtime-float,
-google-runtime-int,
-hicpp-avoid-goto,
-hicpp-explicit-conversions,
-hicpp-function-size,
-hicpp-no-array-decay,
-hicpp-no-assembler,
-hicpp-signed-bitwise,
-hicpp-uppercase-literal-suffix,
-llvm-header-guard,
@@ -48,6 +74,7 @@ Checks: '*,
-llvmlibc-*,
-misc-use-anonymous-namespace,
-misc-confusable-identifiers,
-misc-explicit-constructor,
-misc-include-cleaner,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
@@ -55,20 +82,22 @@ Checks: '*,
-modernize-type-traits,
-modernize-use-constraints,
-modernize-use-designated-initializers,
-modernize-use-integer-sign-comparison,
-modernize-use-nodiscard,
-modernize-use-ranges,
-modernize-use-string-view,
-modernize-use-std-numbers,
-modernize-use-trailing-return-type,
-performance-enum-size,
-portability-avoid-pragma-once,
-readability-function-cognitive-complexity,
-readability-function-size,
-readability-identifier-length,
-readability-magic-numbers,
-readability-redundant-access-specifiers,
-readability-redundant-parentheses,
-readability-redundant-typename,
-readability-simplify-boolean-expr,
-readability-trailing-comma,
-readability-uppercase-literal-suffix,
-readability-use-concise-preprocessor-directives'
+3 -3
View File
@@ -163,9 +163,9 @@ jobs:
python3 $GENERATOR --list-tags
TAG_COUNT=$(python3 $GENERATOR --list-tags | wc -l)
python3 $GENERATOR --abi-tags diag,_dp,_ns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_ns -->' $RUNNER_TEMP/abi_tags.natvis
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_ns_v[0-9_]* -->' $RUNNER_TEMP/abi_tags.natvis
python3 $GENERATOR --abi-tags diag,_dp,_vns --abi-tags _diag --output $RUNNER_TEMP/abi_tags.natvis
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_vns -->' $RUNNER_TEMP/abi_tags.natvis
grep -q '<!-- Namespace nlohmann::json_abi_diag_dp_vns_v[0-9_]* -->' $RUNNER_TEMP/abi_tags.natvis
test $(grep -c '<!-- Namespace ' $RUNNER_TEMP/abi_tags.natvis) -eq $(( $(grep -c '<!-- Namespace ' nlohmann_json.natvis) + 2 ))
python3 $GENERATOR --all --output $RUNNER_TEMP/all.natvis
+2 -1
View File
@@ -43,7 +43,8 @@ jobs:
- name: flawfinder_scan
uses: david-a-wheeler/flawfinder@c4216b74cf2639ffa98503768bd6e4299b5440c9 # v2.0.20
with:
arguments: '--sarif ./'
# single_include/ is omitted: it is generated from include/ and would report every finding twice
arguments: '--sarif ./cmake ./docs ./include ./src ./tests ./tools'
output: 'flawfinder_results.sarif'
- name: Upload analysis results to GitHub Security tab
-1
View File
@@ -90,7 +90,6 @@ cc_library(
"include/nlohmann/detail/view/simd.hpp",
"include/nlohmann/detail/view/string_ref.hpp",
"include/nlohmann/detail/view/value.hpp",
"include/nlohmann/detail/view/view_mode.hpp",
"include/nlohmann/json.hpp",
"include/nlohmann/json_fwd.hpp",
"include/nlohmann/json_literals.hpp",
+1 -1
View File
@@ -309,7 +309,7 @@ The "Check amalgamation" workflow fails if the file is out of date.
The file covers the namespace variants with up to two ABI tags. A Natvis file for other configurations can be
generated with the `--abi-tags` or `--all` options, for example
`make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_ns --output my_nlohmann_json.natvis"`; see
`make natvis NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my_nlohmann_json.natvis"`; see
[`tools/generate_natvis`](tools/generate_natvis/README.md). With MSVC, CMake adds the file to the `nlohmann_json`
target and installs it.
+1 -1
View File
@@ -120,7 +120,7 @@ $(AMALGAMATED_VIEW_FILE): $(SRCS)
tools/amalgamate/amalgamate.py -c tools/amalgamate/config_json_view.json -s . --verbose=yes
NATVIS_VENV=tools/generate_natvis/venv
# extra options for generate_natvis.py, e.g. NATVIS_ARGS="--abi-tags _diag,_dp,_ns --output my.natvis"
# extra options for generate_natvis.py, e.g. NATVIS_ARGS="--abi-tags _diag,_dp,_vns --output my.natvis"
NATVIS_ARGS=
# regenerate nlohmann_json.natvis from the ABI tags and version in include/nlohmann/detail/abi_macros.hpp
+4 -4
View File
@@ -151,7 +151,7 @@ The `json` class provides an API for manipulating a JSON value. To create a `jso
```cpp
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
// ...
@@ -164,7 +164,7 @@ If using modules (enabled with `NLOHMANN_JSON_BUILD_MODULES`), this example beco
import std;
import nlohmann.json;
using json = nlohmann::json;
using nlohmann::json;
// ...
@@ -842,7 +842,7 @@ assert(p == p2);
To make this work with one of your types, you only need to provide two functions:
```cpp
using json = nlohmann::json;
using nlohmann::json;
namespace ns {
void to_json(json& j, const person& p) {
@@ -1257,7 +1257,7 @@ See the page [quality assurance](https://json.nlohmann.me/community/quality_assu
#include <nlohmann/json.hpp>
// for convenience
using json = nlohmann::json;
using nlohmann::json;
```
to the files you want to process JSON and set the necessary switches to enable C++11 (e.g., `-std=c++11` for GCC and Clang).
@@ -113,19 +113,22 @@ basic_json(basic_json&& other) noexcept;
```mermaid
flowchart TD
A(["initializer_list init"]) --> B{"empty, or every element is a 2-element<br/>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<br/>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"]
```
<p class="nj-caption" markdown>Decision flow for an initializer list: hexagons are checks, edge labels are their
outcomes, and rectangles are the resulting value or exception.</p>
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.
+6 -1
View File
@@ -7,7 +7,12 @@ const_iterator begin() const noexcept;
Returns an iterator to the first element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
+6 -1
View File
@@ -6,7 +6,12 @@ const_iterator cbegin() const noexcept;
Returns an iterator to the first element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
+6 -1
View File
@@ -6,7 +6,12 @@ const_iterator cend() const noexcept;
Returns an iterator to one past the last element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
+7 -1
View File
@@ -6,7 +6,13 @@ const_reverse_iterator crbegin() const noexcept;
Returns an iterator to the reverse-beginning; that is, the last element.
![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-rbegin-rend.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
+7 -1
View File
@@ -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.
![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-rbegin-rend.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
+6 -1
View File
@@ -7,7 +7,12 @@ const_iterator end() const noexcept;
Returns an iterator to one past the last element.
![Illustration from cppreference.com](../../images/range-begin-end.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-begin-end.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
@@ -40,6 +40,9 @@ classDiagram
style json_exception fill:#CCCCFF
```
<p class="nj-caption" markdown>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`.</p>
Subclasses:
- [`parse_error`](parse_error.md) for exceptions indicating a parse error
+1 -1
View File
@@ -45,7 +45,7 @@ Constant.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -40,6 +40,9 @@ classDiagram
style json_invalid_iterator fill:#CCCCFF
```
<p class="nj-caption" markdown>Class 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`.</p>
## Member functions
- **what** - returns explanatory string
@@ -40,6 +40,9 @@ classDiagram
style json_other_error fill:#CCCCFF
```
<p class="nj-caption" markdown>Class 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`.</p>
## Member functions
- **what** - returns explanatory string
@@ -41,6 +41,9 @@ classDiagram
style json_out_of_range fill:#CCCCFF
```
<p class="nj-caption" markdown>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`.</p>
## Member functions
- **what** - returns explanatory string
@@ -43,6 +43,9 @@ classDiagram
style json_parse_error fill:#CCCCFF
```
<p class="nj-caption" markdown>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`.</p>
## Member functions
- **what** - returns explanatory string
@@ -22,7 +22,12 @@ The parser callback distinguishes the following events:
## Examples
![Example when certain parse events are triggered](../../images/callback_events.png)
<div class="nj-fig-wrap" markdown>
--8<-- "images/callback_events.svg"
</div>
<p class="nj-caption" markdown>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.</p>
??? example
@@ -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 |
![Example when certain parse events are triggered](../../images/callback_events.png)
<div class="nj-fig-wrap" markdown>
--8<-- "images/callback_events.svg"
</div>
<p class="nj-caption" markdown>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.</p>
Discarding a value (i.e., returning `#!cpp false`) has different effects depending on the context in which function was
called:
+7 -1
View File
@@ -7,7 +7,13 @@ const_reverse_iterator rbegin() const noexcept;
Returns an iterator to the reverse-beginning; that is, the last element.
![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-rbegin-rend.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
+7 -1
View File
@@ -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.
![Illustration from cppreference.com](../../images/range-rbegin-rend.svg)
<div class="nj-fig-wrap" markdown>
--8<-- "images/range-rbegin-rend.svg"
</div>
<p class="nj-caption" markdown>`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.</p>
## Return value
@@ -41,6 +41,9 @@ classDiagram
style json_type_error fill:#CCCCFF
```
<p class="nj-caption" markdown>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`.</p>
## Member functions
- **what** - returns explanatory string
@@ -48,6 +48,9 @@ functions [`is_null`](is_null.md), [`is_object`](is_object.md), [`is_array`](is_
F --> G[binary]
```
<p class="nj-caption" markdown>Arrows point from a type to the next greater type in the ordering used by
`operator<`.</p>
!!! note "Types of numbers"
There are three enumerators for numbers (`number_integer`, `number_unsigned`, and `number_float`) to distinguish
@@ -12,7 +12,7 @@ void erase(view_type array, I idx);
std::size_t erase(const json_pointer& ptr);
```
Only an **editable** document (`#!cpp view_mode::editable`, e.g. [`json_editable_document`](../json_editable_document.md))
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `erase`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
1. Removes every member of `object` whose key is `key` (see [Notes](#notes) on duplicate keys) and returns how many
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
template<typename BasicJsonType, view_mode Mode = view_mode::read_only>
template<typename BasicJsonType, bool Editable = false>
class basic_json_document;
```
@@ -20,9 +20,9 @@ is move-only: a copy would duplicate the whole index, the decoded-string buffer,
enough in every use we know of. The index, the decoded strings, and the owned text live in one heap block that the
document holds through a `#!cpp std::unique_ptr`; this is also why views survive a move of the document.
With `#!cpp Mode == view_mode::editable`, the document also offers [`set`](set.md), [`push_back`](push_back.md),
With `#!cpp Editable == true`, the document also offers [`set`](set.md), [`push_back`](push_back.md),
[`insert`](insert.md), and [`erase`](erase.md) to change values in place, see [Edits](#edits) below. The source text
itself is never written; a read-only document (`#!cpp view_mode::read_only`, the default) does not carry any of the
itself is never written; a read-only document (`#!cpp Editable == false`, the default) does not carry any of the
bookkeeping edits need, and calling any of them on one fails to compile (`#!cpp static_assert`).
## Template parameters
@@ -32,10 +32,9 @@ bookkeeping edits need, and calling any of them on one fails to compile (`#!cpp
[`ordered_json`](../ordered_json.md). Only 64-bit `number_integer_t`/`number_unsigned_t` types are supported; this
is checked with a `static_assert`.
`Mode`
: a [`view_mode`](../view_mode.md): `#!cpp view_mode::editable` if the document supports [`set`](set.md),
[`push_back`](push_back.md), [`insert`](insert.md), and [`erase`](erase.md) (optional, `#!cpp view_mode::read_only`
by default). See [Edits](#edits) below.
`Editable`
: whether the document supports [`set`](set.md), [`push_back`](push_back.md), [`insert`](insert.md), and
[`erase`](erase.md) (optional, `#!cpp false` by default). See [Edits](#edits) below.
## Specializations
@@ -48,7 +47,7 @@ bookkeeping edits need, and calling any of them on one fails to compile (`#!cpp
## Member types
- **view_type** - the type of view returned by [`root()`](root.md) (`#!cpp basic_json_view<BasicJsonType, Mode>`)
- **view_type** - the type of view returned by [`root()`](root.md) (`#!cpp basic_json_view<BasicJsonType, Editable>`)
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
- **image_check** - how [`load()`](load.md) validates an image (`full`, `bounds`, `none`), see [`image_check`](load.md#image_check)
@@ -81,15 +80,15 @@ bookkeeping edits need, and calling any of them on one fails to compile (`#!cpp
### Edits
- [**set**](set.md) - replace a value, or set an object member, an array element, or the value a JSON pointer refers
to (editable documents only)
- [**push_back**](push_back.md) - append to an array (editable documents only)
- [**insert**](insert.md) - insert an element into an array before a given position (editable documents only)
to (`#!cpp Editable` documents only)
- [**push_back**](push_back.md) - append to an array (`#!cpp Editable` documents only)
- [**insert**](insert.md) - insert an element into an array before a given position (`#!cpp Editable` documents only)
- [**erase**](erase.md) - remove an object member, an array element, or the value a JSON pointer refers to
(editable documents only)
(`#!cpp Editable` documents only)
## Edits
An editable document (`#!cpp view_mode::editable`) can be changed after parsing, with [`set`](set.md),
An editable document (`#!cpp Editable == true`) can be changed after parsing, with [`set`](set.md),
[`push_back`](push_back.md), [`insert`](insert.md), and [`erase`](erase.md);
[`json_editable_document`](../json_editable_document.md) and
[`ordered_json_editable_document`](../ordered_json_editable_document.md) are the corresponding specializations. A few
@@ -5,7 +5,7 @@ template<typename I, typename V>
view_type insert(view_type array, I idx, V&& value);
```
Only an **editable** document (`#!cpp view_mode::editable`, e.g. [`json_editable_document`](../json_editable_document.md))
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `insert`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
Inserts `value` into `array` as a new element before position `idx`, which must not be past the end
@@ -55,7 +55,10 @@ validate with overload 2 first, if the original vector must survive a failed loa
## Exceptions
Throws [`parse_error.116`](../../home/exceptions.md#jsonexceptionparse_error116) if `image` is not one
On a big-endian target, throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) -- the same
exception [`save()`](save.md#exceptions) throws there, since the image format is little-endian only.
Otherwise throws [`parse_error.116`](../../home/exceptions.md#jsonexceptionparse_error116) if `image` is not one
`save()` could have written, or fails the requested `check`:
| message | when |
@@ -92,9 +95,6 @@ are checked once, however many nodes refer to it.
## Notes
**Little-endian targets only.** On a big-endian target, `load()` does not exist, just like
[`save()`](save.md#notes): the image format is little-endian, so a call fails to compile.
### `image_check` { #image_check }
```cpp
@@ -13,7 +13,7 @@ editable, and it does not have to be `array`'s own document -- which is copied s
source document afterward; a `BasicJsonType` value; or anything `BasicJsonType` can be constructed from (numbers,
strings, `#!cpp bool`, `#!cpp nullptr`, containers, ...).
Only an **editable** document (`#!cpp view_mode::editable`, e.g. [`json_editable_document`](../json_editable_document.md))
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `push_back`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
## Template parameters
@@ -12,7 +12,7 @@ An edited document is written in its *current* state, with its values in documen
parser would have produced them for that JSON text: a member [`set`](set.md) added goes at the end, an
[`erase`](erase.md)d member leaves no trace, and a float that is not finite (NaN or positive/negative infinity)
becomes null, the same substitution [`dump()`](../basic_json_view/dump.md) makes. The same document always saves to
the same bytes -- also across `BasicJsonType` and the [`view_mode`](../view_mode.md), since the image reflects document order and
the same bytes -- also across `BasicJsonType` and `#!cpp Editable`, since the image reflects document order and
values only, not which specialization produced them.
## Return value
@@ -31,6 +31,9 @@ Throws [`type_error.320`](../../home/exceptions.md#jsonexceptiontype_error320) i
[discarded](is_discarded.md) -- a default-constructed document, or one a failed [`parse()`](parse.md)/
[`read()`](read.md) with `allow_exceptions == false` left discarded.
On a big-endian target, throws `type_error.320` with a different message instead: the image format is little-endian
only (see [Notes](#notes)).
Throws [`out_of_range.416`](../../home/exceptions.md#jsonexceptionout_of_range416) if the node count, the text, or
the decoded strings of the image would individually reach 4 GiB -- the same 32-bit offsets
[`parse()`](parse.md#exceptions) and, for edits, [`set`](set.md)/[`push_back`](push_back.md) are already limited to.
@@ -41,6 +44,9 @@ the decoded strings of the image would individually reach 4 GiB -- the same 32-b
[json.exception.type_error.320] cannot save a discarded json_document
```
```
[json.exception.type_error.320] json_document images need a little-endian target
```
```
[json.exception.out_of_range.416] images of 4 GiB or more are not supported by json_document
```
@@ -64,9 +70,9 @@ else -- see [`load`'s Exceptions](load.md#exceptions).
the *same* build on the *same* (little-endian) machine -- not as a long-term storage format. Keep the original
JSON text if you need to read a saved document back with a future library version.
**Little-endian targets only.** The image is written as raw little-endian bytes, with no byte-swapping. On a
big-endian target, `save()` and [`load`](load.md) do not exist: a call fails to compile rather than produce bytes a
big-endian reader could not interpret correctly.
**Little-endian only.** The image is written as raw little-endian bytes, with no byte-swapping. `save()` (and
[`load`](load.md)) throw `type_error.320` on a big-endian target rather than silently produce bytes a big-endian
reader could not interpret correctly.
## Examples
@@ -18,7 +18,7 @@ template<typename V>
view_type set(const json_pointer& ptr, V&& value);
```
Only an **editable** document (`#!cpp view_mode::editable`, e.g. [`json_editable_document`](../json_editable_document.md))
Only an **editable** document (`#!cpp Editable == true`, e.g. [`json_editable_document`](../json_editable_document.md))
has `set`; calling it on a read-only `basic_json_document` fails to compile (`#!cpp static_assert`).
1. Replaces the value `target` refers to with `value`.
+12 -37
View File
@@ -19,36 +19,16 @@ For the types below, the conversion works directly on the flat index -- no `Basi
document's own buffer of decoded strings (see [`get_string()`](get_string.md))
- `BasicJsonType` -- equivalent to [`materialize()`](materialize.md)
- `basic_json_view` -- returns `#!cpp *this`
- `#!cpp std::vector<U, A>` of the types above -- from an array, element by element, each converted with
`#!cpp get<U>()`; `#!cpp std::vector<basic_json_view>` keeps a view of every element instead of a value
- `#!cpp std::map<K, basic_json_view, C, A>` and `#!cpp std::unordered_map<K, basic_json_view, H, E, A>`, if `K` is
constructible from a `#!cpp (const char*, std::size_t)` pair -- views of the members of an object; with a repeated
key, the view of the *last* member is kept, as [`BasicJsonType::parse()`](../basic_json/parse.md) keeps its value
- `#!cpp std::vector<U, A>` -- from an array, element by element, each converted with `#!cpp get<U>()`; `#!cpp
std::vector<basic_json_view>` keeps a view of every element instead of a value
- `#!cpp std::map<K, V, C, A>` and `#!cpp std::unordered_map<K, V, H, E, A>`, if `K` is constructible from a `#!cpp
(const char*, std::size_t)` pair -- from an object, member by member, each value converted with `#!cpp get<V>()`; with a repeated
key, the *last* value is kept, as [`BasicJsonType::parse()`](../basic_json/parse.md) (and
[`materialize()`](materialize.md)) does; `#!cpp std::map<std::string, basic_json_view>` keeps views of the members
instead of values
A default-constructible `T` whose `from_json()` accepts views reads the view directly as well, without building a
`BasicJsonType` value. This covers the library's own conversions of the standard library types -- all other
`#!cpp std::vector`s, `#!cpp std::map`/`#!cpp std::unordered_map` (also with other key types), `#!cpp std::list`,
`#!cpp std::deque`, `#!cpp std::set`, `#!cpp std::forward_list`, `#!cpp std::valarray`, `#!cpp std::array`, C arrays,
`#!cpp std::pair`, `#!cpp std::tuple`, `#!cpp std::optional`, enumerations, `#!cpp std::filesystem::path`, ... --
which give the same values as `#!cpp materialize().get<T>()` (from an object, a repeated key keeps the *last* value,
as [`BasicJsonType::parse()`](../basic_json/parse.md) does), as well as the types of the
[`NLOHMANN_DEFINE_TYPE_*`](../macros/nlohmann_define_type_intrusive.md) and
[`NLOHMANN_DEFINE_DERIVED_TYPE_*`](../macros/nlohmann_define_derived_type.md) macros and the enumerations of
[`NLOHMANN_JSON_SERIALIZE_ENUM`](../macros/nlohmann_json_serialize_enum.md), and any `from_json()` constrained to
accept views, e.g. with [`is_json_view`](../is_json_view.md). A `from_json()` that also accepts types that are no JSON
values at all, such as the unconstrained `#!cpp template<typename BasicJsonType> void from_json(const BasicJsonType&,
T&)` of [arbitrary type conversions](../../features/arbitrary_types.md), is not called with a view: it may use
`BasicJsonType` functions a view does not have. See [json_view](../../features/json_view.md).
!!! warning "Duplicate keys"
Such a `from_json()` looks members up in the view, where a repeated key finds the **first** member, while
`#!cpp materialize().get<T>()` sees the **last** one, as [`BasicJsonType::parse()`](../basic_json/parse.md)
keeps it: for `#!cpp {"x":1,"x":2}`, `#!cpp get<point>()` reads `#!cpp x == 1`. See
[Duplicate keys](../../features/json_view.md#duplicate-keys).
Every other `T` -- user types whose `from_json()` is written for `BasicJsonType` only, types without a default
constructor, `#!cpp std::tuple`s holding references, ... -- is converted by `#!cpp materialize().get<T>()`: the subtree is built into a real `BasicJsonType`
Every other `T` -- `#!cpp std::list`, `#!cpp std::pair`, `#!cpp std::array`, enumerations, user types with a
`from_json()`, ... -- is converted by `#!cpp materialize().get<T>()`: the subtree is built into a real `BasicJsonType`
value first (as [`BasicJsonType::parse()`](../basic_json/parse.md) would), and converted from there exactly as
[`BasicJsonType::get<T>()`](../basic_json/get.md) would convert it.
@@ -73,15 +53,12 @@ Strong guarantee: there are no changes to the view or the document it refers to.
throws for the same JSON type and `T`.
- For `#!cpp std::vector<U, A>`: throws `type_error.302` if the value is not an array; otherwise, whatever converting
an element to `U` throws.
- For `#!cpp std::map`/`#!cpp std::unordered_map` of views: throws `type_error.302` if the value is not an object.
- For a `T` whose `from_json()` reads the view: whatever that `from_json()` throws; for the library's conversions and
the macros, the same exceptions with the same messages as [`BasicJsonType::get<T>()`](../basic_json/get.md) of the
same value.
- For `#!cpp std::map`/`#!cpp std::unordered_map`: throws `type_error.302` if the value is not an object; otherwise,
whatever converting a member to the mapped type throws.
- For every other `T`: whatever [`materialize().get<T>()`](../basic_json/get.md) throws -- typically `type_error.302`,
or whatever a user-provided `from_json()` throws.
None of the exceptions thrown directly by this function or by a `from_json()` that reads the view (the first four
bullets above) carry a
None of the exceptions thrown directly by this function (the first three bullets above) carry a
[`JSON_DIAGNOSTICS`](../macros/json_diagnostics.md) path: the view has no `BasicJsonType` value to point at. An
exception thrown while converting through `materialize()` (the last bullet) is different: it is thrown by a real
`BasicJsonType` value, so it **does** carry a `JSON_DIAGNOSTICS` path if `BasicJsonType` was built with it enabled.
@@ -99,8 +76,6 @@ document.
- `#!cpp std::map`/`#!cpp std::unordered_map`: linear in the number of members for walking them, plus the container's
own insertion cost per member (logarithmic for `#!cpp std::map`, amortized constant for `#!cpp
std::unordered_map`), times the complexity of converting one member to the mapped type.
- a `T` whose `from_json()` reads the view: the cost of that `from_json()`; for the macros, linear in the number of
members times the cost of a lookup, plus the cost of converting the members.
- every other `T`: the cost of [`materialize()`](materialize.md) and of destroying the `BasicJsonType` value
afterwards, plus that of [`BasicJsonType::get<T>()`](../basic_json/get.md).
@@ -5,13 +5,12 @@ template<typename T>
T& get_to(T& v) const;
```
Converts the value to `T` and stores it in `v`, in one of three ways:
Converts the value to `T` and stores it in `v`, in one of two ways:
- For the types that [`get<T>()`](get.md) converts directly -- arithmetic types, `#!cpp bool`,
`#!cpp std::nullptr_t`, [`string_view_t`](index.md#member-types), `#!cpp std::basic_string`, `BasicJsonType`,
`basic_json_view`, vectors of these, and maps of views -- `v` is assigned: `#!cpp v = get<T>()`.
- For a type whose `from_json()` accepts views (see [`get<T>()`](get.md)), that `from_json()` is called with the
view and the existing `v`, without building a `BasicJsonType` value.
`basic_json_view`, `#!cpp std::vector`, and `#!cpp std::map`/`#!cpp std::unordered_map` with string keys -- `v` is
assigned: `#!cpp v = get<T>()`.
- For every other type, the subtree is built into a `BasicJsonType` value and `#!cpp materialize().get_to(v)` is
called, i.e. `from_json()` is invoked with the existing `v`, exactly as
[`BasicJsonType::get_to()`](../basic_json/get_to.md) does.
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
template<typename BasicJsonType, view_mode Mode = view_mode::read_only>
template<typename BasicJsonType, bool Editable = false>
class basic_json_view;
```
@@ -37,7 +37,7 @@ Moving the document itself does not invalidate its views: the index is heap-allo
`#!cpp operator ValueType()`), and no `#!cpp get_ptr()` or `#!cpp get_ref()`; see [`get`](get.md).
`basic_json_view` itself is always read-only -- it never has a `set` or `push_back` of its own. A view of an
**editable** document (`#!cpp view_mode::editable`) sees every edit made through
**editable** document (`#!cpp Editable == true`) sees every edit made through
[`basic_json_document::set`](../basic_json_document/set.md) and
[`basic_json_document::push_back`](../basic_json_document/push_back.md): once a value is changed, every view that
still refers to it -- including ones taken before the change -- reads the new value. See
@@ -49,10 +49,9 @@ still refers to it -- including ones taken before the change -- reads the new va
: a specialization of [`basic_json`](../basic_json/index.md), matching the
[`basic_json_document`](../basic_json_document/index.md) the view was taken from.
`Mode`
: a [`view_mode`](../view_mode.md): whether the view is of an editable document, matching the
[`basic_json_document`](../basic_json_document/index.md) it was taken from (optional, `#!cpp view_mode::read_only` by
default). See [Edits](../basic_json_document/index.md#edits).
`Editable`
: whether the view is of an editable document, matching the [`basic_json_document`](../basic_json_document/index.md)
it was taken from (optional, `#!cpp false` by default). See [Edits](../basic_json_document/index.md#edits).
## Specializations
@@ -64,7 +63,6 @@ still refers to it -- including ones taken before the change -- reads the new va
## Member types
- **basic_json_type** - `BasicJsonType` (it also marks the class for [`is_json_view`](../is_json_view.md))
- **value_t** - the JSON type enumeration, see [`basic_json::value_t`](../basic_json/value_t.md)
- **string_t**, **number_integer_t**, **number_unsigned_t**, **number_float_t**, **json_pointer** - the corresponding
member types of `BasicJsonType`
-55
View File
@@ -1,55 +0,0 @@
# <small>nlohmann::</small>is_json_view
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
template<typename T>
struct is_json_view;
```
A type trait: `#!cpp is_json_view<T>::value` is `#!cpp true` if `T` is a [`basic_json_view`](basic_json_view/index.md)
of any `BasicJsonType` and any [`view_mode`](view_mode.md) -- [`json_view`](json_view.md),
[`json_editable_view`](json_editable_view.md), [`ordered_json_view`](ordered_json_view.md), ... -- and
`#!cpp false` otherwise, for [`basic_json`](basic_json/index.md) as well.
It is meant for constraining templates that accept views, in particular a `from_json()` that should read views
directly: [`get<T>()`](basic_json_view/get.md) on a view calls a `from_json()` with the view only if that `from_json()`
accepts views but not arbitrary types.
## Template parameters
`T`
: the type to check (without cv-qualifiers or references)
## Notes
A view is recognized by its member type `basic_json_type` (a [`basic_json`](basic_json/index.md) specialization) and
its [`materialize()`](basic_json_view/materialize.md) returning that type, so the trait needs no declaration of the
view class.
## Examples
??? example
The example below shows the trait, and a `from_json()` constrained to `json` values and views: `get<T>()` on a view
reads the view directly.
```cpp
--8<-- "examples/is_json_view.cpp"
```
Output:
```
--8<-- "examples/is_json_view.output"
```
## See also
- [basic_json_view](basic_json_view/index.md) - a handle to one value of a document
- [get](basic_json_view/get.md) - which conversions read the view directly
- [view_mode](view_mode.md) - read-only or editable
## Version history
Added in version 3.13.0.
+1 -1
View File
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using json_document = basic_json_document<json, view_mode::read_only>;
using json_document = basic_json_document<json>;
```
This type is a [`basic_json_document`](basic_json_document/index.md) of the default [`json`](json.md)
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using json_editable_document = basic_json_document<json, view_mode::editable>;
using json_editable_document = basic_json_document<json, true>;
```
This type is an **editable** [`basic_json_document`](basic_json_document/index.md) of the default
+1 -1
View File
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using json_editable_view = basic_json_view<json, view_mode::editable>;
using json_editable_view = basic_json_view<json, true>;
```
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of a
@@ -36,6 +36,9 @@ flowchart LR
parent["parent_pointer() returns /a/b"] -.-> B
```
<p class="nj-caption" markdown>Boxes are the reference tokens in order; dotted arrows show which token each member
function reads, removes, or adds to.</p>
The diagram shows the reference tokens of the JSON pointer `/a/b/c`.
## Member types
+3
View File
@@ -25,6 +25,9 @@ sequenceDiagram
P->>H: end_object()
```
<p class="nj-caption" markdown>Each arrow is one call from the parser to the SAX handler, from top to bottom in the
order the calls happen.</p>
Note `elements` is passed as `#!cpp std::numeric_limits<std::size_t>::max()` (i.e., "unknown") for JSON text input;
only binary formats such as CBOR or MessagePack may report the actual number of elements in `start_object`/
`start_array`. Also note that `1` is reported via `number_unsigned` rather than `number_integer` because it has no
+1 -1
View File
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using json_view = basic_json_view<json, view_mode::read_only>;
using json_view = basic_json_view<json>;
```
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of a [`json_document`](json_document.md).
+2
View File
@@ -43,6 +43,8 @@ header. See also the [macro overview page](../../features/macros.md).
- [**JSON_SKIP_UNSUPPORTED_COMPILER_CHECK**](json_skip_unsupported_compiler_check.md) - do not warn about unsupported compilers
- [**JSON_USE_GLOBAL_UDLS**](json_use_global_udls.md) - place user-defined string literals (UDLs) into the global namespace
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
- [**JSON_VIEW_NO_SIMD**](json_view_no_simd.md) - use only portable code in the parser of `json_view.hpp`
- [**JSON_VIEW_USE_SSSE3**](json_view_use_ssse3.md) - validate non-ASCII strings with SSSE3 in the parser of `json_view.hpp`
## Library version
+2 -2
View File
@@ -38,7 +38,7 @@ Therefore, assertions can be switched off by defining `NDEBUG`.
```cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -64,7 +64,7 @@ Therefore, assertions can be switched off by defining `NDEBUG`.
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -79,7 +79,7 @@ The default value is `0` (disabled — existing behavior is preserved).
```cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -98,7 +98,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#define JSON_BRACE_INIT_COPY_SEMANTICS 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -54,7 +54,7 @@ The default value is `0` (disabled, the deprecated functions can still be called
```cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -72,7 +72,7 @@ The default value is `0` (disabled, the deprecated functions can still be called
#define JSON_DELETE_DEPRECATED_FUNCTIONS 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -39,7 +39,7 @@ The default value is `0`.
#define JSON_DISABLE_ENUM_SERIALIZATION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
enum class Choice
{
@@ -66,7 +66,7 @@ The default value is `0`.
#define JSON_DISABLE_ENUM_SERIALIZATION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
enum class Choice
{
@@ -99,7 +99,7 @@ The default value is `0`.
#define JSON_DISABLE_ENUM_SERIALIZATION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
enum class Choice
{
@@ -92,7 +92,7 @@ The default value is `0`: streams are scanned in bulk.
#include <sstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -115,7 +115,7 @@ The default value is `0`: streams are scanned in bulk.
#include <sstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -72,7 +72,7 @@ The default value is `0` (disabled — existing behavior is preserved).
```cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -89,7 +89,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#define JSON_DISABLE_TUPLE_REFERENCE_CONVERSION 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -73,7 +73,7 @@ The default value is `0`: the file is locked once and read with the unlocked std
#include <cstdio>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -92,7 +92,7 @@ The default value is `0`: the file is locked once and read with the unlocked std
#include <cstdio>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
+2 -4
View File
@@ -5,8 +5,7 @@
```
When defined, the library uses only portable C++ code where it would otherwise use vector instructions: when scanning
strings during parsing, and when writing floating-point numbers during serialization. This includes the parser of
[`basic_json_document`](../basic_json_document/index.md) (`<nlohmann/json_view.hpp>`).
strings during parsing, and when writing floating-point numbers during serialization.
The macro is an escape hatch, for example for toolchains that cannot compile the vector code, for sanitizers or
analyzers that do not understand it, or to compare the speed of both variants. It does not change any result: values,
@@ -62,7 +61,7 @@ By default, `#!cpp JSON_NO_SIMD` is not defined, and vector instructions are use
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -78,7 +77,6 @@ By default, `#!cpp JSON_NO_SIMD` is not defined, and vector instructions are use
- [**JSON_USE_SIMDUTF**](json_use_simdutf.md) - use the simdutf library to accelerate UTF-8 validation
- [**JSON_DISABLE_STREAM_BULK_SCAN**](json_disable_stream_bulk_scan.md) - read a `std::istream` one character at a time
- [Parsing: input sources and performance](../../features/parsing/index.md#input-sources-and-performance)
- [json_view](../../features/json_view.md) - the zero-copy view, whose parser the macro also affects
## Version history
@@ -94,7 +94,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#include <sstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -115,7 +115,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#include <sstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -64,7 +64,7 @@ The default value is `0` (disabled, the behavior of version 3.12.0 and earlier i
```cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -81,7 +81,7 @@ The default value is `0` (disabled, the behavior of version 3.12.0 and earlier i
#define JSON_STRICT_BINARY_UTF8 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -92,7 +92,7 @@ The default value is `0` (disabled — existing behavior is preserved).
```cpp
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -109,7 +109,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#define JSON_STRICT_NUL_HANDLING 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -77,7 +77,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#include <map>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
enum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };
@@ -105,7 +105,7 @@ The default value is `0` (disabled — existing behavior is preserved).
#include <map>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
enum TaskState { TS_STOPPED, TS_RUNNING, TS_COMPLETED };
@@ -0,0 +1,52 @@
# JSON_VIEW_NO_SIMD
```cpp
#define JSON_VIEW_NO_SIMD
```
When defined, the parser of [`basic_json_document`](../basic_json_document/index.md) (`<nlohmann/json_view.hpp>`)
uses only portable C++ to scan strings. By default, it scans long runs of string bytes 16 at a time with NEON on
AArch64 (with GCC and Clang) and SSE2 on x86-64, which are part of the baseline instruction sets of these
architectures, and validates non-ASCII text with NEON (or SSSE3, see
[`JSON_VIEW_USE_SSSE3`](json_view_use_ssse3.md)).
The same input is accepted or rejected either way, with the same values, and errors are reported the same way; only
the speed differs. The macro exists for platforms whose compilers lack the intrinsics headers, and to test the portable
code.
!!! note "ABI compatibility"
The macro selects between two definitions of the same inline functions. Whether it is defined is encoded in the
[namespace](../../features/namespace.md) (tag `_vns`), resulting in distinct symbol names. Translation units
compiled with and without it can therefore be linked into the same program without One Definition Rule (ODR)
violations, but they cannot exchange instances of library types.
## Default definition
By default, `#!cpp JSON_VIEW_NO_SIMD` is not defined, and the vector code is used where available.
```cpp
#undef JSON_VIEW_NO_SIMD
```
## Examples
??? example
The code below uses the portable string scanning of the view.
```cpp
#define JSON_VIEW_NO_SIMD
#include <nlohmann/json_view.hpp>
...
```
## See also
- [JSON_VIEW_USE_SSSE3](json_view_use_ssse3.md) - validate non-ASCII strings with SSSE3 on x86-64
- [json_view](../../features/json_view.md) - the zero-copy view
## Version history
- Added in version 3.13.0.
@@ -0,0 +1,53 @@
# JSON_VIEW_USE_SSSE3
```cpp
#define JSON_VIEW_USE_SSSE3
```
When defined on x86-64, the parser of [`basic_json_document`](../basic_json_document/index.md)
(`<nlohmann/json_view.hpp>`) validates non-ASCII text in strings with SSSE3 without asking the CPU first.
By default, the parser checks once at run time whether the CPU has SSSE3 (all x86-64 CPUs since about 2011 have it)
and then validates non-ASCII text 16 bytes at a time, using the "lookup4" algorithm of
[simdjson](https://github.com/simdjson/simdjson); on CPUs without SSSE3, it validates one UTF-8 sequence at a time.
The vector check is compiled for SSSE3 with a function attribute (GCC 4.9 and later, Clang), so this needs no compiler
option. With MSVC, the check uses `__cpuid`. On AArch64, the vector check uses NEON and is always on.
Define the macro only together with a compiler option that enables SSSE3 (e.g. `-mssse3`, or `-march=` with a CPU that
has it), and only for programs that run on such CPUs. It saves the check of the CPU, which costs little. The same
input is accepted or rejected either way; only the speed of non-ASCII text differs.
!!! note "ABI compatibility"
The macro selects between two definitions of the same inline functions. Whether it is defined is encoded in the
[namespace](../../features/namespace.md) (tag `_vssse3`, on every architecture), resulting in distinct symbol
names. Translation units compiled with and without it can therefore be linked into the same program without One
Definition Rule (ODR) violations, but they cannot exchange instances of library types.
## Default definition
By default, `#!cpp JSON_VIEW_USE_SSSE3` is not defined.
```cpp
#undef JSON_VIEW_USE_SSSE3
```
## Examples
??? example
With CMake, for a program that only runs on CPUs with SSSE3:
```cmake
target_compile_definitions(your_target PRIVATE JSON_VIEW_USE_SSSE3)
target_compile_options(your_target PRIVATE -mssse3)
```
## See also
- [JSON_VIEW_NO_SIMD](json_view_no_simd.md) - use only portable code in the view's parser
- [JSON_USE_SIMDUTF](json_use_simdutf.md) - validate UTF-8 with simdutf in `basic_json`'s parser
## Version history
- Added in version 3.13.0.
@@ -147,13 +147,6 @@ void to_json(BasicJsonType& j, const B& b) {
See Implementation limits for [NLOHMANN_DEFINE_TYPE_INTRUSIVE](nlohmann_define_type_intrusive.md) and
[NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE](nlohmann_define_type_non_intrusive.md), respectively.
!!! info "Views"
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
(`<nlohmann/json_view.hpp>`): [`get<T>()`](../basic_json_view/get.md) on a view looks the members up in the
view, without building a `json` value first. The base part is read from the view as well if the base's
`from_json()` accepts views, and from [`materialize()`](../basic_json_view/materialize.md) otherwise.
## Examples
??? example "Example: (1) NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE"
@@ -199,5 +192,3 @@ void to_json(BasicJsonType& j, const B& b) {
6. Added in version 3.12.0.
All six macros were changed to allow an empty member list in version 3.13.0.
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
@@ -81,12 +81,6 @@ See the examples below for the concrete generated code.
that serializes a struct's members positionally into a JSON array; for that, write `to_json`/`from_json` by
hand, building/reading a `json::array()` of the members in order.
!!! info "Views"
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
(`<nlohmann/json_view.hpp>`): [`get<T>()`](../basic_json_view/get.md) on a view looks the members up in the
view, without building a `json` value first.
## Examples
??? example "Example: (1) NLOHMANN_DEFINE_TYPE_INTRUSIVE"
@@ -195,5 +189,3 @@ See the examples below for the concrete generated code.
All three macros were changed to work with any `basic_json` specialization (not only `nlohmann::json`) in version 3.12.0,
and to allow an empty member list in version 3.13.0.
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
@@ -80,12 +80,6 @@ See the examples below for the concrete generated code.
that serializes a struct's members positionally into a JSON array; for that, write `to_json`/`from_json` by
hand, building/reading a `json::array()` of the members in order.
!!! info "Views"
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
(`<nlohmann/json_view.hpp>`): [`get<T>()`](../basic_json_view/get.md) on a view looks the members up in the
view, without building a `json` value first.
## Examples
??? example "Example: (1) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE"
@@ -194,5 +188,3 @@ See the examples below for the concrete generated code.
All three macros were changed to work with any `basic_json` specialization (not only `nlohmann::json`) in version 3.12.0,
and to allow an empty member list in version 3.13.0.
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
@@ -39,6 +39,6 @@ the library.
## Version history
- Added in version 3.11.0. Changed inline namespace name in version 3.11.2. Added the ABI tag `_dp` in
version 3.12.0, and the ABI tags `_bics`, `_psp`, `_snul`, `_sbu8`, `_ekmo`, `_dsbs`, `_dufio`, and `_ns` in
version 3.13.0; see
version 3.12.0, and the ABI tags `_bics`, `_psp`, `_snul`, `_sbu8`, `_ekmo`, `_dsbs`, `_dufio`, `_ns`, `_vns`,
and `_vssse3` in version 3.13.0; see
[`nlohmann` Namespace](../../features/namespace.md#structure).
@@ -45,12 +45,6 @@ inline void from_json(const BasicJsonType& j, type& e);
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
with the converted keys. Such maps can be read from both forms.
!!! info "Views"
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
(`<nlohmann/json_view.hpp>`), comparing the view with the entries of the mapping, without building a `json` value
first.
## Examples
??? example "Example: Basic usage"
@@ -94,5 +88,3 @@ inline void from_json(const BasicJsonType& j, type& e);
## Version history
Added in version 3.4.0.
The generated `from_json()` reads the views of `json_document`s since version 3.13.0.
@@ -48,12 +48,6 @@ inline void from_json(const BasicJsonType& j, type& e);
Define [`JSON_USE_OBJECTS_FOR_ENUM_KEYED_MAPS`](json_use_objects_for_enum_keyed_maps.md) to store them as objects
with the converted keys. Such maps can be read from both forms.
!!! info "Views"
The generated `from_json()` also reads the views of [`json_document`](../json_document.md)s
(`<nlohmann/json_view.hpp>`), comparing the view with the entries of the mapping, without building a `json` value
first.
## Examples
??? example "Example: Basic usage"
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using ordered_json_document = basic_json_document<ordered_json, view_mode::read_only>;
using ordered_json_document = basic_json_document<ordered_json>;
```
This type is a [`basic_json_document`](basic_json_document/index.md) of the [`ordered_json`](ordered_json.md)
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using ordered_json_editable_document = basic_json_document<ordered_json, view_mode::editable>;
using ordered_json_editable_document = basic_json_document<ordered_json, true>;
```
This type is an **editable** [`basic_json_document`](basic_json_document/index.md) of the
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using ordered_json_editable_view = basic_json_view<ordered_json, view_mode::editable>;
using ordered_json_editable_view = basic_json_view<ordered_json, true>;
```
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an
+1 -1
View File
@@ -3,7 +3,7 @@
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
using ordered_json_view = basic_json_view<ordered_json, view_mode::read_only>;
using ordered_json_view = basic_json_view<ordered_json>;
```
This type is a [`basic_json_view`](basic_json_view/index.md) of a value of an
-80
View File
@@ -1,80 +0,0 @@
# <small>nlohmann::</small>view_mode
<small>Defined in header `<nlohmann/json_view.hpp>`</small>
```cpp
enum class view_mode : std::uint8_t
{
read_only,
editable
};
```
The second template parameter of [`basic_json_document`](basic_json_document/index.md) and
[`basic_json_view`](basic_json_view/index.md): whether a document can be changed after parsing, and whether a view is
of such a document.
`read_only`
: the default: the document is parsed once and then only read. It carries none of the bookkeeping edits need, and
calling [`set`](basic_json_document/set.md), [`push_back`](basic_json_document/push_back.md),
[`insert`](basic_json_document/insert.md), or [`erase`](basic_json_document/erase.md) on it fails to compile.
`editable`
: the document also offers [`set`](basic_json_document/set.md), [`push_back`](basic_json_document/push_back.md),
[`insert`](basic_json_document/insert.md), and [`erase`](basic_json_document/erase.md); its views see every edit,
see [Edits](basic_json_document/index.md#edits).
The shortcuts name both modes: [`json_document`](json_document.md) and [`json_view`](json_view.md) are read-only,
[`json_editable_document`](json_editable_document.md) and [`json_editable_view`](json_editable_view.md) are editable
(and likewise for `ordered_json`).
## Notes
The mode is a compile-time property of the document's and the view's type, not a setting of a call, and there is no conversion between the two modes: a read-only view reads a
container in place, while a view of an editable document follows the links that edits leave behind. A function that
accepts views therefore names the modes it accepts in its signature:
```cpp
// views of editable documents only
template<typename BasicJsonType>
void f(basic_json_view<BasicJsonType, view_mode::editable> v);
// views of read-only documents only
template<typename BasicJsonType>
void f(basic_json_view<BasicJsonType, view_mode::read_only> v);
// either
template<typename BasicJsonType, view_mode Mode>
void f(basic_json_view<BasicJsonType, Mode> v);
```
A function that takes a [`json_view`](json_view.md) accepts neither an [`ordered_json_view`](ordered_json_view.md)
nor a [`json_editable_view`](json_editable_view.md). Views of the two modes still compare with
[`operator==`](basic_json_view/operator_eq.md).
## Examples
??? example
The example below shows a function template that accepts the views of both modes, and one that accepts only
views of editable documents.
```cpp
--8<-- "examples/view_mode.cpp"
```
Output:
```
--8<-- "examples/view_mode.output"
```
## See also
- [basic_json_document](basic_json_document/index.md) - a parsed JSON text
- [basic_json_view](basic_json_view/index.md) - a handle to one value of a document
- [json_editable_document](json_editable_document.md) - an editable document of `json`
## Version history
Added in version 3.13.0.
@@ -41,6 +41,8 @@ flowchart LR
E --> F[Trusted caller]
```
<p class="nj-caption" markdown>The 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.</p>
## Secure design
- **Strict parsing.** The parser accepts exactly the JSON grammar of [RFC 8259](https://datatracker.ietf.org/doc/html/rfc8259).
@@ -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.
<div class="nj-fig-wrap" markdown>
--8<-- "images/qa_pipeline.svg"
</div>
<p class="nj-caption" markdown>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.</p>
## C++ language compliance and compiler compatibility
!!! success "Requirement: Compiler support"
@@ -188,10 +197,13 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
```
- [x] The code is checked with the latest [Cppcheck](https://cppcheck.sourceforge.io) with all warnings enabled.
- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) with 89 enabled
rules.
- [x] The code is checked with the latest [Clang Static Analyzer](https://clang-analyzer.llvm.org) with 52 enabled
checkers.
- [x] The code is checked with [Infer](https://fbinfer.com).
- [x] The code is checked with [Codacy](https://app.codacy.com/gh/nlohmann/json/dashboard).
- [x] The code is scanned with [CodeQL](https://codeql.github.com), [Semgrep](https://semgrep.dev), and
[Flawfinder](https://dwheeler.com/flawfinder/) on every push and pull request and on a schedule; the findings are
reported to GitHub's code scanning.
## Dynamic analysis
@@ -204,6 +216,8 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
- [x] The test suite is executed with [Valgrind](https://valgrind.org) (Memcheck) to detect memory leaks.
- [x] The test suite is executed with [Sanitizers](https://github.com/google/sanitizers) (address sanitizer, undefined
behavior sanitizer, integer overflow detection, nullability violations).
- [x] The fuzz targets are run with [CIFuzz](https://google.github.io/oss-fuzz/getting-started/continuous-integration/)
on every pull request to catch regressions before they are merged.
## Dependencies
@@ -223,6 +237,8 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
No release is made while such an alert is open.
- [x] Third-party code included in the repository for testing, such as [doctest](https://github.com/doctest/doctest),
is updated manually.
- [x] The repository is evaluated with the [OpenSSF Scorecard](https://securityscorecards.dev) on a schedule and on
every push to the default branch, and the results are reported to GitHub's code scanning.
## Style check
@@ -258,4 +274,21 @@ Note: Some modern features (like C++20 ranges or filesystem support) may be disa
- [x] The library is tested against relevant CMake versions:
- CMake 3.5 (the earliest supported)
- CMake 3.31.6 (the latest 3.x release)
- CMake 4.0.0 (a very recent release)
- CMake 4.0.0 (the first 4.x release)
!!! success "Requirement: Other build systems"
The library can be used with build systems and package managers other than CMake.
- [x] The library can be consumed with [Meson](https://json.nlohmann.me/integration/package_managers/) and the Swift
Package Manager; the installation with Meson and the resolution of `Package.swift` are tested in the CI.
!!! success "Requirement: Reproducible and verifiable builds"
The library can be built and tested without network access or a Git checkout, and its licensing is machine-readable.
- [x] The test suite is executed from an exported source tree without the `.git` directory and with the test data
being available offline.
- [x] The test suite is executed without the tests that change installed files to check that builds are reproducible.
- [x] The repository is checked for compliance with the [REUSE specification](https://reuse.software) so that the
license and copyright of every file is machine-readable.
- [x] The documentation is built with warnings treated as errors, and its links are checked regularly.
+12
View File
@@ -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:
<div class="nj-fig-wrap" markdown>
--8<-- "images/roadmap_lanes.svg"
</div>
<p class="nj-caption" markdown>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.</p>
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 |
<p class="nj-table-caption" markdown>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.</p>
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) |
<p class="nj-table-caption" markdown>Deprecated functions, with the release that deprecated each one and the section of the migration guide that shows its replacement.</p>
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.
+782
View File
@@ -0,0 +1,782 @@
/* 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;
}
/* ---- 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; }
}
+142
View File
@@ -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; }
+75
View File
@@ -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); }
+176
View File
@@ -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); }
+107
View File
@@ -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); }
}
+98
View File
@@ -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; }
}
+459
View File
@@ -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); }
+207
View File
@@ -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); }
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><g font-family='Menlo,monospace' font-size='26' font-weight='600' fill='#ffffff' fill-opacity='0.10'><text x='14' y='34'>{</text><text x='92' y='22'>]</text><text x='136' y='60'>:</text><text x='52' y='82'>[</text><text x='118' y='112'>,</text><text x='20' y='140'>}</text><text x='78' y='150'>:</text><text x='140' y='158'>{</text></g></svg>

After

Width:  |  Height:  |  Size: 408 B

+1 -1
View File
@@ -2,7 +2,7 @@
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -2,7 +2,7 @@
#include <vector>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
+3 -3
View File
@@ -2,19 +2,19 @@
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
// a valid JSON text
auto valid_text = R"(
const auto* valid_text = R"(
{
"numbers": [1, 2, 3]
}
)";
// an invalid JSON text
auto invalid_text = R"(
const auto* invalid_text = R"(
{
"strings": ["extra", "comma", ]
}
@@ -2,7 +2,7 @@
#include <string>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
+1 -1
View File
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
+2 -2
View File
@@ -2,9 +2,9 @@
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
std::cout << std::boolalpha << std::is_same<std::vector<json>, json::array_t>::value << std::endl;
std::cout << std::boolalpha << std::is_same<std::vector<json>, json::array_t>::value << '\n';
}
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
using namespace nlohmann::literals;
int main()
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
using namespace nlohmann::literals;
int main()
@@ -3,7 +3,7 @@
#include <nlohmann/json.hpp>
using namespace std::string_view_literals;
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -3,7 +3,7 @@
#include <nlohmann/json.hpp>
using namespace std::string_view_literals;
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
+1 -1
View File
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
+1 -1
View File
@@ -1,7 +1,7 @@
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
Loaded 100 of 601 files, more files were not shown because too many files have changed in this diff. Show more