daKmoR / rocket

Move to https://github.com/modernweb-dev/rocket/
MIT License
13 stars 5 forks source link

[feature] mdjs plugins #126

Open bennypowers opened 3 years ago

bennypowers commented 3 years ago

Users should be able to extends mdjs, adding their own directives which transform code.

Use Case: Copy Snippet

This simple use case would let a user define a new directive which simply wraps the code block in a custom element. It has no parameters, just does what it says on the box.

Before

​    <code-copy>
​    
    ```bash
    npm init @apollo-elements


​

## After
​
```md
    ```bash copy
    npm init @apollo-elements

## Use Case: Code Tabs

This more advanced use case lets a user define a directive that takes a parameter, namely the ID for a tab, which references a config object that includes tab label and icon

### Before

```md
    <code-tabs>

    <code-tab package="lit">

    ```js
    html`<p>I'm a little teapot</p>`
</code-tab>

<code-tab package="FAST">

```js
html<MyComponent>`<p>I'm a little teapot</p>`
```

</code-tab>

</code-tabs>

### After
 <code-tabs>

```js tab lit
html`<p>I'm a little teapot</p>`
```

```js tab FAST
html<MyComponent>`<p>I'm a little teapot</p>`
```

</code-tabs>

### Use Case: Code Demo

Similar to the above, you can imaging a `graphql live` directive which lets the viewer execute a graphql query in-browser, or a `graphql live uri=https://api.spacex.land/graphql` directive which queries from a specific endpoint.

### Proposed Plugin API

Consider this a strawman proposal

```ts
interface Plugin {
  name: string;
  directive(directive: string, code: string): BlockProcessor;
}

interface Directive {
  language: string;
  command: string; // first command, non-nullable
  params: string[]; // rest, split by whitespace
}

declare class BlockProcessor {
  config: Config; // injected behind-the-scenes
  directive: Directive;
  transform(code: string): string; // returns the replaced code-block
  loadModules(): string[]; // returns any module scripts to load on the page
}