- fix bug: missing nodes in global graph

- fix bug: mismatch mapping node in index page (/)
- local graph now include both backlink and forward link
This commit is contained in:
Tuan Cao 2022-04-18 11:48:36 +07:00
parent 13e6cca5a4
commit ce8de2da9f
4 changed files with 60 additions and 37 deletions

View File

@ -44,6 +44,8 @@ export const Transformer = {
if (result === undefined || result.length === 0) { if (result === undefined || result.length === 0) {
console.log("Cannot resolve file path " + pageName) console.log("Cannot resolve file path " + pageName)
} }
// console.log("Internal Link resolved: [" + pageName + "] ==> [" + temp[0] +"]")
return (result !== undefined && result.length > 0) ? [toSlug(result)] : ["/"] return (result !== undefined && result.length > 0) ? [toSlug(result)] : ["/"]
}, },
hrefTemplate: function (permalink) { hrefTemplate: function (permalink) {
@ -122,8 +124,6 @@ export const Transformer = {
}, },
/* Pair provided and existing Filenames*/ /* Pair provided and existing Filenames*/
getInternalLinks: function (aFilePath) { getInternalLinks: function (aFilePath) {
// const filePaths = Node.getFiles(postsDirectory);
// const currentFilePath = Transformer.pairCurrentFile(aFilePath, filePaths)
const fileContent = Node.readFileSync(aFilePath); const fileContent = Node.readFileSync(aFilePath);
const internalLinks = [] const internalLinks = []
const sanitizedContent = Transformer.preprocessThreeDashes(fileContent) const sanitizedContent = Transformer.preprocessThreeDashes(fileContent)
@ -155,11 +155,10 @@ export const Transformer = {
shortSummary: canonicalSlug shortSummary: canonicalSlug
} }
if (canonicalSlug != null && internalLinks.find(aLink => aLink.slug === canonicalSlug) == null) { if (canonicalSlug != null && internalLinks.indexOf(canonicalSlug) < 0) {
internalLinks.push(backLink); internalLinks.push(backLink);
} }
return [canonicalSlug] return [canonicalSlug]
} }
, ,
@ -172,6 +171,11 @@ export const Transformer = {
.use(html) .use(html)
.processSync(sanitizedContent) .processSync(sanitizedContent)
// console.log("Internal Links of: " + aFilePath)
// internalLinks.forEach(aLink => {
// console.log(aLink.title + " --> " + aLink.slug)
// })
// console.log("===============Internal Links")
return internalLinks; return internalLinks;
} }
} }

View File

@ -29,8 +29,9 @@ export function getShortSummary(slug) {
export function getAllMarkdownFiles() { export function getAllMarkdownFiles() {
return Node.getFiles(Node.getMarkdownFolder()) return Node.getFiles(Node.getMarkdownFolder())
} }
export function getSinglePost(slug) { export function getSinglePost(slug) {
console.log("\n\nFile is scanning: ", slug)
// List of filenames that will provide existing links to wikilink // List of filenames that will provide existing links to wikilink
let currentFilePath = slug !== "index" ? toFilePath(slug) : Node.getMarkdownFolder() + "/index.md" let currentFilePath = slug !== "index" ? toFilePath(slug) : Node.getMarkdownFolder() + "/index.md"
@ -39,8 +40,9 @@ export function getSinglePost(slug) {
var fileContent = Node.readFileSync(currentFilePath) var fileContent = Node.readFileSync(currentFilePath)
const currentFileFrontMatter = Transformer.getFrontMatterData(fileContent) const currentFileFrontMatter = Transformer.getFrontMatterData(fileContent)
// console.log("===============\n\nFile is scanning: ", slug)
const [htmlContent] = Transformer.getHtmlContent(fileContent) const [htmlContent] = Transformer.getHtmlContent(fileContent)
// console.log("==================================")
//console.log("hrmlcontents and backlinks") //console.log("hrmlcontents and backlinks")
return { return {
id: slug, id: slug,
@ -52,15 +54,15 @@ export function getSinglePost(slug) {
export function toFilePath(slug) { export function toFilePath(slug) {
// Construct file name from slug of /notes/abcxyz // Construct file name from slug of /notes/abcxyz
let filePath ; let filePath;
if (slug === '/') { if (slug === '/') {
filePath = Node.getMarkdownFolder() + "/index.md" filePath = Node.getMarkdownFolder() + "/index.md"
} else { } else {
filePath = Node.getMarkdownFolder() + slug filePath = Node.getMarkdownFolder() + slug
.replaceAll('__','/') .replaceAll('__', '/')
.replaceAll('--',' ') .replaceAll('--', ' ')
.replaceAll('ambersand','&') .replaceAll('ambersand', '&')
+ ".md"; + ".md";
} }
@ -76,9 +78,9 @@ export function toSlug(filePath) {
if (Node.isFile(filePath) && filePath.includes(Node.getMarkdownFolder())) { if (Node.isFile(filePath) && filePath.includes(Node.getMarkdownFolder())) {
return filePath.replace(Node.getMarkdownFolder(), '') return filePath.replace(Node.getMarkdownFolder(), '')
.replaceAll('/','__') .replaceAll('/', '__')
.replaceAll(' ','--') .replaceAll(' ', '--')
.replaceAll('&','ambersand') .replaceAll('&', 'ambersand')
.replace('.md', '') .replace('.md', '')
} else { } else {
//TODO handle this properly //TODO handle this properly
@ -88,30 +90,36 @@ export function toSlug(filePath) {
} }
export function constructBackLinks() { export function constructGraphData() {
const filePaths = getAllMarkdownFiles(); const filePaths = getAllMarkdownFiles();
const edges = [] const edges = []
const nodes = [] const nodes = []
filePaths.forEach(filename => { filePaths
.forEach(aFilePath => {
// const {currentFilePath} = getFileNames(filename) // const {currentFilePath} = getFileNames(filename)
const internalLinks = Transformer.getInternalLinks(filename) const aNode = {
slug: toSlug(aFilePath),
shortSummary: getShortSummary(toSlug(aFilePath))
}
nodes.push(aNode)
console.log("Constructing graph for node: " + aFilePath )
const internalLinks = Transformer.getInternalLinks(aFilePath)
internalLinks.forEach(aLink => { internalLinks.forEach(aLink => {
if (aLink.slug === null || aLink.slug.length === 0) return if (aLink.slug === null || aLink.slug.length === 0) return
const anEdge = { const anEdge = {
source: toSlug(filename), source: toSlug(aFilePath),
target: aLink.slug, target: aLink.slug,
} }
edges.push(anEdge) edges.push(anEdge)
if (nodes.findIndex(aNode => aNode.slug === aLink.slug) === -1) { console.log("Source: " + anEdge.source)
aLink.shortSummary = getShortSummary(aLink.slug) console.log("Target: " + anEdge.target)
// console.log(aLink.shortSummary)
nodes.push(aLink)
}
}) })
console.log("==============Constructing graph" )
} }
) )
@ -119,9 +127,9 @@ export function constructBackLinks() {
} }
export function getGraphData(currentNodeId) { export function getLocalGraphData(currentNodeId) {
const {nodes, edges} = constructBackLinks() const {nodes, edges} = constructGraphData()
const newNodes = nodes.map(aNode => ( const newNodes = nodes.map(aNode => (
{ {
@ -140,18 +148,29 @@ export function getGraphData(currentNodeId) {
})) }))
const existingNodeIDs = newNodes.map(aNode => aNode.data.id) const existingNodeIDs = newNodes.map(aNode => aNode.data.id)
currentNodeId = currentNodeId === 'index' ? '__index' : currentNodeId
if (currentNodeId != null && existingNodeIDs.includes(currentNodeId)) { if (currentNodeId != null && existingNodeIDs.includes(currentNodeId)) {
const localNodeIDs = newEdges const outGoingNodeIds = newEdges
.filter(anEdge => anEdge.data.source === currentNodeId) .filter(anEdge => anEdge.data.source === currentNodeId)
.map(anEdge => anEdge.data.target) .map(anEdge => anEdge.data.target)
localNodeIDs.push(currentNodeId) const incomingNodeIds = newEdges
.filter(anEdge => anEdge.data.target === currentNodeId)
.map(anEdge => anEdge.data.source)
const localNodes = newNodes.filter(aNode => localNodeIDs.includes(aNode.data.id)) outGoingNodeIds.push(currentNodeId)
const localEdges = newEdges.filter(edge => localNodeIDs.includes(edge.data.source)).filter(edge => localNodeIDs.includes(edge.data.target))
const localNodeIds = incomingNodeIds.concat(outGoingNodeIds.filter(item => incomingNodeIds.indexOf(item) < 0))
if (localNodeIds.indexOf(currentNodeId) < 0) {
localNodeIds.push(currentNodeId)
}
const localNodes = newNodes.filter(aNode => localNodeIds.includes(aNode.data.id))
var localEdges = newEdges.filter(edge => localNodeIds.includes(edge.data.source)).filter(edge => localNodeIds.includes(edge.data.target))
// Filter self-reference edges
localEdges = localEdges.filter(edge => edge.data.source !== edge.data.target)
return { return {
nodes: localNodes, nodes: localNodes,
edges: localEdges edges: localEdges
@ -189,7 +208,7 @@ export function convertObject(thisObject) {
let routerPath = getAllSlugs().find(slug => { let routerPath = getAllSlugs().find(slug => {
const fileName = Transformer.parseFileNameFromPath(toFilePath(slug)) const fileName = Transformer.parseFileNameFromPath(toFilePath(slug))
return Transformer.normalizeFileName(fileName) === Transformer.normalizeFileName(thisObject.name) return Transformer.normalizeFileName(fileName) === Transformer.normalizeFileName(thisObject.name)
}) || null }) || null
routerPath = routerPath ? '/note/' + routerPath : null routerPath = routerPath ? '/note/' + routerPath : null
const newObject = { const newObject = {

View File

@ -1,5 +1,5 @@
import Layout from "../components/Layout"; import Layout from "../components/Layout";
import {getSinglePost, getDirectoryData, convertObject, getFlattenArray, getGraphData} from "../lib/utils"; import {getSinglePost, getDirectoryData, convertObject, getFlattenArray, getLocalGraphData} from "../lib/utils";
import FolderTree from "../components/FolderTree"; import FolderTree from "../components/FolderTree";
import MDContainer from "../components/MDContainer"; import MDContainer from "../components/MDContainer";
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
@ -32,7 +32,7 @@ export function getStaticProps() {
const tree = convertObject(getDirectoryData()); const tree = convertObject(getDirectoryData());
const contentData = getSinglePost("index"); const contentData = getSinglePost("index");
const flattenNodes = getFlattenArray(tree) const flattenNodes = getFlattenArray(tree)
const graphData = getGraphData("index"); const graphData = getLocalGraphData("index");
return { return {
props: { props: {
content: contentData, content: contentData,

View File

@ -5,7 +5,7 @@ import {
getSinglePost, getSinglePost,
convertObject, convertObject,
getDirectoryData, getDirectoryData,
constructBackLinks, getGraphData constructGraphData, getLocalGraphData
} from "../../lib/utils"; } from "../../lib/utils";
import FolderTree from "../../components/FolderTree"; import FolderTree from "../../components/FolderTree";
import {getFlattenArray} from "../../lib/utils"; import {getFlattenArray} from "../../lib/utils";
@ -46,7 +46,7 @@ export async function getStaticPaths() {
}; };
} }
const {nodes, edges} = constructBackLinks() const {nodes, edges} = constructGraphData()
export function getStaticProps({params}) { export function getStaticProps({params}) {
const note = getSinglePost(params.id); const note = getSinglePost(params.id);
@ -56,7 +56,7 @@ export function getStaticProps({params}) {
const listOfEdges = edges.filter(anEdge => anEdge.target === params.id) const listOfEdges = edges.filter(anEdge => anEdge.target === params.id)
const internalLinks = listOfEdges.map(anEdge => nodes.find(aNode => aNode.slug === anEdge.source)).filter(element => element !== undefined) const internalLinks = listOfEdges.map(anEdge => nodes.find(aNode => aNode.slug === anEdge.source)).filter(element => element !== undefined)
const graphData = getGraphData(params.id) const graphData = getLocalGraphData(params.id)
return { return {
props: { props: {
note, note,