Examples » JSON pretty-printer new in Git master

Uses Utility::Json and Utility::JsonWriter to reformat a JSON file.

The Utility::Json class by default only tokenizes the input without actually parsing anything. While such raw token stream isn't directly usable for querying the file contents, it can be passed as-is to Utility::JsonWriter::writeJson(Utility::JsonToken), allowing for efficient pretty-printing of minified JSON files and vice versa. Here's the code in full, complete with using Utility::Arguments to expose a bunch of formatting options:

#include <Corrade/Containers/Optional.h>
#include <Corrade/Utility/Arguments.h>
#include <Corrade/Utility/Json.h>
#include <Corrade/Utility/JsonWriter.h>

using namespace Corrade;

int main(int argc, char** argv) {
    Utility::Arguments args;
    args.addArgument("file")
            .setHelp("file", "Input JSON file to format")
        .addFinalOptionalArgument("output")
            .setHelp("output", "JSON file to write to instead of standard output")
        .addOption("indent", "2")
            .setHelp("indent", "How many spaces to indent the output with")
        .addBooleanOption("compact")
            .setHelp("compact", "Don't wrap and indent the output")
        .setGlobalHelp("JSON formatter.")
        .parse(argc, argv);

    /* Just tokenize the file without parsing anything */
    const Containers::Optional<Utility::Json> json =
        Utility::Json::fromFile(args.value("file"));
    if(!json)
        /* Utility::Json prints a message already, no need to repeat */
        return 1;

    /* Set up the writer with desired formatting */
    Utility::JsonWriter::Options options;
    if(!args.isSet("compact"))
        options |= Utility::JsonWriter::Option::Wrap|
                   Utility::JsonWriter::Option::TypographicalSpace;
    Utility::JsonWriter writer{options, args.value<unsigned>("indent")};

    /* Pass it the whole input */
    writer.writeJson(json->root());

    /* Write to a file if specified or to standard output */
    if(const Containers::StringView output = args.value("output")) {
        if(!writer.toFile(output))
            /* Again Utility::JsonWriter prints a message already */
            return 1;
    } else Utility::Debug{} << writer.toString();
}

The following CMake commands then produce a corrade-json executable:

find_package(Corrade REQUIRED Utility)
set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)

add_executable(corrade-json main.cpp)
target_link_libraries(corrade-json PRIVATE Corrade::Utility)

Besides JSON being both an input and output, the code could be modified to for example parse a JSON-compatible data representation such as JSON5 or CBOR and output a regular JSON. See the corresponding section in Utility::Json documentation for more information.

The full file content is linked below. Full source code is also available in the GitHub repository.