Skip to content

Commit

Permalink
Use remark to parse codeblocks (#96)
Browse files Browse the repository at this point in the history
* add failing test

* use remark

* fix docs with rollup
  • Loading branch information
platers authored Oct 8, 2021
1 parent 2637526 commit 547306a
Show file tree
Hide file tree
Showing 11 changed files with 5,962 additions and 7,603 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
node_modules

# build
main.js
*.js
*.js.map

# obsidian
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<!--- This file was automatically generated. See docs.ts and *_template.md files for the source. -->

# Obsidian Linter
![Build](https://github.com/platers/obsidian-linter/actions/workflows/main.yml/badge.svg)
![Downloads](https://img.shields.io/github/downloads/platers/obsidian-linter/total)

# Obsidian Linter

This Obsidian plugin formats and styles your notes with a focus on configurability and extensibility.
Rules can be toggled and configured in the settings.

Expand Down
2 changes: 1 addition & 1 deletion docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ Example:
Before:

```markdown
1. Item 1
1. Item 1
2. Item 2

- [ ] Item 1
Expand Down
11 changes: 11 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
process.env.TZ = 'UTC';

// jest.config.ts
import type {Config} from '@jest/types';

// Sync object
const config: Config.InitialOptions = {
transformIgnorePatterns: [
'"/node_modules/(?!unified-lint-rule)',
],
};
export default config;
13,381 changes: 5,835 additions & 7,546 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "rollup --config rollup.config.js -w",
"build": "rollup --config rollup.config.js --environment BUILD:production",
"test": "jest",
"docs": "ts-node --project ./tsconfig-docs.json ./src/docs.ts",
"docs": "node docs.js",
"compile": "npm run build && npm run docs && npm run lint && npm run test",
"lint": "eslint . --ext .ts --fix"
},
Expand Down Expand Up @@ -41,6 +41,8 @@
"diff": "^4.0.2",
"js-yaml": "^3.14.1",
"moment": "^2.29.1",
"ts-dedent": "^2.2.0"
"remark": "^14.0.1",
"ts-dedent": "^2.2.0",
"unified-lint-rule": "^2.1.0"
}
}
49 changes: 33 additions & 16 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,37 @@ if you want to view the source visit the plugins github repository
*/
`;

export default {
input: 'src/main.ts',
output: {
dir: '.',
sourcemap: 'inline',
sourcemapExcludeSources: isProd,
format: 'cjs',
exports: 'default',
banner,
export default [
{
input: 'src/main.ts',
output: {
dir: '.',
sourcemap: 'inline',
sourcemapExcludeSources: isProd,
format: 'cjs',
exports: 'default',
banner,
},
external: ['obsidian'],
plugins: [
typescript(),
nodeResolve({browser: true}),
commonjs(),
]
},
external: ['obsidian'],
plugins: [
typescript(),
nodeResolve({browser: true}),
commonjs(),
]
};
{
input: 'src/docs.ts',
output: {
dir: '.',
sourcemap: 'inline',
format: 'cjs',
banner,
},
external: ['obsidian'],
plugins: [
typescript(),
nodeResolve({browser: true}),
commonjs(),
]
}
];
2 changes: 1 addition & 1 deletion src/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export const rules: Rule[] = [
new Example(
'',
dedent`
1. Item 1
1. Item 1
2. Item 2
- [ ] Item 1
Expand Down
36 changes: 36 additions & 0 deletions src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ describe('Paragraph blank lines', () => {
`;
expect(rulesDict['paragraph-blank-lines'].apply(before)).toBe(after);
});
it('Handles lists', () => {
const before = dedent`
Hello
World
- 1
\t- 2
- 3
`;
const after = dedent`
Hello
World
- 1
\t- 2
- 3
`;
expect(rulesDict['paragraph-blank-lines'].apply(before)).toBe(after);
});
});
describe('Consecutive blank lines', () => {
it('Handles ignores code blocks', () => {
Expand All @@ -253,6 +272,23 @@ describe('Consecutive blank lines', () => {
expect(rulesDict['consecutive-blank-lines'].apply(before)).toBe(after);
});
});
describe('Convert spaces to tabs', () => {
it('Basic case', () => {
const before = dedent`
- Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Vestibulum id tortor lobortis, tristique mi quis, pretium metus.
- Nunc ut arcu fermentum enim auctor accumsan ut a risus.
- Donec ut auctor dui.
`;
const after = dedent`
- Lorem ipsum dolor sit amet, consectetur adipiscing elit.
\t- Vestibulum id tortor lobortis, tristique mi quis, pretium metus.
- Nunc ut arcu fermentum enim auctor accumsan ut a risus.
\t\t- Donec ut auctor dui.
`;
expect(rulesDict['convert-spaces-to-tabs'].apply(before, {Tabsize: '4'})).toBe(after);
});
});

describe('Trailing spaces', () => {
it('One trailing space removed', () => {
Expand Down
50 changes: 39 additions & 11 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {rules} from './rules';
import {load} from 'js-yaml';
import {remark} from 'remark';
import {visit} from 'unist-util-visit';
import type {Position} from 'unist';

// Useful regexes

Expand Down Expand Up @@ -47,6 +50,37 @@ export function getDisabledRules(text: string): string[] {
return disabled_rules;
}


/**
* Replaces all codeblocks in the given text with a placeholder.
* @param {string} text The text to replace codeblocks in
* @param {string} placeholder The placeholder to use
* @return {string} The text with codeblocks replaced, and the list of codeblocks
* @return {string[]} The codeblocks replaced
*/
function replaceCodeblocks(text: string, placeholder: string): {text: string, replacedCodeBlocks: string[]} {
const ast = remark().parse(text);
const replacedCodeBlocks: string[] = [];
const positions: Position[] = [];
visit(ast, 'code', (node) => {
positions.push(node.position);
});

// Sort positions by start position in reverse order
positions.sort((a, b) => b.start.offset - a.start.offset);

for (const position of positions) {
const codeblock = text.substring(position.start.offset, position.end.offset);
replacedCodeBlocks.push(codeblock);
text = text.substring(0, position.start.offset) + placeholder + text.substring(position.end.offset);
}

// Reverse the codeblocks so that they are in the same order as the original text
replacedCodeBlocks.reverse();

return {text, replacedCodeBlocks};
}

/**
* Substitutes YAML and codeblocks in a text with a placeholder.
* Then applies the given function to the text.
Expand All @@ -56,31 +90,25 @@ export function getDisabledRules(text: string): string[] {
* @return {string} The processed text
*/
export function ignoreCodeBlocksAndYAML(text: string, func: (text: string) => string): string {
const codeMatches = text.match(codeBlockRegex);
const codePlaceholder = 'PLACEHOLDER 321417';
if (codeMatches) {
for (const match of codeMatches) {
text = text.replace(match, codePlaceholder);
}
}
const ret = replaceCodeblocks(text, codePlaceholder);
text = ret.text;
const replacedCodeBlocks = ret.replacedCodeBlocks;

const yamlPlaceholder = '---\n---';
const yamlMatches = text.match(yamlRegex);
if (yamlMatches) {
text = text.replace(yamlMatches[0], yamlPlaceholder);
}


text = func(text);

if (yamlMatches) {
text = text.replace(yamlPlaceholder, yamlMatches[0]);
}

if (codeMatches) {
for (const match of codeMatches) {
text = text.replace(codePlaceholder, match);
}
for (const codeblock of replacedCodeBlocks) {
text = text.replace(codePlaceholder, codeblock);
}

return text;
Expand Down
23 changes: 0 additions & 23 deletions tsconfig-docs.json

This file was deleted.

0 comments on commit 547306a

Please sign in to comment.