2022-04-28 09:51:00 +00:00
|
|
|
import {visit} from "unist-util-visit";
|
2022-04-28 09:45:10 +00:00
|
|
|
|
2022-04-28 09:51:00 +00:00
|
|
|
const regex = /\!\[\[(([a-z\-_0-9\\/\:]+\s*)+\.(jpg|jpeg|png|gif|svg|webp))]]/gi;
|
2022-04-28 10:15:28 +00:00
|
|
|
const regex2 = /\!\[\[(([a-z\-_0-9\\/\:]+\s*)+\.(jpg|jpeg|png|gif|svg|webp))]]/gi; //TODO why can't I reuse regex literal???
|
2022-04-28 09:45:10 +00:00
|
|
|
|
2022-04-28 09:51:00 +00:00
|
|
|
function convertTextNode(node) {
|
|
|
|
const searchText = node.value;
|
|
|
|
|
|
|
|
/*
|
|
|
|
This regex MATCH following type of image link
|
|
|
|
![[youtube.png]] ==> Image with no folder path, no space in between
|
|
|
|
![[a .png]] ==> with space
|
|
|
|
![[tuancao/a.png]] ==> file path WITHOUT space
|
|
|
|
![[tuancao/a .png]] ==> file path WITH space
|
|
|
|
|
|
|
|
Image with extension: jpg, jpeg, gif, svg, webp, png
|
|
|
|
![[/tuancao/a.jpg]]
|
|
|
|
![[/tuancao/a.webp]]
|
|
|
|
![[/tuancao/a.png]]
|
|
|
|
![[/tuancao/a.jpeg]]
|
|
|
|
...
|
|
|
|
|
|
|
|
---
|
|
|
|
Will NOT match following case
|
|
|
|
|
|
|
|
[[picture.jpg]] ==> Link without "!" at the begining won't match
|
|
|
|
![[abc]] ==> without the extension
|
|
|
|
![[/tuancao/a.md]] ==> Unsupported format
|
|
|
|
![[/tuancao/a.mp4]]==> Unsupported format
|
|
|
|
*/
|
|
|
|
const matches = searchText.matchAll(
|
|
|
|
regex
|
|
|
|
);
|
|
|
|
|
|
|
|
let startIndex = 0;
|
|
|
|
let endIndex = searchText.length;
|
|
|
|
|
|
|
|
let children = [];
|
|
|
|
for (const match of matches) {
|
|
|
|
endIndex = match.index;
|
|
|
|
|
|
|
|
// Constructing text node from un-matched string
|
|
|
|
const textNode = {
|
|
|
|
// change type child node, so that visit() function won't recursively visit this node with "text" type
|
|
|
|
type: "text-temp",
|
|
|
|
value: searchText.substring(startIndex, endIndex),
|
|
|
|
};
|
|
|
|
|
|
|
|
const imageNode = {
|
2022-04-28 10:15:28 +00:00
|
|
|
type: "image",
|
|
|
|
//TODO: Use some kind of option to pass in default images path
|
2022-04-28 10:17:44 +00:00
|
|
|
url: encodeURI(`/images/${match[1]}`), //encode white space from file name
|
2022-04-28 09:51:00 +00:00
|
|
|
alt: match[1],
|
|
|
|
};
|
|
|
|
|
|
|
|
children.push(imageNode);
|
|
|
|
|
|
|
|
let matchEndIndex = match.index + match[0].length;
|
|
|
|
startIndex = matchEndIndex;
|
|
|
|
}
|
2022-04-28 09:45:10 +00:00
|
|
|
|
2022-04-28 09:51:00 +00:00
|
|
|
if (startIndex < searchText.length) {
|
|
|
|
const textNode = {
|
|
|
|
type: "text-temp",
|
|
|
|
value: searchText.substring(startIndex, searchText.length),
|
|
|
|
};
|
|
|
|
children.push(textNode);
|
2022-04-28 09:45:10 +00:00
|
|
|
}
|
|
|
|
|
2022-04-28 09:51:00 +00:00
|
|
|
return {
|
|
|
|
type: "paragraph",
|
|
|
|
children: children,
|
|
|
|
};
|
2022-04-28 09:45:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export default function attacher(options) {
|
2022-04-28 09:51:00 +00:00
|
|
|
return function transformer(tree, vfile) {
|
|
|
|
visit(tree, "text", (node) => {
|
2022-04-28 10:15:28 +00:00
|
|
|
if (regex2.test(node.value)) {
|
2022-04-28 09:51:00 +00:00
|
|
|
const newNode = convertTextNode(node);
|
|
|
|
node.type = "paragraph";
|
|
|
|
node.children = newNode.children;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Change back "text-temp" node ==> "text" to clean up
|
|
|
|
visit(tree, "text-temp", (node) => {
|
|
|
|
node.type = "text";
|
|
|
|
});
|
|
|
|
|
|
|
|
return tree;
|
|
|
|
};
|
2022-04-28 09:45:10 +00:00
|
|
|
}
|