From 3a79e89d7c8b01179d64051ea51ab806fb7937b8 Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:07:49 +0900 Subject: [PATCH 1/7] add README badges to link the documentations --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 9a4d138..e8ef059 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A Julia package for reading and writing JSON data. +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliaio.github.io/JSON.jl/stable) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliaio.github.io/JSON.jl/dev) [![Build Status](https://github.com/JuliaIO/JSON.jl/workflows/CI/badge.svg)](https://github.com/JuliaIO/JSON.jl/actions/workflows/CI.yml?query=branch%3Amaster) [![codecov.io](http://codecov.io/github/JuliaIO/JSON.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaIO/JSON.jl?branch=master) From cbfed0be62c75762649ea87fd12cdfeab0917ae1 Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:08:35 +0900 Subject: [PATCH 2/7] use `julia-repl` syntax highlighting --- docs/src/reading.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/reading.md b/docs/src/reading.md index 8e18eb7..cbbba55 100644 --- a/docs/src/reading.md +++ b/docs/src/reading.md @@ -39,7 +39,7 @@ Each entrypoint function first calls `JSON.lazy`, which will consume the JSON in So what can we do with a `JSON.LazyValue`? -```julia +```julia-repl julia> x = JSON.lazy("{\"a\": 1, \"b\": null, \"c\": true, \"d\": false, \"e\": \"\", \"f\": [1,2,3], \"g\": {\"h\":{\"i\":\"foo\"}}}") LazyObject{String} with 7 entries: "a" => JSON.LazyValue(1) @@ -55,7 +55,7 @@ Note that for convenience at the REPL, special `show` overloads enable displayin `LazyValue`s support convenient syntax for both _navigating_ their structure and _materializing_, with an aim to support lazy workflows. Examples include: -```julia +```julia-repl # convenient "get" syntax on lazy objects julia> x.a JSON.LazyValue(1) @@ -115,7 +115,7 @@ Ok, but at some point, we _do_ actually need Julia values to operate on, so let' In the `LazyValue` syntax example, it was shown that empty `getindex` will result in a "default" materialization of a `LazyValue`: -```julia +```julia-repl julia> x[] JSON.Object{String, Any} with 7 entries: "a" => 1 From 596e390b854e70ed0a52e460647c2519deb7de22 Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:12:31 +0900 Subject: [PATCH 3/7] tables should be left-aligned! --- docs/src/reading.md | 4 ++-- docs/src/writing.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/reading.md b/docs/src/reading.md index cbbba55..f52db3a 100644 --- a/docs/src/reading.md +++ b/docs/src/reading.md @@ -19,7 +19,7 @@ There are several "entrypoints" to reading JSON in JSON.jl, including: These functions are all built to accept the same kinds of JSON inputs: | Accepted `json` sources | Notes | -|--------------------------------------------|---------------------------------------------------| +|:-------------------------------------------|:--------------------------------------------------| | `AbstractString` | UTF‑8; UTF‑8‑BOM handled automatically | | `AbstractVector{UInt8}` | zero‑copy if already bytes | | `IO`, `IOStream`, `Base.AbstractCmd` | stream fully read into a byte vector | @@ -130,7 +130,7 @@ JSON.Object{String, Any} with 7 entries: Under the hood, this `getindex` call is really calling `JSON.parse(lazyvalue)`. `JSON.parse` can also be called as a main entrypoint function with all the same input types as `JSON.lazy`. This form of `parse` is referred to as "untyped parsing" or "untyped materialization". It allocates and _materializes_ the raw JSON values into appropriate "default" Julia-level values. In particular: | JSON construct | Default Julia value | -|----------------|---------------------------------------------------------------------------| +|:---------------|:--------------------------------------------------------------------------| | object | `JSON.Object{String,Any}` (order‑preserving drop-in replacement for Dict) | | array | `Vector{Any}` | | string | `String` | diff --git a/docs/src/writing.md b/docs/src/writing.md index 982d646..ae17356 100644 --- a/docs/src/writing.md +++ b/docs/src/writing.md @@ -26,7 +26,7 @@ JSON.json(file_name::String, x) -> String The `JSON.json` function accepts a wide range of Julia types and transforms them into their JSON representation by knowing how to serialize a core set of types: | Julia type | JSON representation | -|------------------------------------|------------------------------------------| +|:-----------------------------------|:------------------------------------------| | `Nothing` | `null` | | `Bool` | `true` or `false` | | `Number` | Numeric value (integer or floating point) | From 191eadc12f6c5d87d68f0ab0254fad41325dc9b6 Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:37:36 +0900 Subject: [PATCH 4/7] add `@ref`s to the documentation --- docs/src/migrate.md | 10 +++++----- docs/src/reading.md | 18 +++++++++--------- docs/src/writing.md | 12 ++++++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/src/migrate.md b/docs/src/migrate.md index 55af95d..1652644 100644 --- a/docs/src/migrate.md +++ b/docs/src/migrate.md @@ -7,7 +7,7 @@ This guide provides an overview of how to migrate your code from either the pre- ## Migration guide from pre-1.0 -> 1.0 ### Writing JSON -- `JSON.json` +- [`JSON.json`](@ref) - What stayed the same: - Produces a compact String by default - Can automatically serialize basic structs in a sensible way @@ -33,7 +33,7 @@ This guide provides an overview of how to migrate your code from either the pre- - Utilizing multiple dispatch to combine `JSON.print` and `JSON.json` and provide convenience for writing to files - Most opened issues over the last few years were about providing more controls around writing JSON without having to completely implement a custom serializer - More consistency with `JSON.parse` keyword args with `allownan` and `jsonlines` -- `JSON.print` +- [`JSON.print`](@ref) - What stayed the same: - Technically still defined for backwards compatibility, but just calls `JSON.json` under the hood - Why the changes: @@ -55,12 +55,12 @@ This guide provides an overview of how to migrate your code from either the pre- - There was often confusion about whether a custom Serialization or StructuralContext was needed and what intefaces were then required to implement - The need to customize separators, delimiters, and indentation, while powerful, can be accomplished much simpler via keyword arguments or is not necessary at all (i.e. JSON.jl shouldn't be too concerned with how to produce anything that isn't JSON) - Instead of overloading show_string/show_element/show_key/show_pair/show_json, `lower` can be used to accomplish any requirements of "overloading" how values are serialized; the addition of "styles" also allows customizing for non-owned types instead of needing a custom context + `show_json` method -- `JSONText` +- [`JSONText`](@ref) - What changed: - Nothing; `JSONText` can still be used to have a JSON-formatted string be written as-is when serializing ### Reading JSON -- `JSON.parse` / `JSON.parsefile` +- [`JSON.parse`](@ref) / [`JSON.parsefile`](@ref) - What stayed the same: - These functions take the same JSON input arguments (String, IO, or filename for `parsefile`) - The `dicttype`, `allownan`, and `null` keyword arguments all remain and implement the same functionality @@ -75,7 +75,7 @@ This guide provides an overview of how to migrate your code from either the pre- - The `inttype` keyword argument is rare among other JSON libraries and doesn't serve a strong purpose; memory gains from possibly using smaller ints is minimal and leads to more error-prone code via overflows by trying to force integers into non-standard small types - For the `allownan` default value change, there are many benchmarks/JSON-accuracy checking test suites that enforce adherance to the specification; following the specification by default is recommended and common across language JSON libraries - Mmapping is an internal detail that most users shouldn't worry about anyway, and it can be done transparently without any outside affect to the user -- `JSONText` +- [`JSONText`](@ref) - `JSONText` can now also be used while parsing, as a field type of a struct or directly to return the raw JSON (similar to how writing with `JSONText` works) ## Migration guide for JSON3.jl diff --git a/docs/src/reading.md b/docs/src/reading.md index f52db3a..d007259 100644 --- a/docs/src/reading.md +++ b/docs/src/reading.md @@ -11,10 +11,10 @@ This guide to reading JSON in the JSON.jl package aims to: ## Core JSON Parsing - `JSON.lazy` and `JSON.LazyValue` There are several "entrypoints" to reading JSON in JSON.jl, including: - - `JSON.parse`/`JSON.parse!` - - `JSON.parsefile`/`JSON.parsefile!` - - `JSON.lazy`/`JSON.lazyfile` - - `JSON.isvalidjson` + - [`JSON.parse`](@ref)/`JSON.parse!` + - [`JSON.parsefile`](@ref)/[`JSON.parsefile!`](@ref) + - [`JSON.lazy`](@ref)/[`JSON.lazyfile`](@ref) + - [`JSON.isvalidjson`](@ref) These functions are all built to accept the same kinds of JSON inputs: @@ -26,18 +26,18 @@ These functions are all built to accept the same kinds of JSON inputs: The core JSON parsing machinery is hence built around having an `AbstractVector{UInt8}` or `AbstractString` JSON input where individual bytes can be parsed to identify JSON structure, validate syntax, and ultimately produce Julia-level values. -Each entrypoint function first calls `JSON.lazy`, which will consume the JSON input until the type of the next JSON value can be identified (`{` for objects, `[` for arrays, `"` for strings, `t` for true, `f` for false, `n` for null, and `-` or a digit for numbers). `JSON.lazy` returns a `JSON.LazyValue`, which wraps the JSON input buffer (`AbstractVector{UInt8}` or `AbstractString`), and marks the byte position the value starts at, the type of the value, and any keyword arguments that were provided that may affect parsing. Currently supported parsing-specific keyword arguments to `JSON.lazy` (and thus all other entrypoint functions) include: +Each entrypoint function first calls [`JSON.lazy`](@ref), which will consume the JSON input until the type of the next JSON value can be identified (`{` for objects, `[` for arrays, `"` for strings, `t` for true, `f` for false, `n` for null, and `-` or a digit for numbers). [`JSON.lazy`](@ref) returns a [`JSON.LazyValue`](@ref), which wraps the JSON input buffer (`AbstractVector{UInt8}` or `AbstractString`), and marks the byte position the value starts at, the type of the value, and any keyword arguments that were provided that may affect parsing. Currently supported parsing-specific keyword arguments to [`JSON.lazy`](@ref) (and thus all other entrypoint functions) include: - `allownan::Bool = false`: whether "special" float values shoudl be allowed while parsing (`NaN`, `Inf`, `-Inf`); these values are specifically _not allowed_ in the JSON spec, but many JSON libraries allow reading/writing - `ninf::String = "-Infinity"`: the string that will be used to parse `-Inf` if `allownan=true` - `inf::String = "Infinity"`: the string that will be used to parse `Inf` if `allownan=true` - `nan::String = "NaN"`: the string that will be sued to parse `NaN` if `allownan=true` - - `jsonlines::Bool = false`: whether the JSON input should be treated as an implicit array, with newlines separating individual JSON elements with no leading `'['` or trailing `']'` characters. Common in logging or streaming workflows. Defaults to `true` when used with `JSON.parsefile` and the filename extension is `.jsonl` or `ndjson`. Note this ensures that parsing will _always_ return an array at the root-level. + - `jsonlines::Bool = false`: whether the JSON input should be treated as an implicit array, with newlines separating individual JSON elements with no leading `'['` or trailing `']'` characters. Common in logging or streaming workflows. Defaults to `true` when used with [`JSON.parsefile`](@ref) and the filename extension is `.jsonl` or `ndjson`. Note this ensures that parsing will _always_ return an array at the root-level. - Materialization-specific keyword arguments (i.e. they affect materialization, but not parsing) - `dicttype = JSON.Object{String, Any}`: type to parse JSON objects as by default (recursively) - `null = nothing`: value to return for JSON `null` value -So what can we do with a `JSON.LazyValue`? +So what can we do with a [`JSON.LazyValue`](@ref)? ```julia-repl julia> x = JSON.lazy("{\"a\": 1, \"b\": null, \"c\": true, \"d\": false, \"e\": \"\", \"f\": [1,2,3], \"g\": {\"h\":{\"i\":\"foo\"}}}") @@ -127,7 +127,7 @@ JSON.Object{String, Any} with 7 entries: "g" => Object{String, Any}("h"=>Object{String, Any}("i"=>"foo")) ``` -Under the hood, this `getindex` call is really calling `JSON.parse(lazyvalue)`. `JSON.parse` can also be called as a main entrypoint function with all the same input types as `JSON.lazy`. This form of `parse` is referred to as "untyped parsing" or "untyped materialization". It allocates and _materializes_ the raw JSON values into appropriate "default" Julia-level values. In particular: +Under the hood, this `getindex` call is really calling `JSON.parse(lazyvalue)`. [`JSON.parse`](@ref) can also be called as a main entrypoint function with all the same input types as [`JSON.lazy`](@ref). This form of `parse` is referred to as "untyped parsing" or "untyped materialization". It allocates and _materializes_ the raw JSON values into appropriate "default" Julia-level values. In particular: | JSON construct | Default Julia value | |:---------------|:--------------------------------------------------------------------------| @@ -145,7 +145,7 @@ Because `Object` uses a linked-list implementation, key lookups are `O(n)`, perf ## `JSON.parse` - Typed materialization -While untyped materialization is convenient for quick exploration, one of the most powerful features of JSON.jl is its ability to directly parse JSON into concrete Julia types. This is done by providing a type as the second argument to `JSON.parse` and opens up a world of type-safe JSON parsing with minimal boilerplate. +While untyped materialization is convenient for quick exploration, one of the most powerful features of JSON.jl is its ability to directly parse JSON into concrete Julia types. This is done by providing a type as the second argument to [`JSON.parse`](@ref) and opens up a world of type-safe JSON parsing with minimal boilerplate. ### Basic usage with structs diff --git a/docs/src/writing.md b/docs/src/writing.md index ae17356..7b43242 100644 --- a/docs/src/writing.md +++ b/docs/src/writing.md @@ -10,7 +10,7 @@ This guide to writing JSON in the JSON.jl package aims to: ## Core JSON Serialization - `JSON.json` -The main entrypoint for serializing Julia values to JSON in JSON.jl is the `JSON.json` function. This function offers flexible output options: +The main entrypoint for serializing Julia values to JSON in JSON.jl is the [`JSON.json`](@ref) function. This function offers flexible output options: ```julia # Serialize to a String @@ -23,7 +23,7 @@ JSON.json(io::IO, x) -> IO JSON.json(file_name::String, x) -> String ``` -The `JSON.json` function accepts a wide range of Julia types and transforms them into their JSON representation by knowing how to serialize a core set of types: +The [`JSON.json`](@ref) function accepts a wide range of Julia types and transforms them into their JSON representation by knowing how to serialize a core set of types: | Julia type | JSON representation | |:-----------------------------------|:------------------------------------------| @@ -40,11 +40,11 @@ For values that don't fall into one of the above categories, `JSON.lower` will b ## Customizing JSON Output -`JSON.json` supports numerous keyword arguments to control how data is serialized: +[`JSON.json`](@ref) supports numerous keyword arguments to control how data is serialized: ### Pretty Printing -By default, `JSON.json` produces compact JSON without extra whitespace. For human-readable output: +By default, [`JSON.json`](@ref) produces compact JSON without extra whitespace. For human-readable output: ```julia # Boolean flag for default pretty printing (2-space indent) @@ -355,7 +355,7 @@ JSON.json(config) ## Handling Circular References -`JSON.json` automatically detects circular references to prevent infinite recursion: +[`JSON.json`](@ref) automatically detects circular references to prevent infinite recursion: ```julia mutable struct Node @@ -374,7 +374,7 @@ JSON.json(node; omit_null=false) ## Custom Dictionary Key Serialization -For dictionaries with non-string keys, `JSON.json` has a few default `lowerkey` definitions to convert keys to strings: +For dictionaries with non-string keys, [`JSON.json`](@ref) has a few default `lowerkey` definitions to convert keys to strings: ```julia # Integer keys From 407691356ed2c68d1fa7e310fc28a653f3e622d8 Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:39:49 +0900 Subject: [PATCH 5/7] we don't need `@contents` blocks except for top page --- docs/src/reading.md | 3 --- docs/src/reference.md | 3 --- docs/src/writing.md | 3 --- 3 files changed, 9 deletions(-) diff --git a/docs/src/reading.md b/docs/src/reading.md index d007259..24de52f 100644 --- a/docs/src/reading.md +++ b/docs/src/reading.md @@ -4,9 +4,6 @@ This guide to reading JSON in the JSON.jl package aims to: - Provide a comprehensive overview of the JSON reading process. - Explain the various options and configurations available for reading JSON data. - Offer practical examples to illustrate the usage of different functions and options. - -```@contents -``` ## Core JSON Parsing - `JSON.lazy` and `JSON.LazyValue` diff --git a/docs/src/reference.md b/docs/src/reference.md index e99a5af..7348666 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -1,8 +1,5 @@ # API Reference -```@contents -``` - ```@autodocs Modules = [JSON] ``` diff --git a/docs/src/writing.md b/docs/src/writing.md index 7b43242..9678a03 100644 --- a/docs/src/writing.md +++ b/docs/src/writing.md @@ -5,9 +5,6 @@ This guide to writing JSON in the JSON.jl package aims to: - Explain the various options and configurations available for writing JSON data. - Offer practical examples to illustrate the usage of different functions and options. -```@contents -``` - ## Core JSON Serialization - `JSON.json` The main entrypoint for serializing Julia values to JSON in JSON.jl is the [`JSON.json`](@ref) function. This function offers flexible output options: From ad975e51b4383e5660af46f691115fce187466fe Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:44:26 +0900 Subject: [PATCH 6/7] sort sections --- docs/make.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index a95f09a..cb0ebfa 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,5 +1,15 @@ using Documenter, JSON -makedocs(modules = [JSON], sitename = "JSON.jl") +makedocs( + modules = [JSON], + sitename = "JSON.jl", + pages = [ + "Home" => "index.md", + "JSON Writing" => "writing.md", + "JSON Reading" => "reading.md", + "Migration Guides" => "migrate.md", + "API Reference" => "reference.md", + ], +) deploydocs(repo = "github.com/JuliaIO/JSON.jl.git", push_preview = true) From efd2f0cd77b3dedf8d8bc2cea88e7f0e3dc3f1c2 Mon Sep 17 00:00:00 2001 From: Horikawa Yuto Date: Fri, 21 Nov 2025 01:44:45 +0900 Subject: [PATCH 7/7] guides -> Guides --- docs/src/migrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/migrate.md b/docs/src/migrate.md index 1652644..21e005c 100644 --- a/docs/src/migrate.md +++ b/docs/src/migrate.md @@ -1,4 +1,4 @@ -# Migration guides +# Migration Guides This guide provides an overview of how to migrate your code from either the pre-1.0 JSON.jl package to the 1.0 release or from JSON3.jl. The 1.0 release introduces several improvements and changes, particularly in how JSON is read and written, leveraging StructUtils.jl for customization and extensibility. Below, we outline the key differences and provide step-by-step instructions for updating your code.