Skip to content

Commit

Permalink
Merge pull request #23 from hougesen/feat/parse-code-blocks
Browse files Browse the repository at this point in the history
feat: parse code blocks
  • Loading branch information
hougesen authored Jul 6, 2022
2 parents 81510a0 + 0f7d55f commit 4f3135b
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 10 deletions.
16 changes: 16 additions & 0 deletions __tests__/generateCodeBlock.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect, it, describe } from 'vitest';
import { generateCodeBlock } from '../src/utils/generateCodeBlock';

describe('generateCodeBlock.ts', () => {
it('valid code block ', () => {
const languages = ['', 'js', 'ts', 'java', 'rust'];

for (const language of languages) {
expect(generateCodeBlock(['```' + language, 'const x = 10;', 'const y = Math.pow(x,x);', '```'])).toEqual(
`<code${
language ? `lang="${language}" class="codeblock codeblock--${language}"` : ''
}>const x = 10; <br /> const y = Math.pow(x,x);</code>`
);
}
});
});
21 changes: 21 additions & 0 deletions __tests__/mock-data/dummy_with_code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
This is before the code block





```js
const x = 10;
const y = x * x;
```










This is after the code block
29 changes: 28 additions & 1 deletion __tests__/parseDocument.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { readFile } from 'fs/promises';
import { describe, expect, it } from 'vitest';

import { IMrkdwnyOptions } from '../src';
Expand Down Expand Up @@ -51,7 +52,12 @@ const dummyOptions: IMrkdwnyOptions = {
},
};

describe('parseDocument.ts', () => {
describe('parseDocument.ts', async () => {
const dummyMarkdownWithCode = await readFile(`${__dirname}/mock-data/dummy_with_code.md`, 'utf8');

const dummyMarkdownWithCodeHtml =
'<p>This is before the code block</p><codelang="js" class="codeblock codeblock--js">const x = 10; <br /> const y = x * x;</code><p>This is after the code block</p>';

it('validate mock results', () => {
for (const { markdown, html } of mockResults) {
expect(parseDocument(markdown)).toEqual(html);
Expand Down Expand Up @@ -102,4 +108,25 @@ describe('parseDocument.ts', () => {
'<p class="text" style="text-align: center"><strong class="bold">bold text</strong></p>'
);
});

it('validate that codeblocks work', () => {
expect(parseDocument(dummyMarkdownWithCode)).toEqual(dummyMarkdownWithCodeHtml);
});

it("validate that whitespace doesn't matter", () => {
expect(
parseDocument(
dummyMarkdownWithCode
?.split('\n')
?.filter((l) => l?.trim()?.length)
?.join('\n') ?? ''
)
).toEqual(dummyMarkdownWithCodeHtml);
});

it('validate that multiple codeblocks work', () => {
expect(parseDocument(dummyMarkdownWithCode + '\n' + dummyMarkdownWithCode)).toEqual(
dummyMarkdownWithCodeHtml + dummyMarkdownWithCodeHtml
);
});
});
8 changes: 3 additions & 5 deletions __tests__/parseMetaData.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { readFileSync } from 'fs';
import { readFile } from 'fs/promises';
import { describe, expect, it } from 'vitest';

import { parseMetaData } from '../src/utils/parseMetaData';

describe('parseMetaData.ts', () => {
it('output valid metadata', () => {
const dummyMetaData = readFileSync(`${__dirname}/mock-data/dummy_meta.md`, 'utf8');
it('output valid metadata', async () => {
const dummyMetaData = await readFile(`${__dirname}/mock-data/dummy_meta.md`, 'utf8');
const result = parseMetaData(dummyMetaData);

// Strings
Expand All @@ -18,6 +18,4 @@ describe('parseMetaData.ts', () => {
expect(result).toHaveProperty('string_date', new Date('02-02-2021'));
expect(result).toHaveProperty('iso_date', new Date('2022-07-04T15:50:00.577Z'));
});

it.todo('invalid');
});
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface IMrkdwnyElementOptions {
h4?: IElementBaseOptions;
h5?: IElementBaseOptions;
h6?: IElementBaseOptions;
code?: IElementBaseOptions;
}
export interface IMrkdwnyOptions {
elements?: IMrkdwnyElementOptions;
Expand Down
17 changes: 17 additions & 0 deletions src/utils/generateCodeBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function generateCodeBlock(code: string[], attributes = ''): string {
const language = code?.shift()?.replace('```', '')?.trim() ?? '';

if (language?.length) {
if (attributes?.includes('class="')) {
attributes.replace('class="', `class="codeblock codeblock--${language}`);
} else {
attributes += ` class="codeblock codeblock--${language}"`;
}
}

code.pop();

return `<code${language ? `lang="${language}"` : ''}${attributes}>${code
?.filter((l) => l?.trim()?.length && l?.includes('```') === false)
?.join(' <br /> ')}</code>`;
}
30 changes: 26 additions & 4 deletions src/utils/parseDocument.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,40 @@
import { IMrkdwnyOptions } from '../';
import { generateAttributes } from './generateAttributes';
import { generateCodeBlock } from './generateCodeBlock';
import { parseLine } from './parseLine';
import { removeCommments } from './removeComments';

export function parseDocument(fileContent: string, options: IMrkdwnyOptions = {}): string {
const withoutComments = removeCommments(fileContent)?.trim()?.split('\n');
const lines = removeCommments(fileContent)?.trim()?.split('\n');

const attributes = generateAttributes(options?.elements);

let html = '';

for (const line of withoutComments) {
if (line?.length) {
html += parseLine(line, attributes);
for (let i = 0; i < lines.length; i += 1) {
if (lines[i]?.length) {
if (lines[i].startsWith('```')) {
let codeEnd = i;

for (let j = i + 1; j < lines.length; j += 1) {
if (lines[j].startsWith('```')) {
codeEnd = j;
break;
}
}

if (i !== codeEnd) {
const codeLines = lines.splice(i, codeEnd - i + 1);

html += generateCodeBlock(codeLines, attributes?.code ?? '');

i -= 1;

continue;
}
}

html += parseLine(lines[i], attributes);
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/utils/regex/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ export const BOLDEMAsterisRegex = /(?<!\*)(\*\*\*)(?!\*)(.*?)(?<!\*)(\*\*\*)(?!\
*
*/
export const BOLDEMUnderscoreRegex = /(?<!\_)(\_\_\_)(?!\_)(.*?)(?<!\_)(\_\_\_)(?!\_)/;

export const CODERegex = /^(```)([^]*?)(```)/;

0 comments on commit 4f3135b

Please sign in to comment.