Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposes the independent steps into individual functions #27

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 65 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
//!
//! * [`compile()`][]
//! — turn MDX into JavaScript
//! * [`compile_with_ast()`][]
//! — turn MDX into JavaScript, but also return the original Markdown AST
#![deny(clippy::pedantic)]
#![allow(clippy::must_use_candidate)]
#![allow(clippy::too_many_lines)]
Expand All @@ -13,7 +15,7 @@

extern crate markdown;
mod configuration;
mod hast;
pub mod hast;
mod hast_util_to_swc;
mod mdast_util_to_hast;
mod mdx_plugin_recma_document;
Expand All @@ -30,29 +32,19 @@ use crate::{
swc::{parse_esm, parse_expression, serialize},
swc_util_build_jsx::{swc_util_build_jsx, Options as BuildOptions},
};
use markdown::{to_mdast, Constructs, Location, ParseOptions};
use hast_util_to_swc::Program;
use markdown::{mdast, to_mdast, Constructs, Location, ParseOptions};

pub use crate::configuration::{MdxConstructs, MdxParseOptions, Options};
pub use crate::mdx_plugin_recma_document::JsxRuntime;

/// Turn MDX into JavaScript.
///
/// ## Examples
///
/// ```
/// use mdxjs::compile;
/// # fn main() -> Result<(), String> {
///
/// assert_eq!(compile("# Hi!", &Default::default())?, "import { jsx as _jsx } from \"react/jsx-runtime\";\nfunction _createMdxContent(props) {\n const _components = Object.assign({\n h1: \"h1\"\n }, props.components);\n return _jsx(_components.h1, {\n children: \"Hi!\"\n });\n}\nfunction MDXContent(props = {}) {\n const { wrapper: MDXLayout } = props.components || {};\n return MDXLayout ? _jsx(MDXLayout, Object.assign({}, props, {\n children: _jsx(_createMdxContent, props)\n })) : _createMdxContent(props);\n}\nexport default MDXContent;\n");
/// # Ok(())
/// # }
/// ```
/// Turn MDX into an mdast node.
///
/// ## Errors
///
/// This project errors for many different reasons, such as syntax errors in
/// the MDX format or misconfiguration.
pub fn compile(value: &str, options: &Options) -> Result<String, String> {
pub fn parse_to_mdast(value: &str, options: &Options) -> Result<mdast::Node, String> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d prefer reusing the names that are currently used in the JS world, albeit that this one is specific to MDX instead of markdown, which doesn’t exist there.

How about mdast_util_from_mdx, inspired by mdast-util-from-markdown

let parse_options = ParseOptions {
constructs: Constructs {
attention: options.parse.constructs.attention,
Expand Down Expand Up @@ -95,6 +87,31 @@ pub fn compile(value: &str, options: &Options) -> Result<String, String> {
mdx_esm_parse: Some(Box::new(parse_esm)),
mdx_expression_parse: Some(Box::new(parse_expression)),
};

to_mdast(value, &parse_options)
}

/// Turn a mdast node into an hast one.
///
/// ## Errors
///
/// This project errors for many different reasons, such as syntax errors in
/// the MDX format or misconfiguration.
pub fn mdast_to_hast(mdast: &mdast::Node) -> hast::Node {
mdast_util_to_hast(mdast)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be exposed as the full name: mdast_util_to_hast.

}

/// Turn an hast node into an SWC program.
///
/// ## Errors
///
/// This project errors for many different reasons, such as syntax errors in
/// the MDX format or misconfiguration.
pub fn hast_to_program(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hast_util_to_swc?

hast: &hast::Node,
original_source: &str,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should match value from earlier

options: &Options,
) -> Result<Program, String> {
let document_options = DocumentOptions {
pragma: options.pragma.clone(),
pragma_frag: options.pragma_frag.clone(),
Expand All @@ -110,16 +127,44 @@ pub fn compile(value: &str, options: &Options) -> Result<String, String> {
development: options.development,
};

let location = Location::new(value.as_bytes());
let mdast = to_mdast(value, &parse_options)?;
let hast = mdast_util_to_hast(&mdast);
let mut program = hast_util_to_swc(&hast, options.filepath.clone(), Some(&location))?;
let location = Location::new(original_source.as_bytes());

let mut program = hast_util_to_swc(hast, options.filepath.clone(), Some(&location))?;
mdx_plugin_recma_document(&mut program, &document_options, Some(&location))?;
mdx_plugin_recma_jsx_rewrite(&mut program, &rewrite_options, Some(&location));

if !options.jsx {
swc_util_build_jsx(&mut program, &build_options, Some(&location))?;
}

Ok(serialize(&mut program.module, Some(&program.comments)))
Ok(program)
}

pub fn program_to_string(program: &mut Program) -> String {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swc_util_to_js?

serialize(&mut program.module, Some(&program.comments))
}

/// Turn MDX into JavaScript.
///
/// ## Examples
///
/// ```
/// use mdxjs::compile;
/// # fn main() -> Result<(), String> {
///
/// assert_eq!(compile("# Hi!", &Default::default())?, "import { jsx as _jsx } from \"react/jsx-runtime\";\nfunction _createMdxContent(props) {\n const _components = Object.assign({\n h1: \"h1\"\n }, props.components);\n return _jsx(_components.h1, {\n children: \"Hi!\"\n });\n}\nfunction MDXContent(props = {}) {\n const { wrapper: MDXLayout } = props.components || {};\n return MDXLayout ? _jsx(MDXLayout, Object.assign({}, props, {\n children: _jsx(_createMdxContent, props)\n })) : _createMdxContent(props);\n}\nexport default MDXContent;\n");
/// # Ok(())
/// # }
/// ```
///
/// ## Errors
///
/// This project errors for many different reasons, such as syntax errors in
/// the MDX format or misconfiguration.
pub fn compile(value: &str, options: &Options) -> Result<String, String> {
let mdast = parse_to_mdast(value, options)?;
let hast = mdast_to_hast(&mdast);
let mut program = hast_to_program(&hast, value, options)?;

Ok(program_to_string(&mut program))
}