Skip to content

Commit

Permalink
feat(unified-doc): support doc.file('.md') extension type.
Browse files Browse the repository at this point in the history
- Implement `doc.file('.md')` using `hast-util-to-mdast` and `mdast-util-to-markdown`.
- Update tests and documentation for `doc.file('.md')`.
- Expose supported `mimeTypes` and `extensionTypes` for consumption.
  • Loading branch information
chrisrzhou committed Sep 9, 2020
1 parent dc173cb commit 2b22a1a
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 18 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"@mapbox/rehype-prism": "^0.5.0",
"@types/jest": "^26.0.9",
"babel-jest": "^26.2.2",
"husky": "^4.2.5",
"husky": "^4.3.0",
"jest": "^26.4.2",
"lerna": "^3.22.1",
"microbundle": "^0.12.2",
Expand Down
2 changes: 2 additions & 0 deletions packages/unified-doc/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export { default } from './lib/doc';

export { extensionTypes, mimeTypes } from './lib/enums';
2 changes: 1 addition & 1 deletion packages/unified-doc/lib/enums.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export const extensionTypes = {
HTML: '.html',
MARKDOWN: '.md',
TEXT: '.txt',
};

export const mimeTypes = {
HTML: 'text/html',
MARKDOWN: 'text/markdown',
TEXT: 'text/plain',
};
10 changes: 8 additions & 2 deletions packages/unified-doc/lib/file.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import toHtml from 'hast-util-to-html';
import toMdast from 'hast-util-to-mdast';
import toMarkdown from 'mdast-util-to-markdown';
import mime from 'mime-types';

import { extensionTypes, mimeTypes } from './enums';
import { extensionTypes } from './enums';
import { toText } from './hast';

export function inferMimeType(filename) {
return mime.lookup(filename) || mimeTypes.TEXT;
return mime.lookup(filename) || 'text/plain';
}

export function getFileData({
Expand All @@ -21,6 +23,10 @@ export function getFileData({
content = toHtml(hast);
break;
}
case extensionTypes.MARKDOWN: {
content = toMarkdown(toMdast(hast));
break;
}
case extensionTypes.TEXT: {
content = toText(hast);
break;
Expand Down
2 changes: 2 additions & 0 deletions packages/unified-doc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
"deepmerge": "^4.2.2",
"hast-util-sanitize": "^3.0.0",
"hast-util-to-html": "^7.1.1",
"hast-util-to-mdast": "^7.1.1",
"hast-util-to-string": "^1.0.4",
"mdast-util-to-markdown": "^0.1.1",
"mime-types": "^2.1.27",
"rehype-parse": "^7.0.1",
"rehype-stringify": "^8.0.0",
Expand Down
28 changes: 27 additions & 1 deletion packages/unified-doc/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ expect(doc.compile()).toBeInstanceOf(VFile); // vfile instance
- [`doc.search(query[, options])`](#docsearchquery-options)
- [`doc.textContent()`](#doctextContent)
- [`options`](#options)
- [`enums`](#enums)

A `doc` refers to an instance of `unified-doc`.

Expand Down Expand Up @@ -129,7 +130,7 @@ Returns the results of the compiled content based on the `compiler` attached to
```ts
function file(extension?: string): FileData;
```
Returns `FileData` for the specified extension. This is a useful way to convert and output different file formats. Supported extensions include `'.html'`, `'.txt'`. If no extension is provided, the source file should be returned. Future extensions can be implemented, providing a powerful way to convert file formats for any supported content type
Returns `FileData` for the specified extension. This is a useful way to convert and output different file formats. Supported extensions include `'.html'`, `'.txt'`, `.md`. If no extension is provided, the source file should be returned. Future extensions can be implemented, providing a powerful way to convert file formats for any supported content type

#### Example
```js
Expand All @@ -156,6 +157,15 @@ expect(doc.file('.html')).toEqual({
type: 'text/html',
});

// export file as markdown
expect(doc.file('.markdown')).toEqual({
content: '> **some** markdown content',
extension: '.md',
name: 'doc.md',
stem: 'doc',
type: 'text/markdown',
});

// export file as text (only textContent is extracted)
expect(doc.file('.txt')).toEqual({
content: 'some markdown content',
Expand Down Expand Up @@ -378,6 +388,22 @@ interface SearchOptions {
}
```

### `enums`
The following enums indicate `mimeTypes` for supported parsers and `extensionTypes` for supported file conversion targets.

```ts
const extensionTypes = {
HTML: '.html',
MARKDOWN: '.md',
TEXT: '.txt',
};

const mimeTypes = {
HTML: 'text/html',
MARKDOWN: 'text/markdown',
};
```

<!-- Definitions -->
[micromatch]: https://github.com/micromatch/micromatch
[rehype]: https://github.com/rehypejs/rehype
Expand Down
16 changes: 15 additions & 1 deletion packages/unified-doc/tests/doc/file.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Doc from '../../lib/doc';
import { markdownContent } from '../fixtures';
import { htmlContent, markdownContent } from '../fixtures';

describe('doc.file', () => {
it('returns the source file if no extension is provided', () => {
Expand Down Expand Up @@ -78,4 +78,18 @@ describe('doc.file', () => {
expect(content2).toContain('data-mark-id="b"');
expect(content2).toContain('data-mark-id="c"');
});

it('returns a markdown file when ".md" extension is provided', () => {
const doc = Doc({
content: htmlContent,
filename: 'doc.html',
});
const file = doc.file('.md');
expect(file.content).toEqual('> **some** content');
expect(file.extension).toEqual('.md');
expect(file.name).toEqual('doc.md');
expect(file.stem).toEqual('doc');
expect(file.type).toEqual('text/markdown');
});

});
33 changes: 21 additions & 12 deletions packages/unified-doc/tests/file.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import vfile from 'vfile';
import { hast, markdownContent } from './fixtures';
import { inferMimeType, getFileData } from '../lib/file';

const unusedVile = vfile({
basename: 'doc.md',
contents: 'unused',
})

describe('file', () => {
// only test the default mime type since other behaviors are implemented/tested in "mime" package.
describe(inferMimeType, () => {
Expand Down Expand Up @@ -55,10 +60,7 @@ describe('file', () => {
const fileData = getFileData({
extension: '.txt',
hast,
vfile: vfile({
basename: 'doc.md',
contents: 'unused',
}),
vfile: unusedVile,
});
expect(fileData.content).not.toEqual('some markdown content');
expect(fileData.content).toEqual('\nsome markdown content\n');
Expand Down Expand Up @@ -103,10 +105,7 @@ describe('file', () => {
const fileData = getFileData({
extension: '.txt',
hast,
vfile: vfile({
basename: 'doc.html',
contents: 'unused',
}),
vfile: unusedVile,
});
expect(fileData.content).toEqual('body content should be included.');
});
Expand All @@ -115,10 +114,7 @@ describe('file', () => {
const fileData = getFileData({
extension: '.html',
hast,
vfile: vfile({
basename: 'doc.html',
contents: 'unused',
}),
vfile: unusedVile,
});
expect(fileData.content).not.toEqual(markdownContent);
expect(fileData.content).toEqual(
Expand All @@ -129,5 +125,18 @@ describe('file', () => {
expect(fileData.stem).toEqual('doc');
expect(fileData.type).toEqual('text/html');
});

it('returns markdown file data when ".md" extension is provided', () => {
const fileData = getFileData({
extension: '.md',
hast,
vfile: unusedVile,
});
expect(fileData.content).toEqual('> **some** markdown content');
expect(fileData.extension).toEqual('.md');
expect(fileData.name).toEqual('doc.md');
expect(fileData.stem).toEqual('doc');
expect(fileData.type).toEqual('text/markdown');
});
});
});
10 changes: 10 additions & 0 deletions packages/unified-doc/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,13 @@ export interface SearchResultSnippet extends SearchResult {
* The core function that returns a `doc` instance with unified document APIs
*/
export default function Doc(options: Options): DocInstance;

/**
* Extension types for supported file conversion target format
*/
export const extensionTypes: Record<string, string>;

/**
* Mime types for supported parsers
*/
export const mimeTypes: Record<string, string>;

0 comments on commit 2b22a1a

Please sign in to comment.