WIP: Render backlink in MarkDown content component.

This commit is contained in:
Tuan Cao 2022-04-07 10:44:02 +07:00
parent 930d7bf48d
commit b47d1053d8
4 changed files with 83 additions and 78 deletions

View File

@ -2,9 +2,29 @@ import React from 'react';
import Alert from '@mui/material/Alert'; import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle'; import AlertTitle from '@mui/material/AlertTitle';
import {useRouter} from 'next/router' import {useRouter} from 'next/router'
import {Transformer} from "../lib/transformer"; import Link from 'next/link'
function MDContent({content,fileNames, handleOpenNewContent}) { function BackLinks({linkList}) {
return (<ul>
{
(linkList != null && linkList.length > 0)
?
linkList.map(aLink =>
<li>
<Link href={aLink.link}>
<a>
{aLink.title}
</a>
</Link>
</li>
)
: <h1>No Back link found</h1>
}
</ul>);
}
function MDContent({content, fileNames, backLinks, handleOpenNewContent}) {
function handleInternalLinkClick() { function handleInternalLinkClick() {
//Processing fetching //Processing fetching
@ -12,16 +32,22 @@ function MDContent({content,fileNames, handleOpenNewContent}) {
//TODO: handle clicking on internal link, go fetching md content from file then passing it up to parent //TODO: handle clicking on internal link, go fetching md content from file then passing it up to parent
handleOpenNewContent(content) handleOpenNewContent(content)
} }
const router = useRouter(); const router = useRouter();
return ( return (
<div className="markdown-rendered"> <div className="markdown-rendered">
<Alert severity="info"> <Alert severity="info">
<AlertTitle>Want to know more?</AlertTitle> <AlertTitle>Want to know more?</AlertTitle>
🌱 <strong>Follow</strong> or <strong>DM</strong> me on Twitter at <span><a href="https://twitter.com/tuancm">@tuancm</a></span> 🌱 <strong>Follow</strong> or <strong>DM</strong> me on Twitter at <span><a
href="https://twitter.com/tuancm">@tuancm</a></span>
</Alert> </Alert>
<div dangerouslySetInnerHTML={{__html: content}}/> <div dangerouslySetInnerHTML={{__html: content}}/>
<button onClick={handleInternalLinkClick}>Click me </button> <button onClick={handleInternalLinkClick}>Click me</button>
<hr/>
<div>
<BackLinks linkList={backLinks}/>
</div>
</div> </div>
); );
} }

View File

@ -8,11 +8,6 @@ import html from "remark-html";
import frontmatter from "remark-frontmatter"; import frontmatter from "remark-frontmatter";
import externalLinks from "remark-external-links"; import externalLinks from "remark-external-links";
import highlight from "remark-highlight.js"; import highlight from "remark-highlight.js";
import remarkRehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify'
import {createElement, Fragment, useEffect, useState} from 'react'
import rehypeReact from 'rehype-react'
import CustomLink from "../components/CustomLink";
const postsDirectory = path.join(process.cwd(), 'posts') const postsDirectory = path.join(process.cwd(), 'posts')
const isFile = fileName => { const isFile = fileName => {
@ -29,11 +24,9 @@ export const Transformer = {
if (indexOfFirst === -1) { if (indexOfFirst === -1) {
return false return false
} }
var indexOfSecond = content.indexOf("---", (indexOfFirst + 1)) let indexOfSecond = content.indexOf("---", (indexOfFirst + 1));
if (indexOfSecond !== -1) { return indexOfSecond !== -1;
return true
}
return false
}, },
getFrontMatterData: function (filecontent) { getFrontMatterData: function (filecontent) {
if (Transformer.haveFrontMatter(filecontent)) { if (Transformer.haveFrontMatter(filecontent)) {
@ -42,11 +35,12 @@ export const Transformer = {
return {} return {}
}, },
getHtmlContent: function (content, {fileNames}) {
getProcessor : function (content, {fileNames}) {
let htmlContent = [] let htmlContent = []
let internalLinks = [] let internalLinks = []
return unified() const sanitizedContent = Transformer.preprocessThreeDashes(content)
unified()
.use(markdown, {gfm: true}) .use(markdown, {gfm: true})
.use(highlight) .use(highlight)
.use(externalLinks, {target: "_blank", rel: ['noopener']}) .use(externalLinks, {target: "_blank", rel: ['noopener']})
@ -56,7 +50,14 @@ export const Transformer = {
pageResolver: function(pageName){ pageResolver: function(pageName){
const name = [Transformer.parseFileNameFromPath(pageName)] const name = [Transformer.parseFileNameFromPath(pageName)]
//console.log("\n\nwiki internal links", Transformer.parseFileNameFromPath(name[0])); //console.log("\n\nwiki internal links", Transformer.parseFileNameFromPath(name[0]));
internalLinks.push(Transformer.parseFileNameFromPath(name[0]));
const backLink = {
title: name,
link: Transformer.parseFileNameFromPath(name[0]),
shortSummary: name
}
internalLinks.push(backLink);
return name return name
}, },
hrefTemplate: function(permalink){ hrefTemplate: function(permalink){
@ -68,18 +69,7 @@ export const Transformer = {
aliasDivider:"|" aliasDivider:"|"
}) })
.use(remarkRehype) .use(html)
},
getHtmlContent: function (content, {fileNames}) {
let htmlContent = []
let internalLinks = []
const sanitizedContent = Transformer.preprocessThreeDashes(content)
Transformer.getProcessor(content, fileNames)
// .use(rehypeReact, {createElement, Fragment})
.use(rehypeStringify)
.process(sanitizedContent, .process(sanitizedContent,
function (err, file) { function (err, file) {
//console.log("asd", String(file).slice(0,50)) //console.log("asd", String(file).slice(0,50))
@ -89,7 +79,6 @@ export const Transformer = {
) )
htmlContent = htmlContent.join("") htmlContent = htmlContent.join("")
htmlContent = htmlContent.split("---") htmlContent = htmlContent.split("---")
//console.log("ffffff ", htmlContent)
return [htmlContent, internalLinks] return [htmlContent, internalLinks]
}, },
@ -158,10 +147,8 @@ export const Transformer = {
//console.log("----", providedSanitizedFileName, possibleSanitizedFileName) //console.log("----", providedSanitizedFileName, possibleSanitizedFileName)
//console.log("---", possibleSanitizedFileName, providedSanitizedFileName) //console.log("---", possibleSanitizedFileName, providedSanitizedFileName)
if (providedSanitizedFileName === possibleSanitizedFileName) { return providedSanitizedFileName === possibleSanitizedFileName;
return true
}
return false
}) })
console.log("p---", possibleFilePath) console.log("p---", possibleFilePath)
return possibleFilePath[0] return possibleFilePath[0]

View File

@ -3,18 +3,6 @@ import {Node} from "./node"
import {Transformer} from "./transformer"; import {Transformer} from "./transformer";
const dirTree = require("directory-tree"); const dirTree = require("directory-tree");
function pathSelector(filename, allFilePaths){
if (filename.replace(".md", "") === "index"){
return "/index.md"
}
else if (filename.replace(".md", "") === "sidebar"){
return "/sidebar.md"
}
return allFilePaths.filter(f => !(f.endsWith("index.md") && f.endsWith("sidebar.md")))
}
const postsDirectory = path.join(process.cwd(), 'posts') const postsDirectory = path.join(process.cwd(), 'posts')
export function getAllFileNames() { export function getAllFileNames() {
@ -63,7 +51,8 @@ export function getSinglePost(filename) {
return { return {
id:filename, id:filename,
...currentFileFrontMatter, ...currentFileFrontMatter,
data:htmlContent data:htmlContent,
backLinks: backlinks
} }
} }

View File

@ -10,43 +10,46 @@ import {
} 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";
import MDContainer from "../../components/MDContainer"; import MDContent from "../../components/MDContent";
import {Transformer} from "../../lib/transformer";
export default function Home({ note, fileNames,tree, flattenNodes}) { export default function Home({note, backLinks, fileNames, tree, flattenNodes}) {
return ( return (
<Layout> <Layout>
<Head> <Head>
{note.title && <meta name="title" content={note.title} />} {note.title && <meta name="title" content={note.title}/>}
</Head> </Head>
<div className = 'container'> <div className='container'>
<nav className="nav-bar"> <nav className="nav-bar">
<FolderTree tree={tree} flattenNodes={flattenNodes}/> <FolderTree tree={tree} flattenNodes={flattenNodes}/>
</nav> </nav>
<MDContainer post={note.data} fileNames = {fileNames}/> <MDContent content={note.data} fileNames={fileNames} handleOpenNewContent={null} backLinks={backLinks}/>
</div> </div>
</Layout> </Layout>
); );
} }
export async function getStaticPaths() { export async function getStaticPaths() {
const allPostsData = getPostListData(); const allPostsData = getPostListData();
const paths = allPostsData.map(p => ({params: {id:p}})) const paths = allPostsData.map(p => ({params: {id: p}}))
return { return {
paths, paths,
fallback:false fallback: false
}; };
} }
export async function getStaticProps({ params }) {
export function getStaticProps({params}) {
const note = getSinglePost(params.id); const note = getSinglePost(params.id);
const tree = convertObject(getDirectoryData()); const tree = convertObject(getDirectoryData());
const flattenNodes = getFlattenArray(tree) const flattenNodes = getFlattenArray(tree)
const fileNames = getAllFileNames() const fileNames = getAllFileNames()
return { return {
props: { props: {
note, note,
tree: tree, tree: tree,
flattenNodes: flattenNodes, flattenNodes: flattenNodes,
fileNames: fileNames fileNames: fileNames,
backLinks: note.backLinks
}, },
}; };
} }