adding md viewer
This commit is contained in:
parent
7167ec998f
commit
c877382b2a
@ -15,8 +15,8 @@ export default function AppLayout({ children }: { children: React.ReactNode }) {
|
|||||||
|
|
||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<div className="relative z-0 flex shrink-0 grow justify-center overflow-x-hidden">
|
<div className="relative flex shrink-0 grow justify-center overflow-x-hidden">
|
||||||
<div className="flex-1 overflow-x-hidden sm:px-5">{children}</div>
|
<div className="flex-1 overflow-x-hidden px-5">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
{/* Mobile Banner */}
|
{/* Mobile Banner */}
|
||||||
<MobileBanner />
|
<MobileBanner />
|
||||||
|
@ -1,16 +1,34 @@
|
|||||||
|
import { Button } from "@/components/ui/button";
|
||||||
import HorizontalCarousel from "./_sections/HorizontalCarousel";
|
import HorizontalCarousel from "./_sections/HorizontalCarousel";
|
||||||
|
import { RiArrowRightLine } from "react-icons/ri";
|
||||||
|
import LongFormContentCard from "@/components/LongFormContentCard";
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<div className="relative pt-10">
|
<div className="relative space-y-6 pt-5 sm:pt-7">
|
||||||
<div className="relative -mx-5 space-y-6 overflow-x-hidden">
|
<section className="relative -mx-5 space-y-4 overflow-x-hidden sm:space-y-6">
|
||||||
<div className="flex items-center justify-between px-5">
|
<div className="flex items-center justify-between px-5 max-sm:pr-3">
|
||||||
<h2 className="font-condensed text-3xl font-bold">
|
<h2 className="font-condensed text-2xl font-bold sm:text-3xl">
|
||||||
Explore Creators
|
Explore Creators
|
||||||
</h2>
|
</h2>
|
||||||
|
<Button variant={"ghost"}>
|
||||||
|
View all <RiArrowRightLine className="ml-1 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<HorizontalCarousel />
|
<HorizontalCarousel />
|
||||||
|
</section>
|
||||||
|
<section className="relative space-y-3 overflow-x-hidden sm:space-y-3">
|
||||||
|
<div className="flex items-center justify-between max-sm:pr-3">
|
||||||
|
<h2 className="font-condensed text-xl font-semibold sm:text-xl">
|
||||||
|
Long form content
|
||||||
|
</h2>
|
||||||
|
<Button variant={"ghost"}>
|
||||||
|
View all <RiArrowRightLine className="ml-1 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="relative">
|
||||||
|
<LongFormContentCard />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
9
app/(app)/article/[eventId]/layout.tsx
Normal file
9
app/(app)/article/[eventId]/layout.tsx
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
|
export default function ModalLayout({ children }: { children: ReactElement }) {
|
||||||
|
return (
|
||||||
|
<div className="z-overlay fixed inset-y-[10px] left-[10px] right-[10px] rounded-lg border bg-background px-4 sm:left-[calc(10px_+_var(--sidebar-closed-width))] xl:left-[calc(10px_+_var(--sidebar-open-width))]">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
63
app/(app)/article/[eventId]/page.tsx
Normal file
63
app/(app)/article/[eventId]/page.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
"use client";
|
||||||
|
import { useMemo } from "react";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { RiCloseFill } from "react-icons/ri";
|
||||||
|
import { Avatar, AvatarImage, AvatarFallback } from "@radix-ui/react-avatar";
|
||||||
|
import { useRouter } from "next/navigation";
|
||||||
|
const Viewer = dynamic(() => import("@/components/LongForm/Viewer"), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default function ArticlePage({
|
||||||
|
params: { eventId },
|
||||||
|
}: {
|
||||||
|
params: {
|
||||||
|
eventId: string;
|
||||||
|
};
|
||||||
|
}) {
|
||||||
|
const router = useRouter();
|
||||||
|
const markdown = `This is a test
|
||||||
|
### test text
|
||||||
|
|
||||||
|
- First
|
||||||
|
- Second
|
||||||
|
1 nest`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<div className="absolute inset-x-0 top-0 flex items-center justify-between border-b pb-4 pt-4">
|
||||||
|
<div className="center gap-x-3">
|
||||||
|
<Avatar className="center h-8 w-8 overflow-hidden rounded-sm bg-muted">
|
||||||
|
<AvatarImage
|
||||||
|
src={
|
||||||
|
"https://images.unsplash.com/photo-1566492031773-4f4e44671857?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=4&w=256&h=256&q=60"
|
||||||
|
}
|
||||||
|
alt="user"
|
||||||
|
/>
|
||||||
|
<AvatarFallback className="text-xs">SC</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<span className="text-xs uppercase text-muted-foreground">
|
||||||
|
Derek Seivers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
if (sessionStorage.getItem("RichHistory")) {
|
||||||
|
void router.back();
|
||||||
|
} else {
|
||||||
|
void router.push("/");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
size="icon"
|
||||||
|
variant={"outline"}
|
||||||
|
className=""
|
||||||
|
>
|
||||||
|
<RiCloseFill className="h-5 w-5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="h-[70px] w-full"></div>
|
||||||
|
<Viewer initialMarkdown={markdown} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
65
components/LongForm/Editor.tsx
Normal file
65
components/LongForm/Editor.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
"use client";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { BlockNoteEditor, PartialBlock, Block } from "@blocknote/core";
|
||||||
|
import { BlockNoteView, useBlockNote } from "@blocknote/react";
|
||||||
|
import Spinner from "../spinner";
|
||||||
|
import "@blocknote/core/style.css";
|
||||||
|
|
||||||
|
interface EditorProps {
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
initialMarkdown?: string;
|
||||||
|
editable?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Editor = ({ onChange, initialMarkdown, editable }: EditorProps) => {
|
||||||
|
const { resolvedTheme } = useTheme();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [initialContent, setInitialContent] = useState<Block[]>();
|
||||||
|
|
||||||
|
const editor: BlockNoteEditor = useBlockNote({
|
||||||
|
editable,
|
||||||
|
initialContent: initialContent,
|
||||||
|
onEditorContentChange: (editor) => {
|
||||||
|
onChange(JSON.stringify(editor.topLevelBlocks, null, 2));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (editor) {
|
||||||
|
if (!initialContent && initialMarkdown) {
|
||||||
|
// Whenever the current Markdown content changes, converts it to an array
|
||||||
|
// of Block objects and replaces the editor's content with them.
|
||||||
|
const getBlocks = async () => {
|
||||||
|
const blocks: Block[] =
|
||||||
|
await editor.markdownToBlocks(initialMarkdown);
|
||||||
|
setInitialContent(blocks);
|
||||||
|
editor.replaceBlocks(editor.topLevelBlocks, blocks);
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
void getBlocks();
|
||||||
|
} else if (loading) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [editor]);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BlockNoteView
|
||||||
|
editor={editor}
|
||||||
|
theme={resolvedTheme === "dark" ? "dark" : "light"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Editor;
|
63
components/LongForm/Viewer.tsx
Normal file
63
components/LongForm/Viewer.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
"use client";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
import { BlockNoteEditor, PartialBlock, Block } from "@blocknote/core";
|
||||||
|
import { BlockNoteView, useBlockNote } from "@blocknote/react";
|
||||||
|
import Spinner from "../spinner";
|
||||||
|
import "@blocknote/core/style.css";
|
||||||
|
|
||||||
|
interface EditorProps {
|
||||||
|
initialMarkdown?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Viewer = ({ initialMarkdown }: EditorProps) => {
|
||||||
|
const { resolvedTheme } = useTheme();
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const [initialContent, setInitialContent] = useState<Block[]>();
|
||||||
|
|
||||||
|
const editor: BlockNoteEditor = useBlockNote({
|
||||||
|
editable: false,
|
||||||
|
initialContent: initialContent,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("ERFE", editor);
|
||||||
|
if (editor) {
|
||||||
|
if (!initialContent && initialMarkdown) {
|
||||||
|
console.log("initial md", initialMarkdown);
|
||||||
|
// Whenever the current Markdown content changes, converts it to an array
|
||||||
|
// of Block objects and replaces the editor's content with them.
|
||||||
|
const getBlocks = async () => {
|
||||||
|
const blocks: Block[] =
|
||||||
|
await editor.markdownToBlocks(initialMarkdown);
|
||||||
|
setInitialContent(blocks);
|
||||||
|
console.log("Blocks", blocks);
|
||||||
|
// editor.replaceBlocks(editor.topLevelBlocks, blocks);
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
void getBlocks();
|
||||||
|
} else if (loading) {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [editor]);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<BlockNoteView
|
||||||
|
editor={editor}
|
||||||
|
theme={resolvedTheme === "dark" ? "dark" : "light"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Viewer;
|
83
components/LongFormContentCard/index.tsx
Normal file
83
components/LongFormContentCard/index.tsx
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
"use client";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { RiMoreFill } from "react-icons/ri";
|
||||||
|
import { HiOutlineLightningBolt } from "react-icons/hi";
|
||||||
|
import {
|
||||||
|
HiOutlineHandThumbUp,
|
||||||
|
HiOutlineChatBubbleLeftEllipsis,
|
||||||
|
HiOutlineEllipsisHorizontal,
|
||||||
|
} from "react-icons/hi2";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
} from "@/components/ui/card";
|
||||||
|
import { Avatar, AvatarImage, AvatarFallback } from "@radix-ui/react-avatar";
|
||||||
|
import { formatDate } from "@/lib/utils/dates";
|
||||||
|
import { Button } from "../ui/button";
|
||||||
|
|
||||||
|
type CreatorCardProps = {
|
||||||
|
displayName: string;
|
||||||
|
about: string;
|
||||||
|
picture: string;
|
||||||
|
banner: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function LongFormContentCard() {
|
||||||
|
return (
|
||||||
|
<Card className="relative max-w-[400px] overflow-hidden">
|
||||||
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 p-4 pb-4">
|
||||||
|
<div className="center gap-x-3">
|
||||||
|
<Avatar className="center h-8 w-8 overflow-hidden rounded-sm bg-muted">
|
||||||
|
<AvatarImage
|
||||||
|
src={
|
||||||
|
"https://images.unsplash.com/photo-1566492031773-4f4e44671857?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=4&w=256&h=256&q=60"
|
||||||
|
}
|
||||||
|
alt="user"
|
||||||
|
/>
|
||||||
|
<AvatarFallback className="text-xs">SC</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<span className="text-xs uppercase text-muted-foreground">
|
||||||
|
Derek Seivers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="-mr-1 flex items-center gap-x-1.5 text-xs text-muted-foreground">
|
||||||
|
{formatDate(new Date("10-5-23"), "MMM Do")}
|
||||||
|
<Button size={"sm"} variant={"ghost"} className="center h-6 w-6 p-0">
|
||||||
|
<RiMoreFill className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="px-4 pb-3">
|
||||||
|
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold">
|
||||||
|
The start of the Nostr revolution
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription className="line-clamp-4 text-sm">
|
||||||
|
This is the summary of this artilce. Let's hope that it is a good
|
||||||
|
article and that it will end up being worth reading. I don't want to
|
||||||
|
waste my time on some random other stuff.
|
||||||
|
</CardDescription>
|
||||||
|
<div className="mt-3 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<Button size={"sm"} variant={"ghost"} className="gap-x-1.5 px-2">
|
||||||
|
<HiOutlineHandThumbUp className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
<Button size={"sm"} variant={"ghost"} className="gap-x-1.5 px-2">
|
||||||
|
<HiOutlineChatBubbleLeftEllipsis className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<Button size={"sm"} className="gap-x-1.5">
|
||||||
|
<HiOutlineLightningBolt className="h-4 w-4" />
|
||||||
|
<span>zap</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
26
components/spinner.tsx
Normal file
26
components/spinner.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const Spinner = () => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
className="opacity-25"
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
r="10"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="4"
|
||||||
|
></circle>
|
||||||
|
<path
|
||||||
|
className="opacity-75"
|
||||||
|
fill="currentColor"
|
||||||
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Spinner;
|
@ -1,6 +1,9 @@
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import relative from "dayjs/plugin/relativeTime";
|
import relative from "dayjs/plugin/relativeTime";
|
||||||
import updateLocale from "dayjs/plugin/updateLocale";
|
import updateLocale from "dayjs/plugin/updateLocale";
|
||||||
|
import advancedFormat from "dayjs/plugin/advancedFormat";
|
||||||
|
import timezone from "dayjs/plugin/timezone";
|
||||||
|
|
||||||
export function relativeTimeUnix(timestamp: number) {
|
export function relativeTimeUnix(timestamp: number) {
|
||||||
const config = {
|
const config = {
|
||||||
thresholds: [
|
thresholds: [
|
||||||
@ -71,3 +74,8 @@ export function relativeTimeUnix(timestamp: number) {
|
|||||||
dayjs.extend(relative, config);
|
dayjs.extend(relative, config);
|
||||||
return dayjs(timestamp).fromNow();
|
return dayjs(timestamp).fromNow();
|
||||||
}
|
}
|
||||||
|
export function formatDate(timestamp: Date, format?: string) {
|
||||||
|
dayjs.extend(advancedFormat);
|
||||||
|
dayjs.extend(timezone);
|
||||||
|
return dayjs(timestamp).format(format ?? "MMMM Do, YYYY");
|
||||||
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@blocknote/core": "^0.9.5",
|
||||||
|
"@blocknote/react": "^0.9.5",
|
||||||
"@hookform/resolvers": "^3.3.2",
|
"@hookform/resolvers": "^3.3.2",
|
||||||
"@noble/hashes": "^1.3.2",
|
"@noble/hashes": "^1.3.2",
|
||||||
"@nostr-dev-kit/ndk": "^2.0.0",
|
"@nostr-dev-kit/ndk": "^2.0.0",
|
||||||
@ -29,6 +31,7 @@
|
|||||||
"focus-trap-react": "^10.2.3",
|
"focus-trap-react": "^10.2.3",
|
||||||
"framer-motion": "^10.16.4",
|
"framer-motion": "^10.16.4",
|
||||||
"next": "13.5.4",
|
"next": "13.5.4",
|
||||||
|
"next-themes": "^0.2.1",
|
||||||
"node-html-parser": "^6.1.10",
|
"node-html-parser": "^6.1.10",
|
||||||
"nostr-tools": "^1.16.0",
|
"nostr-tools": "^1.16.0",
|
||||||
"ramda": "^0.29.1",
|
"ramda": "^0.29.1",
|
||||||
@ -45,6 +48,7 @@
|
|||||||
"zustand": "^4.4.3"
|
"zustand": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tailwindcss/typography": "^0.5.10",
|
||||||
"@types/crypto-js": "^4.1.2",
|
"@types/crypto-js": "^4.1.2",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/ramda": "^0.29.6",
|
"@types/ramda": "^0.29.6",
|
||||||
|
@ -84,16 +84,20 @@ module.exports = {
|
|||||||
80: 80,
|
80: 80,
|
||||||
90: 90,
|
90: 90,
|
||||||
99: 99,
|
99: 99,
|
||||||
mobileTabs: 980,
|
mobileTabs: 900,
|
||||||
"header-": 989,
|
"header-": 919,
|
||||||
header: 990,
|
header: 920,
|
||||||
"header+": 991,
|
"header+": 921,
|
||||||
headerDialog: 991,
|
headerDialog: 922,
|
||||||
"modal-": 995,
|
"overlay-": 929,
|
||||||
modal: 996,
|
overlay: 930,
|
||||||
"modal+": 997,
|
"overlay+": 931,
|
||||||
"top-": 998,
|
"modal-": 939,
|
||||||
top: 999,
|
modal: 940,
|
||||||
|
"modal+": 941,
|
||||||
|
"top-": 949,
|
||||||
|
top: 950,
|
||||||
|
"top+": 951,
|
||||||
},
|
},
|
||||||
flex: {
|
flex: {
|
||||||
2: 2,
|
2: 2,
|
||||||
@ -106,5 +110,6 @@ module.exports = {
|
|||||||
require("tailwindcss-animate"),
|
require("tailwindcss-animate"),
|
||||||
require("@tailwindcss/container-queries"),
|
require("@tailwindcss/container-queries"),
|
||||||
require("tailwind-scrollbar"),
|
require("tailwind-scrollbar"),
|
||||||
|
require("@tailwindcss/typography"),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
221
test.md
Normal file
221
test.md
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
# h1 Heading 8-)
|
||||||
|
|
||||||
|
## h2 Heading
|
||||||
|
|
||||||
|
### h3 Heading
|
||||||
|
|
||||||
|
#### h4 Heading
|
||||||
|
|
||||||
|
##### h5 Heading
|
||||||
|
|
||||||
|
###### h6 Heading
|
||||||
|
|
||||||
|
## Horizontal Rules
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typographic replacements
|
||||||
|
|
||||||
|
Enable typographer option to see result.
|
||||||
|
|
||||||
|
(c) (C) (r) (R) (tm) (TM) (p) (P) +-
|
||||||
|
|
||||||
|
test.. test... test..... test?..... test!....
|
||||||
|
|
||||||
|
!!!!!! ???? ,, -- ---
|
||||||
|
|
||||||
|
"Smartypants, double quotes" and 'single quotes'
|
||||||
|
|
||||||
|
## Emphasis
|
||||||
|
|
||||||
|
**This is bold text**
|
||||||
|
|
||||||
|
**This is bold text**
|
||||||
|
|
||||||
|
_This is italic text_
|
||||||
|
|
||||||
|
_This is italic text_
|
||||||
|
|
||||||
|
~~Strikethrough~~
|
||||||
|
|
||||||
|
## Blockquotes
|
||||||
|
|
||||||
|
> Blockquotes can also be nested...
|
||||||
|
>
|
||||||
|
> > ...by using additional greater-than signs right next to each other...
|
||||||
|
> >
|
||||||
|
> > > ...or with spaces between arrows.
|
||||||
|
|
||||||
|
## Lists
|
||||||
|
|
||||||
|
Unordered
|
||||||
|
|
||||||
|
- Create a list by starting a line with `+`, `-`, or `*`
|
||||||
|
- Sub-lists are made by indenting 2 spaces:
|
||||||
|
- Marker character change forces new list start:
|
||||||
|
- Ac tristique libero volutpat at
|
||||||
|
* Facilisis in pretium nisl aliquet
|
||||||
|
- Nulla volutpat aliquam velit
|
||||||
|
- Very easy!
|
||||||
|
|
||||||
|
Ordered
|
||||||
|
|
||||||
|
1. Lorem ipsum dolor sit amet
|
||||||
|
2. Consectetur adipiscing elit
|
||||||
|
3. Integer molestie lorem at massa
|
||||||
|
|
||||||
|
4. You can use sequential numbers...
|
||||||
|
5. ...or keep all the numbers as `1.`
|
||||||
|
|
||||||
|
Start numbering with offset:
|
||||||
|
|
||||||
|
57. foo
|
||||||
|
1. bar
|
||||||
|
|
||||||
|
## Code
|
||||||
|
|
||||||
|
Inline `code`
|
||||||
|
|
||||||
|
Indented code
|
||||||
|
|
||||||
|
// Some comments
|
||||||
|
line 1 of code
|
||||||
|
line 2 of code
|
||||||
|
line 3 of code
|
||||||
|
|
||||||
|
Block code "fences"
|
||||||
|
|
||||||
|
```
|
||||||
|
Sample text here...
|
||||||
|
```
|
||||||
|
|
||||||
|
Syntax highlighting
|
||||||
|
|
||||||
|
```js
|
||||||
|
var foo = function (bar) {
|
||||||
|
return bar++;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(foo(5));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tables
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| ------ | ------------------------------------------------------------------------- |
|
||||||
|
| data | path to data files to supply the data that will be passed into templates. |
|
||||||
|
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||||
|
| ext | extension to be used for dest files. |
|
||||||
|
|
||||||
|
Right aligned columns
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| -----: | ------------------------------------------------------------------------: |
|
||||||
|
| data | path to data files to supply the data that will be passed into templates. |
|
||||||
|
| engine | engine to be used for processing templates. Handlebars is the default. |
|
||||||
|
| ext | extension to be used for dest files. |
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
[link text](http://dev.nodeca.com)
|
||||||
|
|
||||||
|
[link with title](http://nodeca.github.io/pica/demo/ "title text!")
|
||||||
|
|
||||||
|
Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
|
||||||
|
|
||||||
|
## Images
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
Like links, Images also have a footnote style syntax
|
||||||
|
|
||||||
|
![Alt text][id]
|
||||||
|
|
||||||
|
With a reference later in the document defining the URL location:
|
||||||
|
|
||||||
|
[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
The killer feature of `markdown-it` is very effective support of
|
||||||
|
[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
|
||||||
|
|
||||||
|
### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
|
||||||
|
|
||||||
|
> Classic markup: :wink: :crush: :cry: :tear: :laughing: :yum:
|
||||||
|
>
|
||||||
|
> Shortcuts (emoticons): :-) :-( 8-) ;)
|
||||||
|
|
||||||
|
see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
|
||||||
|
|
||||||
|
### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
|
||||||
|
|
||||||
|
- 19^th^
|
||||||
|
- H~2~O
|
||||||
|
|
||||||
|
### [\<ins>](https://github.com/markdown-it/markdown-it-ins)
|
||||||
|
|
||||||
|
++Inserted text++
|
||||||
|
|
||||||
|
### [\<mark>](https://github.com/markdown-it/markdown-it-mark)
|
||||||
|
|
||||||
|
==Marked text==
|
||||||
|
|
||||||
|
### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
|
||||||
|
|
||||||
|
Footnote 1 link[^first].
|
||||||
|
|
||||||
|
Footnote 2 link[^second].
|
||||||
|
|
||||||
|
Inline footnote^[Text of inline footnote] definition.
|
||||||
|
|
||||||
|
Duplicated footnote reference[^second].
|
||||||
|
|
||||||
|
[^first]: Footnote **can have markup**
|
||||||
|
|
||||||
|
and multiple paragraphs.
|
||||||
|
|
||||||
|
[^second]: Footnote text.
|
||||||
|
|
||||||
|
### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
|
||||||
|
|
||||||
|
Term 1
|
||||||
|
|
||||||
|
: Definition 1
|
||||||
|
with lazy continuation.
|
||||||
|
|
||||||
|
Term 2 with _inline markup_
|
||||||
|
|
||||||
|
: Definition 2
|
||||||
|
|
||||||
|
{ some code, part of Definition 2 }
|
||||||
|
|
||||||
|
Third paragraph of definition 2.
|
||||||
|
|
||||||
|
_Compact style:_
|
||||||
|
|
||||||
|
Term 1
|
||||||
|
~ Definition 1
|
||||||
|
|
||||||
|
Term 2
|
||||||
|
~ Definition 2a
|
||||||
|
~ Definition 2b
|
||||||
|
|
||||||
|
### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
|
||||||
|
|
||||||
|
This is HTML abbreviation example.
|
||||||
|
|
||||||
|
It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
|
||||||
|
|
||||||
|
\*[HTML]: Hyper Text Markup Language
|
||||||
|
|
||||||
|
### [Custom containers](https://github.com/markdown-it/markdown-it-container)
|
||||||
|
|
||||||
|
::: warning
|
||||||
|
_here be dragons_
|
||||||
|
:::
|
Loading…
x
Reference in New Issue
Block a user