mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-06-05 10:11:12 +02:00
feat: markdown tables
This commit is contained in:
@@ -3,6 +3,7 @@ import type { Components } from "react-markdown";
|
||||
import { useMemo } from "react";
|
||||
import { useGrimoire } from "@/core/state";
|
||||
import { MediaEmbed } from "@/components/nostr/MediaEmbed";
|
||||
import remarkGfm from "remark-gfm";
|
||||
|
||||
interface MarkdownProps {
|
||||
content: string;
|
||||
@@ -79,15 +80,18 @@ export function Markdown({ content, className = "" }: MarkdownProps) {
|
||||
console.log("[Markdown Link]", { href, children });
|
||||
|
||||
// Check if it's a relative NIP link (e.g., "./01.md" or "01.md" or "30.md")
|
||||
if (href && (href.endsWith(".md") || href.includes(".md#"))) {
|
||||
console.log("[Markdown] Detected .md link:", href);
|
||||
// Must be relative (not start with http:// or https://)
|
||||
const isRelativeLink =
|
||||
href && !href.startsWith("http://") && !href.startsWith("https://");
|
||||
if (isRelativeLink && (href.endsWith(".md") || href.includes(".md#"))) {
|
||||
console.log("[Markdown] Detected relative .md link:", href);
|
||||
|
||||
// Extract NIP number from various formats (1-3 digits)
|
||||
const nipMatch = href.match(/(\d{1,3})\.md/);
|
||||
// Extract NIP number from various formats (numeric 1-3 digits or hex A0-FF)
|
||||
const nipMatch = href.match(/([0-9A-F]{1,3})\.md/i);
|
||||
console.log("[Markdown] Regex match result:", nipMatch);
|
||||
|
||||
if (nipMatch) {
|
||||
const nipNumber = nipMatch[1];
|
||||
const nipNumber = nipMatch[1].toUpperCase();
|
||||
console.log("[Markdown] Creating NIP link for NIP-" + nipNumber);
|
||||
|
||||
return (
|
||||
@@ -221,7 +225,9 @@ export function Markdown({ content, className = "" }: MarkdownProps) {
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<ReactMarkdown components={components}>{content}</ReactMarkdown>
|
||||
<ReactMarkdown components={components} remarkPlugins={[remarkGfm]}>
|
||||
{content}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,23 +12,26 @@ function hasRTLCharacters(text: string): boolean {
|
||||
|
||||
export function Text({ node }: TextNodeProps) {
|
||||
const text = node.value;
|
||||
|
||||
|
||||
// If no newlines, render as inline span
|
||||
if (!text.includes("\n")) {
|
||||
const isRTL = hasRTLCharacters(text);
|
||||
return <span dir={isRTL ? "rtl" : "auto"}>{text || "\u00A0"}</span>;
|
||||
}
|
||||
|
||||
// If has newlines, use divs for proper RTL per line
|
||||
|
||||
// If has newlines, use regular inline spans with <br> tags
|
||||
const lines = text.split("\n");
|
||||
return (
|
||||
<>
|
||||
{lines.map((line, idx) => {
|
||||
const isRTL = hasRTLCharacters(line);
|
||||
return (
|
||||
<div key={idx} dir={isRTL ? "rtl" : "auto"}>
|
||||
{line || "\u00A0"}
|
||||
</div>
|
||||
<>
|
||||
{idx > 0 && <br key={`br-${idx}`} />}
|
||||
<span key={idx} dir={isRTL ? "rtl" : "auto"}>
|
||||
{line || "\u00A0"}
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { EventStoreProvider } from "applesauce-react/providers";
|
||||
import Root from "./root";
|
||||
@@ -10,9 +9,7 @@ import "react-mosaic-component/react-mosaic-component.css";
|
||||
document.documentElement.classList.add("dark");
|
||||
|
||||
createRoot(document.getElementById("root")!).render(
|
||||
<StrictMode>
|
||||
<EventStoreProvider eventStore={eventStore}>
|
||||
<Root />
|
||||
</EventStoreProvider>
|
||||
</StrictMode>,
|
||||
<EventStoreProvider eventStore={eventStore}>
|
||||
<Root />
|
||||
</EventStoreProvider>,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user