'多语言'
This commit is contained in:
43
app/lib/ebook.ts
Normal file
43
app/lib/ebook.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { marked } from "marked";
|
||||
|
||||
export interface EbookChunk {
|
||||
html: string;
|
||||
estimatedHeight: number;
|
||||
}
|
||||
|
||||
export interface EbookData {
|
||||
chunks: EbookChunk[];
|
||||
headers: string[];
|
||||
}
|
||||
|
||||
export function parseEbookMarkdown(source: string): EbookData {
|
||||
const html = marked.parse(source, { breaks: true, gfm: true }) as string;
|
||||
const lazyHtml = html.replace(/<img /g, '<img loading="lazy" decoding="async" ');
|
||||
|
||||
let rawChunks = lazyHtml.split(/(?=<h1[\s>])/i).filter((c) => c.trim());
|
||||
if (rawChunks.length <= 1) {
|
||||
rawChunks = lazyHtml.split(/(?=<h2[\s>])/i).filter((c) => c.trim());
|
||||
}
|
||||
|
||||
const headers: string[] = [];
|
||||
const headerRegex = /<h1[^>]*>(.*?)<\/h1>/gi;
|
||||
let m;
|
||||
while ((m = headerRegex.exec(lazyHtml)) !== null) {
|
||||
headers.push(m[1].replace(/<[^>]+>/g, ""));
|
||||
}
|
||||
if (headers.length === 0) {
|
||||
const h2Regex = /<h2[^>]*>(.*?)<\/h2>/gi;
|
||||
while ((m = h2Regex.exec(lazyHtml)) !== null) {
|
||||
headers.push(m[1].replace(/<[^>]+>/g, ""));
|
||||
}
|
||||
}
|
||||
|
||||
const chunks: EbookChunk[] = rawChunks.map((chunkHtml) => {
|
||||
const imgCount = (chunkHtml.match(/<img /g) || []).length;
|
||||
const textLen = chunkHtml.replace(/<[^>]+>/g, "").length;
|
||||
const estimatedHeight = Math.max(300, Math.round(textLen * 0.6 + imgCount * 350));
|
||||
return { html: chunkHtml, estimatedHeight };
|
||||
});
|
||||
|
||||
return { chunks, headers };
|
||||
}
|
||||
22
app/lib/locale-link.tsx
Normal file
22
app/lib/locale-link.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
"use client";
|
||||
|
||||
import NextLink from "next/link";
|
||||
import { usePathname as useNextPathname } from "next/navigation";
|
||||
import { useLocale } from "../context/LocaleContext";
|
||||
|
||||
type LocaleLinkProps = React.ComponentProps<typeof NextLink>;
|
||||
|
||||
export function LocaleLink({ href, ...props }: LocaleLinkProps) {
|
||||
const locale = useLocale();
|
||||
const hrefStr = typeof href === "string" ? href : href.pathname ?? "/";
|
||||
const localeHref = hrefStr.startsWith("/")
|
||||
? `/${locale}${hrefStr === "/" ? "" : hrefStr}`
|
||||
: hrefStr;
|
||||
return <NextLink href={localeHref} {...props} />;
|
||||
}
|
||||
|
||||
export function usePathname() {
|
||||
const path = useNextPathname();
|
||||
const match = path?.match(/^\/(zh|en)(\/.*)?$/);
|
||||
return match ? (match[2] ?? "/") : path ?? "/";
|
||||
}
|
||||
Reference in New Issue
Block a user