Skip to content

rpatters1/mnxdom

Repository files navigation

mnxdom

Document object model for the MNX music interchange format. It is compatible with the C++17 standard.

  • compatible with the C++17 standard and higher. (Currently tested with C++23.)
  • uses nlohmann_json as its JSON parser.
  • allows structured access to MNX objects, without the need of quoted strings.
  • validates against the MNX schema using json-schema-validator.
  • no class serialization beyond nlohmann.
  • every MNX class is a wrapper around the root JSON object and a pointer to the location of the instance.

Documentation

MNX Document Model for C++17

Here is a simple example of code that creates the Hello World MNX JSON file.

// create new document
auto doc = mnx::Document(); // automatically creates required child nodes
// global
auto globalMeasure = doc.global().measures().append();
// required fields are supplied when objects are created
globalMeasure.create_barline(mnx::BarlineType::Regular);
globalMeasure.create_time(4, mnx::TimeSignatureUnit::Quarter);
// parts
auto part = doc.parts().append();
auto measure = part.create_measures().append();
measure.create_clefs().append(mnx::ClefSign::GClef, -2, std::nullopt);
auto event = measure.sequences()
    .append()
    .content()
    .append<mnx::sequence::Event>(mnx::NoteValueBase::Whole);
event.create_notes().append(mnx::sequence::Pitch::make(mnx::NoteStep::C, 4));
// save to file
doc.save("hello-world.json", 4); // indent with 4 spaces

Note that this code never uses references. Since every MNX class in the model is a lightweight wrapper around a root JSON object and a pointer to its location, copying them is extremely cheap. The class instance returned by any method is a temporary instance. Using references on return values can result in undefined behavior.

Setup Instructions

Via FetchContent

Include the top header in your source file.

#include "mnxdom.h"

Add the libary to your project with FetchContent:

include(FetchContent)

FetchContent_Declare(
  musx
  GIT_REPOSITORY https://github.com/rpatters1/mnxdom
  GIT_TAG main # Replace with the desired commit hash, tag, or branch
)
FetchContent_MakeAvailable(musx)

# Also add somewhere:
target_link_libraries(project PRIVATE mnxdom) # replace "project" with your actual project name

Via a system installation

Install the library using:

sudo cmake --install build

This should install:

  • Headers in /usr/local/include/mnxdom
  • pkg-config file in /usr/local/lib/pkgconfig/mnxdom.pc

If you use cmake in your project, and assuming pkg-config on your system is configured to look for files in /usr/local/lib/pkgconfig too, you can use:

  find_package(PkgConfig REQUIRED)
  pkg_check_modules(mnxdom REQUIRED IMPORTED_TARGET mnxdom)
  target_link_libraries(project PRIVATE PkgConfig::mnxdom)

And include the top header in your source file with:

#include <mnxdom/mnxdom.h>

Dependencies

The dependencies pboettch/json-schema-validator and nlohmann/json are required by mnxdom. If you wish mnxdom to use the system versions of either of these dependencies, configure mnxdom with the following CMake flags:

-DUSE_SYSTEM_NLOHMANN_JSON=ON
-DUSE_SYSTEM_JSON_SCHEMA_VALIDATOR=ON

mnxdom vendors the W3C MNX schema and example JSON files in third_party/w3c-mnx. These files are not fetched during the build. To update them from the current main branch of the W3C MNX repository, run:

scripts/update-w3c-mnx.sh

To update to a specific upstream commit or ref of the w3c repository, pass it as an argument. The resolved commit is recorded in third_party/w3c-mnx/UPSTREAM_COMMIT.

Package Builds

Package creators should configure mnxdom so that the build does not download dependencies from the internet. Use system-provided copies of nlohmann/json and json-schema-validator:

cmake -S . -B build \
  -DUSE_SYSTEM_NLOHMANN_JSON=ON \
  -DUSE_SYSTEM_JSON_SCHEMA_VALIDATOR=ON \
  -Dmnxdom_BUILD_TESTING=OFF

If package builds run the test suite, also use a system-provided GoogleTest:

cmake -S . -B build \
  -DUSE_SYSTEM_NLOHMANN_JSON=ON \
  -DUSE_SYSTEM_JSON_SCHEMA_VALIDATOR=ON \
  -DUSE_SYSTEM_GOOGLETEST=ON

The W3C MNX schema and examples are vendored in third_party/w3c-mnx, so CMake does not fetch them. Do not run scripts/update-w3c-mnx.sh during a package build; that script is for maintainers updating the vendored snapshot before a release.

mnxdom records its own version and, when available, its source commit in generated MNX provenance. When building from a source tree without .git, whoever builds mnxdom may provide the source revision explicitly. This includes package creators and client projects that vendor mnxdom or bring it in with CMake FetchContent:

-DMNXDOM_GIT_COMMIT=<mnxdom-commit>

If MNXDOM_GIT_COMMIT is not supplied and .git is unavailable, the commit field is omitted from the provenance rather than filled with a placeholder.

Package builds may also provide a package or build identifier for mnxdom itself:

-DMNXDOM_BUILD_ID=<mnxdom-build-id>

This value is recorded as mnxdom.build in provenance. Client application build metadata should be recorded separately in the client provenance fields.

To Run the Tests

You need cmake to build and run the tests. From the directory containing this repository, configure the build directory:

cmake -S . build

To build the tests:

cmake --build build

To run the tests:

ctest --test-dir build

To Build the Documentation

You need Doxygen to create the documentation. You can download and run the installer from the Doxygen site. Package managers can also install it. Once you have Doxygen you can build the documentation as follows.

cd docs
doxygen Doxyfile

You will then find an html website in ./docs/generated/html. Use a web browser to view the site from your hard drive. Opening any of the .html pages gives you access to the entire site.

About

MNX Document Object Model for C++17

Resources

License

Stars

5 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors

Languages