Skip to content

Commit

Permalink
copied from tabs-extension
Browse files Browse the repository at this point in the history
  • Loading branch information
makhnatkin committed Jun 14, 2024
1 parent 34b3258 commit c45cbe7
Show file tree
Hide file tree
Showing 28 changed files with 4,067 additions and 20 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@
/build
/coverage
/node_modules
/runtime
/plugin
/react

# libraries
npm-debug.log

index.d.ts
*.d.ts
example/package-lock.json
example/build
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
170 changes: 168 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,170 @@
# html-extension
# Diplodoc html extension

[![NPM version](https://img.shields.io/npm/v/@diplodoc/viewer.svg?style=flat)](https://www.npmjs.org/package/@diplodoc/viewer)
#### 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)

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(dirty, {
allowedTags: ['article', 'h1', 'h2', 'p', 'span'],
allowedAttributes: {
'*': ['class']
}
}),
cssValiables: {
'--html-color-primary': '#000'
},
shouldUseIframe: true,
className: 'yfm-html'
})
]
});
```

## 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>
<link rel='stylesheet' href='_assets/html-extension.css' />
</head>
<body>
${result.html}
</body>
</html>
```

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

## 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>

- `runtimeCssPath` - name on runtime css file which will be exposed in results `style` section.<br>
(Default: `_assets/html-extension.css`)<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
import React, { useEffect } from 'react'
import {useDiplodocHtml, HTMLBlock} from '@diplodoc/html-extension/react';

export const App: React.FC = () => {
const selectTabHandler = useCallback<UseDiplodocTabsCallback>(
(html: HTMLBlock, currentTabId?: string) => {
const {group, key} = tab;
// Group could be empty
if (group) {
// ...
}
},
[],
);

const {selectTab, selectTabById} = useDiplodocTabs(selectTabHandler);

useEffect(() => {
selectTab({ group: 'group_1', key: 'my-key' });
// selectTabById('my-key-2');
}, [selectTab, selectTabById]);

}
```
50 changes: 44 additions & 6 deletions esbuild/build.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,58 @@
#!/usr/bin/env node

const esbuild = require('esbuild');
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},
} = require('../tsconfig.json');
} = tsconfigJson;

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

esbuild.build({
build({
...common,
entryPoints: ['src/index.ts'],
outfile: 'index.js',
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',
external: ['markdown-it', 'node:*'],
define: {
PACKAGE: JSON.stringify(packageJson.name),
},
});

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

{% list tabs group=group_1 %}

- Python {#my-tab}

About python

- Java
- One
- Two

- TypeScript
1. One
2. Two

- ipv4

{% endlist %}

{% list tabs group=group_1 %}

- Python

About python

- Java
- One
- Two

- TypeScript
1. One
2. Two

{% endlist %}

{% list tabs %}

- Python

About python

- Java
- One
- Two

- TypeScript
1. One
2. Two

{% endlist %}

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

import {readFile} from 'node:fs/promises';

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

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

// eslint-disable-next-line no-console
console.log(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/tabs-extension-example",
"private": true,
"type": "module",
"scripts": {
"start": "node . 1> build/index.html; open build/index.html"
},
"dependencies": {
"@diplodoc/tabs-extension": "..",
"@diplodoc/transform": "*"
}
}
Loading

0 comments on commit c45cbe7

Please sign in to comment.