Skip to content

Commit

Permalink
First version
Browse files Browse the repository at this point in the history
  • Loading branch information
jvasseur committed Apr 13, 2022
1 parent 6329279 commit 3f9ddc5
Show file tree
Hide file tree
Showing 8 changed files with 2,701 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[{package.json,yarn.lock}]
indent_size = 2
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/index.js
/index.d.ts
/node_modules/
35 changes: 35 additions & 0 deletions index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import indent from '.';

test('It correctly drops template indentation', () => {
expect(indent`
Test ${"value"}
`).toBe('Test value');
});

test('It works when there is no placeholders', () => {
expect(indent`
Test value
`).toBe('Test value');
});

test('It reindent placeholders', () => {
expect(indent`
<test>
${"test\nvalue"}
</test>
`).toBe('<test>\n test\n value\n</test>');
});

test('Nested indent test', () => {
const list = ['First', 'Second'];

expect(indent`
<test>
${list.map((name) => indent`
<value>
${name}
</value>
`).join('\n')}
</test>
`).toBe(`<test>\n <value>\n First\n </value>\n <value>\n Second\n </value>\n</test>`);
})
41 changes: 41 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const indentTag = (strings: TemplateStringsArray, ... expressions: any[]) => {
let parts: string[] = Array.from(strings);

// Drop first line feed
if ('\n' !== strings[0][0]) {
throw new Error('Expect first character to be a line feed');
}

parts[0] = parts[0].slice(1);

// Remove last line
parts[strings.length - 1] = parts[parts.length - 1].replace(/\n[ \t]*$/, '');

// Dedent using indent from first part
const indent = parts[0].match(/^[ \t]*/)![0];

const deindent = new RegExp(`(^|\n)${indent}`, 'g');

parts = parts.map((string) => string.replace(deindent, '$1'));

// Ensure expressions are strings
const values = expressions.map((expression) => String(expression));

// Reindent values
const indented = values.map((value, index) => {
const part = parts[index];

const match = part.match(/\n( *)$/);

// Only indent replacement if there is nothing before it on the line
if (!match) {
return value;
}

return value.replace(/\n/g, match[0]);
})

return parts.flatMap((part, index) => [part, indented[index]]).join('');
}

export default indentTag;
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
31 changes: 31 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "indent-tag",
"version": "0.1.0",
"description": "A template literal tag that automagically reindents placeholders",
"main": "index.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/jvasseur/indent-tag.git"
},
"author": "Jérôme Vasseur",
"license": "MIT",
"bugs": {
"url": "https://github.com/jvasseur/indent-tag/issues"
},
"homepage": "https://github.com/jvasseur/indent-tag#readme",
"devDependencies": {
"@tsconfig/node12": "^1.0.9",
"@types/jest": "^27.4.1",
"jest": "^27.5.1",
"ts-jest": "^27.1.4",
"typescript": "^4.6.3"
},
"scripts": {
"build": "tsc",
"test": "jest"
},
"files": [
"index.d.ts"
]
}
7 changes: 7 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@tsconfig/node12/tsconfig.json",
"compilerOptions": {
"declaration": true
},
"include": ["./index.ts"]
}
Loading

0 comments on commit 3f9ddc5

Please sign in to comment.