Skip to content

Commit

Permalink
fix markdown whitespace
Browse files Browse the repository at this point in the history
  • Loading branch information
kualta committed Sep 22, 2024
1 parent c1700fa commit a26a238
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 46 deletions.
211 changes: 192 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"react-redux": "^8.0.5",
"react-syntax-highlighter": "^15.5.0",
"redux": "^4.2.1",
"remark-breaks": "^4.0.0",
"remark-gfm": "^3.0.1",
"screenfull": "^6.0.2",
"simple-swizzle": "^0.2.2",
Expand Down
34 changes: 7 additions & 27 deletions src/components/Markdown.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import ReactMarkdown from "react-markdown";
import type { Components } from "react-markdown/lib/ast-to-react";
import remarkBreaks from "remark-breaks";
import remarkGfm from "remark-gfm";
import { getBaseUrl } from "~/utils/getBaseUrl";
import { parseContent } from "~/utils/parseContent";
import { CommunityHandle } from "./communities/CommunityHandle";
import { UserLazyHandle } from "./user/UserLazyHandle";

const BASE_URL = getBaseUrl();

const Markdown: React.FC<{ content: string }> = ({ content }) => {
const processedText = replaceHandles(parseLinks(content));
const processedText = parseContent(content).replaceHandles().parseLinks().toString();
return (
<ReactMarkdown
className="prose dark:prose-invert prose-p:m-0 prose-p:inline
prose-ul:m-0 prose-h2:m-0 prose-h1:m-0 prose-li:m-0 prose-li:whitespace-normal
className="prose dark:prose-invert prose-p:m-0 prose-p:inline
prose-ul:m-0 prose-h2:m-0 prose-h1:m-0 prose-li:m-0 prose-li:whitespace-normal prose-p:whitespace-normal
prose-ul:leading-4 prose-ol:leading-4 prose-ol:m-0"
remarkPlugins={[remarkGfm]}
remarkPlugins={[remarkGfm, remarkBreaks]}
components={{
h1: "h2",
a: CustomLink,
Expand All @@ -25,27 +26,6 @@ const Markdown: React.FC<{ content: string }> = ({ content }) => {
);
};

const replaceHandles = (content: string): string => {
if (!content) return content;
const userHandleRegex = /(?<!\/)@[\w^\/]+(?!\/)/g;
const communityHandleRegex = /(?<!\S)\/\w+(?!\S)/g;
return content
.replace(userHandleRegex, (match) => {
const parts = match.slice(1).split("/");
const handle = parts.length > 1 ? parts[1] : parts[0];
return `${BASE_URL}u/${handle}`;
})
.replace(communityHandleRegex, (match) => `${BASE_URL}c${match}`);
};

const parseLinks = (content: string): string => {
const linkRegex = /(https?:\/\/\S+)/gi;
return content.replace(linkRegex, (match) => {
const linkWithoutProtocol = match.replace(/^https?:\/\//, '');
return `[${linkWithoutProtocol}](${match})`;
});
};

const CustomLink: Components["a"] = ({ node, ...props }) => {
const { href, children } = props;
if (href?.startsWith(BASE_URL)) {
Expand All @@ -59,4 +39,4 @@ const CustomLink: Components["a"] = ({ node, ...props }) => {
return <a {...props}>{children}</a>;
};

export default Markdown;
export default Markdown;
41 changes: 41 additions & 0 deletions src/utils/parseContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { getBaseUrl } from "./getBaseUrl";

class ContentParser {
private content: string;

constructor(content: string) {
this.content = content;
}

replaceHandles(): ContentParser {
if (!this.content) return this;
const userHandleRegex = /(?<!\/)@[\w^\/]+(?!\/)/g;
const communityHandleRegex = /(?<!\S)\/\w+(?!\S)/g;
const BASE_URL = getBaseUrl();
this.content = this.content
.replace(userHandleRegex, (match) => {
const parts = match.slice(1).split("/");
const handle = parts.length > 1 ? parts[1] : parts[0];
return `${BASE_URL}u/${handle}`;
})
.replace(communityHandleRegex, (match) => `${BASE_URL}c${match}`);
return this;
}

parseLinks(): ContentParser {
const linkRegex = /(https?:\/\/\S+)/gi;
this.content = this.content.replace(linkRegex, (match) => {
const linkWithoutProtocol = match.replace(/^https?:\/\//, "");
return `[${linkWithoutProtocol}](${match})`;
});
return this;
}

toString(): string {
return this.content;
}
}

export function parseContent(content: string): ContentParser {
return new ContentParser(content);
}

0 comments on commit a26a238

Please sign in to comment.