diff --git a/README.md b/README.md index c4df291..e854f41 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,23 @@ blog/2000-10-30-my-blog-example/ 3. Add your full Markdown blog post content inside the `index.md` file. + * [optional] Add Godbolt links or generate from C++ codeblock: + * If your content includes Godbolt link(s), simply use the `` syntax to generate `Try it on Compiler Explorer 🚀` link(s). + * If your content includes C++ codeblock, you need to include a custom metadata to the codeblock like below: + ``` + ``` cpp { "compilers": ["clang_trunk -std=c++26", "gsnapshot -std=c++26"], "libs": ["beman_optional@trunk"], "filters": {"execute":true} } + // your cpp code + ``` +
+ Metadata reference + + The metadata json object is based on the [Compiler Explorer API](https://github.com/compiler-explorer/compiler-explorer/blob/main/docs/API.md) with custom flavor for easier to write. This metadata json structure is basically `{"compilers": ["CompilerName CompilerFlags"], "libs": ["LibraryId@Version"], "filters": {"execute":true}}` + * The `CompilerName`s you can get from: https://godbolt.org/api/compilers + * The `LibraryId`s you can get from: https://godbolt.org/api/libraries/c++ + +
+ + Example ```shell $ cat blog/2000-10-30-my-blog-example/index.md @@ -66,7 +83,6 @@ socials: # [optional] Include your socials (like your Github, X, Linkedin > Note: The Discourse comments plugin only works for production website (a.k.a. https://bemanproject.org/). You cannot test it locally or on preview deployments. Check [Integrate Discourse comment feature for blog posts](https://github.com/bemanproject/website/issues/25) for more details. - 4. Open a `DRAFT PR` and `wait` up to one minute for a preview deployment of your blog post. * Draft PR example: [Add blog post: My Blog Example #54](https://github.com/bemanproject/website/pull/54/). diff --git a/docs/libs/beman.optional/index.md b/docs/libs/beman.optional/index.md new file mode 100644 index 0000000..dbf09fd --- /dev/null +++ b/docs/libs/beman.optional/index.md @@ -0,0 +1,324 @@ +# beman.optional: C++26 Extensions for std::optional + + + + + ![CI Tests](https://github.com/bemanproject/optional/actions/workflows/ci.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/optional/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/optional?branch=main) + + +This repository implements `std::optional` extensions targeting C++26. The `beman.optional` library aims to evaluate the stability, the usability, and the performance of these proposed changes before they are officially adopted by WG21 into the C++ Working Draft. Additionally, it allows developers to use these new features before they are implemented in major standard library compilers. + +**Implements**: [Give *std::optional* Range Support (P3168R2)](https://wg21.link/P3168R2) and [`std::optional` (P2988R5)](https://wg21.link/P2988R5) + +**Status**: [Production ready. API may undergo changes.](../../beman_library_maturity_model.md#production-ready-api-may-undergo-changes) + +## License + +Source is licensed with the Apache 2.0 license with LLVM exceptions + +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +Documentation and associated papers are licensed with the Creative Commons Attribution 4.0 International license. + +// SPDX-License-Identifier: CC-BY-4.0 + +The intent is that the source and documentation are available for use by people implementing their own optional types as well as people using the optional presented here as-is. + +The README itself is licensed with CC0 1.0 Universal. Copy the contents and incorporate in your own work as you see fit. + +// SPDX-License-Identifier: CC0-1.0 + +## Examples + +Full runnable examples can be found in `examples/` - please check [./examples/README.md](https://github.com/bemanproject/optional/blob/main/examples/README.md). + +### range_loop + +The next code snippet shows optional range support added in [Give *std::optional* Range Support(P3168R2)](https://wg21.link/P3168R2): + +```cpp +#include +... + +beman::optional::optional empty_opt{}; +for ([[maybe_unused]] const auto& i : empty_opt) { + // Should not see this in console. + std::cout << "\"for each loop\" over C++26 optional: empty_opt\n"; +} + +beman::optional::optional opt{26}; +for (const auto& i : opt) { + // Should see this in console. + std::cout << "\"for each loop\" over C++26 optional: opt = " << i << "\n"; +} +``` + +Full code can be found in [./examples/range_loop.cpp](https://github.com/bemanproject/optional/blob/main/examples/range_loop.cpp). Build and run instructions in +[./examples/README.md](https://github.com/bemanproject/optional/blob/main/examples/README.md). + +```cpp { "compilers": ["clang_trunk -std=c++26", "gsnapshot -std=c++26"], "libs": ["beman_optional@trunk"], "filters": {"execute":true} } +// examples/range_loop.cpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +int main() { + // Example from P3168R1: basic range loop over C++26 optional. + + beman::optional::optional empty_opt{}; + for ([[maybe_unused]] const auto& i : empty_opt) { + // Should not see this in console. + std::cout << "\"for each loop\" over C++26 optional: empty_opt\n"; + } + + beman::optional::optional opt{__cplusplus}; + for (const auto& i : opt) { + // Should see this in console. + std::cout << "\"for each loop\" over C++26 optional: opt = " << i << "\n"; + } + + return 0; +} + +// # build example: +// $ cmake --workflow --preset gcc-14 +// +// # run example: +// $ .build/gcc-14/examples/RelWithDebInfo/range_loop +// # note: 1st log (empty_opt) is missing from console! +// "for each loop" over C++26 optional: opt = 26 # 2nd log (non empty opt) +``` + +### optional_ref + +The next code snippet shows optional reference support added in [`std::optional` +(P2988)](https://wg21.link/P2988): + +```cpp +#include +... + +struct Cat { ... }; + +beman::optional::optional find_cat(std::string) { return {}; } +beman::optional::optional do_it(Cat& cat) { return { cat }; } + +beman::optional::optional api() { + beman::optional::optional cat = find_cat("Fido"); + return cat.and_then(do_it); +} + +beman::optional::optional cat = api(); + +``` + +Full code can be found in [./examples/optional_ref.cpp](https://github.com/bemanproject/optional/blob/main/examples/optional_ref.cpp). Build and run instructions in [./examples/README.md](https://github.com/bemanproject/optional/blob/main/examples/README.md). Or try it on Compiler Explorer: + +## How to Build + +### Compiler Support + +This is a modern C++ project which can be compiled with the latest C++ standards (**C++20 or later**). + +Default build: `C++23`. Please check `etc/${compiler}-flags.cmake`. + +### Dependencies + +This project is mainly tested on `Ubuntu 22.04` and `Ubuntu 24.04`, but it should be as portable as CMake is. This project has no C or C++ dependencies. + +Build-time dependencies: + +* `cmake` +* `ninja`, `make`, or another CMake-supported build system + * CMake defaults to "Unix Makefiles" on POSIX systems + +Example of installation on `Ubuntu 24.04`: + +```shell +# Install tools: +apt-get install -y cmake make ninja-build + +# Example of toolchains: +apt-get install \ + g++-14 gcc-14 gcc-13 g++-13 \ + clang-18 clang++-18 clang-17 clang++-17 +``` + +
+ Build GoogleTest dependency from github.com + +If you do not have GoogleTest installed on your development system, you may +optionally configure this project to download a known-compatible release of +GoogleTest from source and build it as well. + +```shell +cmake -B build -S . -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./cmake/use-fetch-content.cmake +``` + +The precise version of GoogleTest that will be used is maintained in +`./lockfile.json`. + +
+ +### Instructions + +Full set of supported toolchains can be found in [.github/workflows/ci.yml](https://github.com/bemanproject/optional/blob/main/.github/workflows/ci.yml). + +#### Preset CMake Flows + +This project strives to be as normal and simple a CMake project as possible. This build workflow in particular will work, producing a static `beman_optional` library, ready to package: + +```shell +# List available preset configurations: +$ cmake --workflow --list-presets +Available workflow presets: + + "system" + "gcc-14" + "gcc-13" + "clang-18" + "clang-17" + +# Run examples: +$ cmake --workflow --preset gcc-14 +cmake --workflow --preset gcc-14 +Executing workflow step 1 of 3: configure preset "gcc-14" +... +-- Build files have been written to: /path/to/repo/.build/gcc-14 + +Executing workflow step 2 of 3: build preset "gcc-14" + +ninja: no work to do. + +Executing workflow step 3 of 3: test preset "gcc-14" + +Test project /path/to/repo/.build/gcc-14 + Start 1: OptionalTest.TestGTest + 1/... Test #1: OptionalTest.TestGTest ........................... Passed 0.00 sec +... + Start x: RangeSupportTest.RangeConcepts +.../... Test #x: RangeSupportTest.RangeConcepts ................... Passed 0.00 sec + Start x+1: RangeSupportTest.IteratorConcepts +.../... Test #x+1: RangeSupportTest.IteratorConcepts ................ Passed 0.00 sec +... + +100% tests passed, 0 tests failed out of ... + +Total Test time (real) = 0.09 sec +``` + +This should build and run the tests with GCC 14 with the address and undefined behavior sanitizers enabled. + +#### Custom CMake Flows + +##### Build and Run Tests + +CI current build and test flows: + +```shell +# Configure build: default build production code + tests (OPTIONAL_ENABLE_TESTING=ON by default). +$ cmake -G "Ninja Multi-Config" \ + -DCMAKE_CONFIGURATION_TYPES="RelWithDebInfo;Asan" \ + -DCMAKE_TOOLCHAIN_FILE=etc/clang-19-toolchain.cmake \ + -B .build -S . +-- The CXX compiler identification is Clang 19.0.0 +... +-- Build files have been written to: /path/to/optional/.build + +# Build. +$ cmake --build .build --config Asan --target all -- -k 0 +... +[30/30] Linking CXX executable ... # Note: 30 targets here (including tests). + +# Run tests. +$ ctest --build-config Asan --output-on-failure --test-dir .build +Internal ctest changing into directory: /path/to/optional/.build +Test project /path/to/optional/.build +... +100% tests passed, 0 tests failed out of 82 + +Total Test time (real) = 0.67 sec +``` + +##### Build Production, but Skip Tests + +By default, we build and run tests. You can provide `-DOPTIONAL_ENABLE_TESTING=OFF` and completely disable building tests: + +```shell +# Configure build: build production code, skip tests (OPTIONAL_ENABLE_TESTING=OFF). +$ cmake -G "Ninja Multi-Config" \ + -DCMAKE_CONFIGURATION_TYPES="RelWithDebInfo;Asan" \ + -DCMAKE_TOOLCHAIN_FILE=etc/clang-19-toolchain.cmake \ + -DOPTIONAL_ENABLE_TESTING=OFF \ + -B .build -S . +-- The CXX compiler identification is Clang 19.0.0 +... +-- Build files have been written to: /path/to/optional/.build + +# Build. +$ cmake --build .build --config Asan --target all -- -k 0 +... +[15/15] Linking CXX executable ... # Note: 15 targets here (tests were not built). + +# Check that tests are not built/installed. +$ ctest --build-config Asan --output-on-failure --test-dir .build +Internal ctest changing into directory: /path/to/beman.optional/.build +Test project /path/to/beman.optional/.build +No tests were found!!! +``` + +#### Pre-Commit for Linting + +Various linting tools are configured and installed via the [pre-commit](https://pre-commit.com/) framework. This requires a working python environment, but also allows the tools, such as clang-format and cmake-lint, to be versioned on a per project basis rather than being installed globally. Version changes in lint checks often means differences in success or failure between the versions in CI and the versions used by a developer. By using the same configurations, this problem is avoided. + +In order to set up a python environment, using a python virtual environment can simplify maintaining different configurations between projects. There is no particular dependency on a particular python3 version. + +##### Creating and configuring a venv + +```shell +python3 -m venv .venv +. .venv/bin/activate && python3 -m pip install --upgrade pip setuptools wheel +. .venv/bin/activate && python3 -m pip install pip-tools +. .venv/bin/activate && python3 -m piptools sync requirements.txt +. .venv/bin/activate && python3 -m piptools sync requirements-dev.txt +. .venv/bin/activate && exec bash +``` + +This will create the venv, install the python and python development tools, and run bash with the PATH and other environment variables set to use the venv preferentially. + +##### Running the linting tools + +```shell +pre-commit run -a +``` + +This will download and configure the lint tools specified in .pre-commit-config.yaml. + +There is also a Makefile that will automate this process and keep everything up to date. + +```shell +make lint +``` + +## Papers + +Latest revision(s) of the papers can be built / found at: + +* [give-std-optional-range-support](https://github.com/neatudarius/give-std-optional-range-support/) for +`Give *std::optional* Range Support (P3168)` + * issue: [#1831](https://github.com/cplusplus/papers/issues/1831) + * LEWG: + * Reviewed in Tokyo 2024. + * Forwarded by LEWG April electronic poll to LWG. + * LWG: + * Reviewed and approved in Saint Louis 2024. +* [./papers/P2988/README.md](https://github.com/bemanproject/optional/blob/main/papers/P2988/README.md) for `std::optional (P2988)`. + * issue: [#1661](https://github.com/cplusplus/papers/issues/1661) + * LEWG: + * Reviewed in Tokyo 2024. + * Forwarded by LEWG in 2025 in Hagenberg. diff --git a/docs/libs/index.md b/docs/libs/index.md new file mode 100644 index 0000000..cd640a8 --- /dev/null +++ b/docs/libs/index.md @@ -0,0 +1,26 @@ +--- +title: Beman Libraries +slug: libraries +--- + +# Beman Libraries + +Below is a table of all libraries within The Beman Project and their current status. + +| Beman Library Name | Status | Description | +|---------------------|----------------------------------------------------|-------------| +| [beman.exemplar](https://github.com/bemanproject/exemplar) | Always an under development library, as it is a template / demo for Beman libraries | A Beman Library Exemplar. | +| | +| [beman.optional](https://github.com/bemanproject/optional) | [Production ready. API may undergo changes.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#production-ready-api-may-undergo-changes) | C++26 Extensions for std::optional. | +| | | +| [beman.any_view](https://github.com/bemanproject/any_view) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) |A generalized type-erased view with customizable properties.| +| [beman.execution](https://github.com/bemanproject/execution) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | Building Block For Asynchronous Programs.| +| [beman.inplace_vector](https://github.com/bemanproject/inplace_vector) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | Dynamically-resizable vector with fixed capacity.| +| [beman.iterator_interface](https://github.com/bemanproject/iterator_interface) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | Iterator creation mechanisms.| +| [beman.lazy](https://github.com/bemanproject/lazy) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | Beman Library Implementation of lazy.| +| [beman.net](https://github.com/bemanproject/net) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | Senders For Network Operations.| +| [beman.scope](https://github.com/bemanproject/scope) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | A generalized type-erased view with customizable properties.| +| [beman.task](https://github.com/bemanproject/task) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | mplementation of task (P3552).| +| [beman.utf_view](https://github.com/bemanproject/utf_view) | [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use) | UTF Transcoding Views.| +| | | +| [beman.dump](https://github.com/bemanproject/dump) | [Retired. No longer maintained or actively developed.](https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#retired-no-longer-maintained-or-actively-developed) | A tool for dumping an object's value to standard output.| diff --git a/docusaurus.config.ts b/docusaurus.config.ts index b204dd0..8527137 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -5,6 +5,8 @@ import { execSync } from 'child_process'; const remarkEmbedder = require('@remark-embedder/core'); const YouTubeTransformer = require('./src/components/youtube-transformer.js'); +const GodboltTransformer = require('./src/components/godbolt-transformer.js'); +const remarkCodeblockMeta = require('./src/plugins/remark-codeblock-meta'); // Note: This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) @@ -22,7 +24,6 @@ try { console.error(`Error determining branch name: ${err}`); } - const config: Config = { title: 'The Beman Project', tagline: @@ -59,7 +60,7 @@ const config: Config = { docs: { sidebarPath: './sidebars.ts', remarkPlugins: [ - [remarkEmbedder, { transformers: [YouTubeTransformer] }], + [remarkEmbedder, { transformers: [YouTubeTransformer, GodboltTransformer] }], remarkCodeblockMeta ], }, blog: { @@ -69,7 +70,7 @@ const config: Config = { xslt: true, }, remarkPlugins: [ - [remarkEmbedder, { transformers: [YouTubeTransformer] }], + [remarkEmbedder, { transformers: [YouTubeTransformer, GodboltTransformer] }], remarkCodeblockMeta ], // Blogging config onInlineTags: 'warn', @@ -83,6 +84,10 @@ const config: Config = { ], ], + clientModules: [ + require.resolve('./src/components/Godbolt.jsx'), + ], + themeConfig: { //TODO: Replace with your project's social card image: './img/beman_logo.png', diff --git a/package.json b/package.json index ed30acc..76651aa 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,9 @@ "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-modal": "^3.16.3", + "unist-util-visit": "^5.0.0" }, "devDependencies": { "@docusaurus/module-type-aliases": "3.7.0", diff --git a/src/components/CodeBlockWithMetadata.jsx b/src/components/CodeBlockWithMetadata.jsx new file mode 100644 index 0000000..5ef2041 --- /dev/null +++ b/src/components/CodeBlockWithMetadata.jsx @@ -0,0 +1,68 @@ +import React from "react"; +import CodeBlock from "@theme/CodeBlock"; +import Godbolt from "./Godbolt"; + +let uniqueID = (function () { + let id = 0; + return function () { return id++; }; +})(); + +export default function CodeBlockWithMetadata({ children, meta, language }) { + const sourceCode = children.trim(); + + let metadata = {}; + try { + metadata = JSON.parse(meta); + if (!metadata.compilers) { + throw new Error("Metadata JSON must include a 'compilers' field."); + } + } catch (err) { + console.error("Invalid metadata JSON in code block:", err); + return ( +
+ {sourceCode} +
+ ); + } + + const lang = (language == "cpp" ? "c++" : language); + + const transformedLibs = (metadata.libs || []).map((lib) => { + const [id, version] = lib.split("@"); + return { id, version }; + }); + + const transformedCompilers = (metadata.compilers || []).map((compiler) => { + const firstSpace = compiler.indexOf(" "); + const id = firstSpace === -1 ? compiler : compiler.slice(0, firstSpace); + const options = firstSpace === -1 ? "" : compiler.slice(firstSpace + 1); + const libs = transformedLibs; + const filters = metadata.filters || {}; + return { id, options, libs, filters }; + }); + + const executor = { + compilerVisible: true, + compilerOutputVisible: true, + compiler: transformedCompilers[0] || {}, + }; + + const session = { + id: uniqueID(), + language: lang, + source: sourceCode, + compilers: transformedCompilers, + executors: [], + }; + + const clientState = { sessions: [session] }; + + const clientStateB64 = btoa(JSON.stringify(clientState)).replace(/\//g, "%2F"); + + return ( +
+ + {sourceCode} +
+ ); +} diff --git a/src/components/Godbolt.jsx b/src/components/Godbolt.jsx new file mode 100644 index 0000000..e622cb2 --- /dev/null +++ b/src/components/Godbolt.jsx @@ -0,0 +1,86 @@ +import React, { useState } from 'react'; +import Modal from 'react-modal'; + +// Bind modal to app element for accessibility +Modal.setAppElement('#__docusaurus'); + +export default function Godbolt({ url }) { + const [isOpen, setIsOpen] = useState(false); + + const getHTMLIframe = (url) => { + if (!url.includes('godbolt.org')) { + return '

Invalid Godbolt URL

'; + } + const fullUrl = url.trim().includes('godbolt.org/#') + ? url.replace('godbolt.org/#', 'godbolt.org/e?hideEditorToolbars=false#') + : url; + return ``; + }; + + const openModal = () => setIsOpen(true); + const closeModal = () => setIsOpen(false); + const iframeHTML = getHTMLIframe(url); + + return ( +
+ { + e.preventDefault(); + openModal(); + }} + style={{ + fontSize: '16px', + color: '#007bff', + textDecoration: 'underline', + cursor: 'pointer', + zIndex: 1000, + }} + onMouseOver={(e) => (e.target.style.color = '#0056b3')} + onMouseOut={(e) => (e.target.style.color = '#007bff')} + > + Try it on Compiler Explorer 🚀 + + +
+ + +
+ ); +} \ No newline at end of file diff --git a/src/components/godbolt-transformer.js b/src/components/godbolt-transformer.js new file mode 100644 index 0000000..9e331a0 --- /dev/null +++ b/src/components/godbolt-transformer.js @@ -0,0 +1,21 @@ +const GodboltTransformer = { + name: "Godbolt", + shouldTransform(url) { + return url.includes("godbolt.org"); + }, + getHTML(url) { + const fullUrl = url.includes("godbolt.org/#") + ? url.replace("godbolt.org/#", `godbolt.org/e?hideEditorToolbars=false#`) + : url; + + return ` + + `; + }, +}; + +module.exports = GodboltTransformer; diff --git a/src/plugins/remark-codeblock-meta/index.js b/src/plugins/remark-codeblock-meta/index.js new file mode 100644 index 0000000..5f7ffa2 --- /dev/null +++ b/src/plugins/remark-codeblock-meta/index.js @@ -0,0 +1,30 @@ +// plugins/remark-codeblock-meta.js + +// Try importing visit using both methods +let visit; +try { + // ES Modules style import + ({ visit } = require("unist-util-visit")); +} catch (err) { + // Fallback if not available like that + visit = require("unist-util-visit").default || require("unist-util-visit"); +} + +module.exports = function remarkCodeblockMeta() { + return (tree) => { + visit(tree, "code", (node) => { + const meta = node.meta?.trim(); + if (meta && meta.startsWith("{") && meta.endsWith("}")) { + // Attach metadata and change node to use our custom component + node.data = { + hName: "CodeBlockWithMetadata", + hProperties: { + meta, + language: node.lang, + children: node.value, + }, + }; + } + }); + }; +}; diff --git a/src/theme/Layout/index.js b/src/theme/Layout/index.js new file mode 100644 index 0000000..3e395dc --- /dev/null +++ b/src/theme/Layout/index.js @@ -0,0 +1,16 @@ +import React from 'react'; +import Layout from '@theme-original/Layout'; +import CodeBlockWithMetadata from '@site/src/components/CodeBlockWithMetadata'; +import { MDXProvider } from '@mdx-js/react'; + +export default function LayoutWrapper(props) { + return ( + + + + ); +} diff --git a/src/theme/MDXComponents.js b/src/theme/MDXComponents.js new file mode 100644 index 0000000..7cd81ea --- /dev/null +++ b/src/theme/MDXComponents.js @@ -0,0 +1,8 @@ +import React from 'react'; +import MDXComponents from '@theme-original/MDXComponents'; +import Godbolt from '../components/Godbolt.jsx'; + +export default { + ...MDXComponents, + Godbolt, +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a1322e8..1afd9c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4191,6 +4191,11 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exenv@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" + integrity sha512-Z+ktTxTwv9ILfgKCk32OX3n/doe+OcLTRtqK9pcL+JsP3J1/VW8Uvl4ZjLlKqeW4rzK4oesDOGMEMRIZqtP4Iw== + express@^4.17.3: version "4.21.2" resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" @@ -7475,6 +7480,11 @@ react-json-view-lite@^1.2.0: resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz#377cc302821717ac79a1b6d099e1891df54c8662" integrity sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw== +react-lifecycles-compat@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + react-loadable-ssr-addon-v5-slorber@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz#2cdc91e8a744ffdf9e3556caabeb6e4278689883" @@ -7489,6 +7499,16 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@types/react" "*" +react-modal@^3.16.3: + version "3.16.3" + resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.16.3.tgz#c412d41915782e3c261253435d01468e2439b11b" + integrity sha512-yCYRJB5YkeQDQlTt17WGAgFJ7jr2QYcWa1SHqZ3PluDmnKJ/7+tVU+E6uKyZ0nODaeEj+xCpK4LcSnKXLMC0Nw== + dependencies: + exenv "^1.2.0" + prop-types "^15.7.2" + react-lifecycles-compat "^3.0.0" + warning "^4.0.3" + react-router-config@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" @@ -8747,6 +8767,13 @@ vfile@^6.0.0, vfile@^6.0.1: "@types/unist" "^3.0.0" vfile-message "^4.0.0" +warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + watchpack@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da"