Skip to content

Commit

Permalink
linting
Browse files Browse the repository at this point in the history
  • Loading branch information
jwbargsten committed May 30, 2021
1 parent f0fed05 commit f5c850f
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 96 deletions.
23 changes: 11 additions & 12 deletions src/hast-processing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Parent } from 'unist';
import { Parent } from "unist"

function duplicateNode(node: Parent) {
return {
Expand All @@ -16,14 +16,17 @@ function getConcatenatedValue(node: Parent | undefined): string {
} else if (node.children && node.children.length) {
return (node.children as Parent[])
.map(getConcatenatedValue)
.filter((value) => value)
.filter(value => value)
.join(``)
}
return ``
}

function cloneTreeUntil(root: Parent, endCondition: ({root, nextNode}: {root: Parent | undefined, nextNode?: Parent}) => boolean): {tree: Parent, is_pruned: boolean} {
let clonedRoot: Parent | undefined;
function cloneTreeUntil(
root: Parent,
endCondition: ({ root, nextNode }: { root: Parent | undefined; nextNode?: Parent }) => boolean
): { tree: Parent; is_pruned: boolean } {
let clonedRoot: Parent | undefined
let endConditionMet = false

function preOrderTraversal(node: Parent) {
Expand All @@ -34,13 +37,13 @@ function cloneTreeUntil(root: Parent, endCondition: ({root, nextNode}: {root: Pa

const newNode = duplicateNode(node)
if (clonedRoot) {
(clonedRoot.children as Parent[]).push(newNode)
;(clonedRoot.children as Parent[]).push(newNode)
} else {
clonedRoot = newNode
}

if (node.children) {
(node.children as Parent[]).forEach((child) => {
;(node.children as Parent[]).forEach(child => {
clonedRoot = newNode
preOrderTraversal(child)
})
Expand All @@ -56,7 +59,7 @@ function findLastTextNode(node: Parent, textNode?: Parent): Parent | undefined {
textNode = node
}
if (node.children) {
(node.children as Parent[]).forEach((child) => {
;(node.children as Parent[]).forEach(child => {
const laterTextNode = findLastTextNode(child, textNode)
if (laterTextNode !== textNode) {
textNode = laterTextNode
Expand All @@ -66,8 +69,4 @@ function findLastTextNode(node: Parent, textNode?: Parent): Parent | undefined {
return textNode
}

export {
getConcatenatedValue,
cloneTreeUntil,
findLastTextNode,
}
export { getConcatenatedValue, cloneTreeUntil, findLastTextNode }
21 changes: 16 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { toString, truncate as truncateString } from "lodash"
import { prune } from "./prune"
import { getConcatenatedValue, cloneTreeUntil, findLastTextNode } from "./hast-processing"
import type { Node, Parent } from 'unist';
import { Node, Parent } from "unist"

// stolen from gatsby/packages/gatsby-transformer-remark/src/extend-node-type.js

function excerptAst(node: Node, { pruneLength = 140, truncate = false, excerptSeparator, omission = `…` }: { pruneLength?: number, truncate?: boolean, excerptSeparator?: string, omission?: string}) {
function excerptAst(
node: Node,
{
pruneLength = 140,
truncate = false,
excerptSeparator,
omission = `…`,
}: { pruneLength?: number; truncate?: boolean; excerptSeparator?: string; omission?: string }
) {
if (!(node as Parent)?.children?.length) {
return node
}

if (excerptSeparator) {
const { tree, is_pruned } = cloneTreeUntil(node as Parent, ({ nextNode }) => nextNode?.value === excerptSeparator)
const { tree, is_pruned } = cloneTreeUntil(
node as Parent,
({ nextNode }) => nextNode?.value === excerptSeparator
)
if (is_pruned) {
return tree
}
Expand All @@ -29,10 +40,10 @@ function excerptAst(node: Node, { pruneLength = 140, truncate = false, excerptSe
}

const lastTextNode = findLastTextNode(excerptAST)
if(!lastTextNode) {
if (!lastTextNode) {
return excerptAST
}
const lastTextNodeValue = toString(lastTextNode.value);
const lastTextNodeValue = toString(lastTextNode.value)
const amountToPruneBy = unprunedExcerpt.length - pruneLength
const desiredLengthOfLastNode = lastTextNodeValue.length - amountToPruneBy
if (!truncate) {
Expand Down
40 changes: 18 additions & 22 deletions src/prune.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import { toString as makeString } from 'lodash';
import { toString as makeString } from "lodash"
/**
* Ensure some object is a coerced to a string
**/

function escapeRegExp(str: string): string {
return makeString(str).replace(/([.*+?^=!:${}()|[\]/\\])/g, '\\$1');
return makeString(str).replace(/([.*+?^=!:${}()|[\]/\\])/g, "\\$1")
}
function defaultToWhiteSpace(characters?: string): string {
return characters == null ? '\\s' : '[' + escapeRegExp(characters) + ']';
return characters == null ? "\\s" : "[" + escapeRegExp(characters) + "]"
}

const nativeTrimRight = String.prototype.trimRight;
const nativeTrimRight = String.prototype.trimRight

function rtrim(str: string, characters?: string): string {
str = makeString(str);
if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
characters = defaultToWhiteSpace(characters);
return str.replace(new RegExp(characters + '+$'), '');
str = makeString(str)
if (!characters && nativeTrimRight) return nativeTrimRight.call(str)
characters = defaultToWhiteSpace(characters)
return str.replace(new RegExp(characters + "+$"), "")
}

/**
Expand All @@ -26,24 +26,20 @@ function rtrim(str: string, characters?: string): string {
*/

function prune(str: string, length: number, pruneStr: string): string {
str = makeString(str);
length = ~~length;
pruneStr = pruneStr != null ? String(pruneStr) : '...';
str = makeString(str)
length = ~~length
pruneStr = pruneStr != null ? String(pruneStr) : "..."

if (str.length <= length) return str;
if (str.length <= length) return str

const tmpl = (c: string): string =>
c.toUpperCase() !== c.toLowerCase() ? 'A' : ' ';
const tmpl = (c: string): string => (c.toUpperCase() !== c.toLowerCase() ? "A" : " ")

let template = str.slice(0, length + 1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
let template = str.slice(0, length + 1).replace(/.(?=\W*\w*$)/g, tmpl) // 'Hello, world' -> 'HellAA AAAAA'

if (template.slice(template.length - 2).match(/\w\w/))
template = template.replace(/\s*\S+$/, '');
else template = rtrim(template.slice(0, template.length - 1));
if (template.slice(template.length - 2).match(/\w\w/)) template = template.replace(/\s*\S+$/, "")
else template = rtrim(template.slice(0, template.length - 1))

return (template + pruneStr).length > str.length
? str
: str.slice(0, template.length) + pruneStr;
return (template + pruneStr).length > str.length ? str : str.slice(0, template.length) + pruneStr
}

export { prune };
export { prune }
108 changes: 51 additions & 57 deletions test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,81 @@
import remark from 'remark';
import stringify from 'remark-stringify';
import excerptAst from '../src';
import remark from "remark"
import stringify from "remark-stringify"
import excerptAst from "../src"

// fake the plugin
const asExcerpt = (options: any) => (node: any) =>
excerptAst(node, options || {});
const asExcerpt = (options: any) => (node: any) => excerptAst(node, options || {})

const runRemark = (md: any, options: any) =>
remark()
.use(asExcerpt, options)
.use(stringify)
.processSync(md);
.processSync(md)

test('should be able to prune only full words', () => {
const res = runRemark('*Full emphasis* and _high stress_, you guys!', {
test("should be able to prune only full words", () => {
const res = runRemark("*Full emphasis* and _high stress_, you guys!", {
pruneLength: 3,
});
expect(String(res)).toBe(`*…*\n`);
});
})
expect(String(res)).toBe(`*…*\n`)
})

test('should not prune if pruneLength not > 0', () => {
const res = runRemark('*Full emphasis* and _high stress_, you guys!', {
test("should not prune if pruneLength not > 0", () => {
const res = runRemark("*Full emphasis* and _high stress_, you guys!", {
pruneLength: 0,
});
expect(String(res)).toBe('*Full emphasis* and *high stress*, you guys!\n');
});
})
expect(String(res)).toBe("*Full emphasis* and *high stress*, you guys!\n")
})

test('should be able to prune till first word', () => {
const res = runRemark('*Full emphasis* and _high stress_, **you guys**!', {
test("should be able to prune till first word", () => {
const res = runRemark("*Full emphasis* and _high stress_, **you guys**!", {
pruneLength: 4,
});
expect(String(res)).toBe(`*Full…*\n`);
});
})
expect(String(res)).toBe(`*Full…*\n`)
})

test('should be able to prune in bold text', () => {
const res = runRemark('*Full emphasis* and _high stress_, **you guys**!', {
test("should be able to prune in bold text", () => {
const res = runRemark("*Full emphasis* and _high stress_, **you guys**!", {
pruneLength: 34,
});
expect(String(res)).toBe(`*Full emphasis* and *high stress*, **you…**\n`);
});
})
expect(String(res)).toBe(`*Full emphasis* and *high stress*, **you…**\n`)
})

test('should be able to deal with imgs', () => {
test("should be able to deal with imgs", () => {
const res = runRemark(
'*Full emphasis* and _high stress_, **![text](https://via.placeholder.com/150) guys**!',
"*Full emphasis* and _high stress_, **![text](https://via.placeholder.com/150) guys**!",
{
pruneLength: 34,
}
);
)
expect(String(res)).toBe(
`*Full emphasis* and *high stress*, **![text](https://via.placeholder.com/150)…**\n`
);
});
)
})

test('should not deal with html stuff', () => {
const res = runRemark(
'*Full emphasis* and _high stress_, <strong>some crazy html code</strong>',
{
pruneLength: 34,
}
);
test("should not deal with html stuff", () => {
const res = runRemark("*Full emphasis* and _high stress_, <strong>some crazy html code</strong>", {
pruneLength: 34,
})
// We don't deal with html in markdown, use rehype-raw to parse html in markdown beforehand
expect(String(res).trimRight()).toBe(
'*Full emphasis* and *high stress*, <strong>…'
);
});
expect(String(res).trimRight()).toBe("*Full emphasis* and *high stress*, <strong>…")
})

test('should handle excerpt separator correctly with html node', () => {
test("should handle excerpt separator correctly with html node", () => {
const md = `
Where oh where is my little pony?
<!-- end -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi auctor sit amet velit id facilisis. Nulla viverra, eros at efficitur pulvinar, lectus orci accumsan nisi, eu blandit elit nulla nec lectus. Integer porttitor imperdiet sapien. Quisque in orci sed nisi consequat aliquam. Aenean id mollis nisi. Sed auctor odio id erat facilisis venenatis. Quisque posuere faucibus libero vel fringilla.
In quis lectus sed eros efficitur luctus. Morbi tempor, nisl eget feugiat tincidunt, sem velit vulputate enim, nec interdum augue enim nec mauris. Nulla iaculis ante sed enim placerat pretium. Nulla metus odio, facilisis vestibulum lobortis vitae, bibendum at nunc. Donec sit amet efficitur metus, in bibendum nisi. Vivamus tempus vel turpis sit amet auctor. Maecenas luctus vestibulum velit, at sagittis leo volutpat quis. Praesent posuere nec augue eget sodales. Pellentesque vitae arcu ut est varius venenatis id maximus sem. Curabitur non consectetur turpis.
`;
`

const res = runRemark(md, {
excerptSeparator: `<!-- end -->`,
pruneLength: 34,
});
expect(String(res)).toBe(`Where oh where is my little pony?\n`);
});
})
expect(String(res)).toBe(`Where oh where is my little pony?\n`)
})

test('should handle excerpt separator correctly with text node', () => {
test("should handle excerpt separator correctly with text node", () => {
const md = `
Where oh where is my little pony?
Expand All @@ -90,25 +84,25 @@ ENDOFEXCERPT
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi auctor sit amet velit id facilisis. Nulla viverra, eros at efficitur pulvinar, lectus orci accumsan nisi, eu blandit elit nulla nec lectus. Integer porttitor imperdiet sapien. Quisque in orci sed nisi consequat aliquam. Aenean id mollis nisi. Sed auctor odio id erat facilisis venenatis. Quisque posuere faucibus libero vel fringilla.
In quis lectus sed eros efficitur luctus. Morbi tempor, nisl eget feugiat tincidunt, sem velit vulputate enim, nec interdum augue enim nec mauris. Nulla iaculis ante sed enim placerat pretium. Nulla metus odio, facilisis vestibulum lobortis vitae, bibendum at nunc. Donec sit amet efficitur metus, in bibendum nisi. Vivamus tempus vel turpis sit amet auctor. Maecenas luctus vestibulum velit, at sagittis leo volutpat quis. Praesent posuere nec augue eget sodales. Pellentesque vitae arcu ut est varius venenatis id maximus sem. Curabitur non consectetur turpis.
`;
`

const res = runRemark(md, {
excerptSeparator: `ENDOFEXCERPT`,
pruneLength: 34,
});
expect(String(res)).toBe(`Where oh where is my little pony?\n\n`);
});
})
expect(String(res)).toBe(`Where oh where is my little pony?\n\n`)
})

test('should fall back to pruneLength if no excerpt separator', () => {
test("should fall back to pruneLength if no excerpt separator", () => {
const md = `
Where oh where **is** my little pony? Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi auctor sit amet velit id facilisis. Nulla viverra, eros at efficitur pulvinar, lectus orci accumsan nisi, eu blandit elit nulla nec lectus. Integer porttitor imperdiet sapien. Quisque in orci sed nisi consequat aliquam. Aenean id mollis nisi. Sed auctor odio id erat facilisis venenatis. Quisque posuere faucibus libero vel fringilla.
In quis lectus sed eros efficitur luctus. Morbi tempor, nisl eget feugiat tincidunt, sem velit vulputate enim, nec interdum augue enim nec mauris. Nulla iaculis ante sed enim placerat pretium. Nulla metus odio, facilisis vestibulum lobortis vitae, bibendum at nunc. Donec sit amet efficitur metus, in bibendum nisi. Vivamus tempus vel turpis sit amet auctor. Maecenas luctus vestibulum velit, at sagittis leo volutpat quis. Praesent posuere nec augue eget sodales. Pellentesque vitae arcu ut est varius venenatis id maximus sem. Curabitur non consectetur turpis.
`;
`

const res = runRemark(md, {
excerptSeparator: `<!-- end -->`,
pruneLength: 40,
});
expect(String(res)).toBe(`Where oh where **is** my little pony? Lorem…\n`);
});
})
expect(String(res)).toBe(`Where oh where **is** my little pony? Lorem…\n`)
})

0 comments on commit f5c850f

Please sign in to comment.