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

feat(transform): added transform plugin , runtime controller, React hook #1

Merged
merged 14 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
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
5 changes: 5 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/build
/coverage
/node_modules
/runtime
/react
/plugin
/example/node_modules
/example/build
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
/build
/coverage
/node_modules
/runtime
/plugin
/react

# libraries
npm-debug.log

index.d.ts
*.d.ts
example/package-lock.json
example/build
example/node_modules
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run precommit
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
src
esbuild
example
4 changes: 0 additions & 4 deletions README-template.md

This file was deleted.

142 changes: 135 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,139 @@
## How to start
# Diplodoc html extension

```bash
# Clone this repo to new folder
git clone [email protected]:diplodoc-platform/package-template.git new-package
cd new-package
#### TODO: add html-extension.svg
[![NPM version](https://img.shields.io/npm/v/@diplodoc/html-extension.svg?style=flat)](https://www.npmjs.org/package/@diplodoc/html-extension)

# Init repo with new package name
./init.sh new-package
This is an extension of the Diplodoc platform, which allows adding HTML in the documentation.

The extension contains some parts:
- [Prepared runtime](#prepared-runtime)
- [MarkdownIt transform plugin](#markdownit-transform-plugin)
- [HTML plugin API](#api)
- [React hook for smart control](#react-hook-for-smart-control)

## Quickstart

Attach the plugin to the transformer:

```js
import htmlExtension from '@diplodoc/html-extension';
import transform from '@diplodoc/transform';
import * as sanitizeHtml from 'sanitize-html';

const {result} = await transform(`
::: html

<article class="forecast">
<h1>Weather forecast for Seattle</h1>
<article class="day-forecast">
<h2>12 June 2024</h2>
<p>Rain.</p>
</article>
<article class="day-forecast">
<h2>13 June 2024</h2>
<p>Periods of rain.</p>
</article>
<article class="day-forecast">
<h2>14 June 2024</h2>
<p>Heavy rain.</p>
</article>
</article>

:::
`, {
plugins: [
htmlExtension.transform({
sanitize: dirtyHtml => sanitizeHtml(dirtyHtml, {
allowedTags: ['article', 'h1', 'h2', 'p', 'span'],
allowedAttributes: {
'*': ['class']
}
}),
containerClasses: 'my-own-class'
})
]
});
```

## Prepared runtime

It is necessary to add `runtime` scripts to make html interactive on your page.<br/>
You can add assets files which were generated by the [MarkdownIt transform plugin](#markdownit-transform-plugin).
```html
<html>
<head>
<!-- Read more about '_assets/html-extension.js' and '_assets/html-extension.css' in 'Transform plugin' section -->
<script src='_assets/html-extension.js' async></script>
</head>
<body>
${result.html}
</body>
</html>
```

Or you can just include runtime's source code in your bundle.
```js
import '@diplodoc/html-extension/runtime'
```

## MarkdownIt transform plugin

Plugin for [@diplodoc/transform](https://github.com/diplodoc-platform/transform) package.

Options:
- `runtimeJsPath` - name on runtime script which will be exposed in results `script` section.<br>
Default: `_assets/html-extension.js`<br>

- `bundle` - boolean flag to enable/disable copying of bundled runtime to target directory.<br>
Where target directore is `<transformer output option>/<plugin runtime option>`<br>
Default: `true`<br>

- `containerClasses` - additional classes which will be added to tab's container node. It allows to customize the html view.<br>
Example: `my-own-class and-other-class`<br>
Default: `undefined`<br>

## API

### Syntax

This plugin uses the directive syntax [proposed](https://talk.commonmark.org/t/generic-directives-plugins-syntax/444) in the CommonMark community, indicated by a block-level double colon at the beginning and end of a block. This HTML directives use `::: html` to open an HTML block, followed by your HTML content, and then `:::` to close the block. The number of empty lines before or after the opening or closing block is not significant.

Please note:
- Nested content within the block will not be parsed as Markdown.
- Embedded directives within the block are not supported.
- Inline directives are not yet supported.


Simple example:
```
::: html

<div>Your HTML code is here</div>

:::
```
Example with some styles:
```
::: html
<style>
<style>
:root {
--dark-bg-color: #000;
--dark-text-color: #FFF;
}
.dark {
background-color: var(--primary-bg-color);
color: : var(--primary-text-color);
}
</style>
<div class="dark">Some info is here</div>
:::
```

## React hook for smart control

You can use the React hook to interact programmatically with the HTML content inside the block.

```TypeScript
// TODO
```
20 changes: 0 additions & 20 deletions esbuild/build.js

This file was deleted.

58 changes: 58 additions & 0 deletions esbuild/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env node

import {readFileSync} from 'node:fs';
import {fileURLToPath} from 'url';
import {dirname} from 'path';

import {build} from 'esbuild';
import {sassPlugin} from 'esbuild-sass-plugin';
const tsconfigJson = readJSON('../tsconfig.json');
const packageJson = readJSON('../package.json');

const {
compilerOptions: {target},
} = tsconfigJson;

const common = {
bundle: true,
sourcemap: true,
target,
tsconfig: './tsconfig.json',
};

build({
...common,
entryPoints: ['src/runtime/index.ts'],
outfile: 'runtime/index.js',
minify: true,
platform: 'browser',
plugins: [
sassPlugin()
],
});

build({
...common,
entryPoints: ['src/react/index.ts'],
outfile: 'react/index.js',
platform: 'neutral',
external: ['react'],
target: 'es6',
format: 'cjs',
});

build({
...common,
entryPoints: ['src/plugin/index.ts'],
outfile: 'plugin/index.js',
platform: 'node',
packages: 'external',
define: {
PACKAGE: JSON.stringify(packageJson.name),
},
});

function readJSON(path) {
const currentFilename = fileURLToPath(import.meta.url);
return JSON.parse(readFileSync(`${dirname(currentFilename)}/${path}`));
}
59 changes: 59 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Simple example

```
npm i
npm start
```

Then this documentation will be rendered by [@diplodoc/transform](https://github.com/diplodoc-platform/transform) and opened in your default browser.

# Example

::: html
<div>Simple HTML code</div>
:::

## Markdown header
Markdown text

::: html
<div>HTML code with table</div>
<style>
/*****************/
/*** header ***/
/*****************/
.header {
background: #EEE;
border-radius: 16px;
font-size: 40px;
line-height: 40px;
padding:16px;
box-sizing: border-box;
color: #363E45;
height:335px;
}
.text_header { font-size:16px; line-height:120%; font-weight:500; }

</style>

<!----------------->
<!-- header --->
<!----------------->
<table width="100%">
<tr>
<td width="74%" class="header">
<div style="width:720px">
<strong>Header</strong>
<div class="text_header" style="width:520px">Some text here</div>
</div>
</td>
<td width="1%" style="padding-left:6px"></td>
<td width="25%" style="min-width:300px"></td>
</tr>
</table>

:::



After html text
34 changes: 34 additions & 0 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import transform from '@diplodoc/transform';
import htmlPlugin from '@diplodoc/html-extension';

import {readFile, writeFile} from 'node:fs/promises';
import {exec} from 'node:child_process';
import {promisify} from 'node:util';

(async () => {
const content = await readFile('./README.md', 'utf8');
const {result} = await transform(content, {
needToSanitizeHtml: false,
output: './build',
plugins: [
htmlPlugin.transform({
bundle: true,
}),
],
});

const html = `
<html>
<head>
${result.meta.script.map((scriptFile) => `<script src="${scriptFile}"></script>`).join('\n')}
${result.meta.style.map((styleFile) => `<link rel="stylesheet" href="${styleFile}" />`).join('\n')}
</head>
<body>
${result.html}
</body>
</html>
`;

await writeFile('./build/index.html', html);
await promisify(exec)('open build/index.html');
})();
12 changes: 12 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@diplodoc/html-extension-example",
"private": true,
"type": "module",
"scripts": {
"start": "node ."
},
"dependencies": {
"@diplodoc/html-extension": "file:..",
"@diplodoc/transform": "*"
}
}
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.(j|t)s?$': ['ts-jest', {tsconfig: '<rootDir>/test/tsconfig.json'}],
},
transformIgnorePatterns: [],
testEnvironment: 'jsdom',
};
Loading
Loading