Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/app/concepts/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { notFound } from "next/navigation";
import { Metadata } from "next";
import Link from "next/link";
import { parseInlineMarkdown } from "@/lib/markdown";
import {
getConceptBySlug,
getAllConceptSlugs,
Expand Down Expand Up @@ -39,12 +40,7 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
}
}

function parseInlineMarkdown(text: string): string {
return text
.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>")
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>')
.replace(/`([^`]+)`/g, "<code>$1</code>");
}
// parseInlineMarkdown imported from @/lib/markdown

function renderConceptBody(content: string) {
const elements: { type: "p" | "h3" | "code" | "ul" | "table"; content: string }[] = [];
Expand Down
10 changes: 3 additions & 7 deletions src/app/functions/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Metadata } from "next";
import Link from "next/link";
import { getFunctionBySlug, getAllFunctionSlugs, buildSearchIndex } from "@/lib/mdx";
import { PQTableData, ExampleStep } from "@/lib/types";
import { parseInlineMarkdown } from "@/lib/markdown";
import FunctionHeader from "@/components/function-page/FunctionHeader";
import SyntaxBlock from "@/components/function-page/SyntaxBlock";
import ParametersTable from "@/components/function-page/ParametersTable";
Expand Down Expand Up @@ -102,12 +103,7 @@ function parseRemarks(content: string): string | null {
return remarksMatch ? remarksMatch[1].trim() : null;
}

function parseInlineMarkdown(text: string): string {
return text
.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>")
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>')
.replace(/`([^`]+)`/g, "<code>$1</code>");
}
// parseInlineMarkdown imported from @/lib/markdown

function renderRemarks(remarks: string) {
const elements: React.ReactElement[] = [];
Expand Down Expand Up @@ -247,7 +243,7 @@ export default async function FunctionPage({ params }: PageProps) {
};

return (
<article>
<article key={slug}>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
Expand Down
8 changes: 2 additions & 6 deletions src/app/patterns/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { notFound } from "next/navigation";
import { Metadata } from "next";
import Link from "next/link";
import { parseInlineMarkdown } from "@/lib/markdown";
import {
getPatternBySlug,
getAllPatternSlugs,
Expand Down Expand Up @@ -38,12 +39,7 @@ export async function generateMetadata({ params }: PageProps): Promise<Metadata>
}
}

function parseInlineMarkdown(text: string): string {
return text
.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>")
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>')
.replace(/`([^`]+)`/g, "<code>$1</code>");
}
// parseInlineMarkdown imported from @/lib/markdown

function renderBody(content: string) {
const elements: { type: "p" | "h3" | "code" | "ul" | "ol"; content: string; lang?: string }[] = [];
Expand Down
5 changes: 3 additions & 2 deletions src/components/function-page/ExampleSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { useState } from "react";
import { PQTableData, ExampleStep } from "@/lib/types";
import { sampleTables } from "@/data/sample-tables";
import { parseInlineMarkdown } from "@/lib/markdown";
import PQTable from "@/components/pq-table/PQTable";
import SyntaxBlock from "./SyntaxBlock";

Expand Down Expand Up @@ -42,7 +43,7 @@ export default function ExampleSection({
<h3>
Example {index + 1}: {title}
</h3>
{description && <p className="example-description">{description}</p>}
{description && <p className="example-description" dangerouslySetInnerHTML={{ __html: parseInlineMarkdown(description) }} />}

<div className="example-code">
<SyntaxBlock code={code} />
Expand Down Expand Up @@ -96,7 +97,7 @@ export default function ExampleSection({
{currentStep && (
<div className="step-output">
{currentStep.description && (
<p className="step-description">{currentStep.description}</p>
<p className="step-description" dangerouslySetInnerHTML={{ __html: parseInlineMarkdown(currentStep.description) }} />
)}
<div className="example-table">
<PQTable data={currentStep.output} />
Expand Down
24 changes: 24 additions & 0 deletions src/lib/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Lightweight inline-markdown parser used in function pages.
*
* Handles: **bold**, [link](url), and `code`.
* M function names inside backticks (e.g. `Table.AddColumn`) are
* automatically linked to their function page.
*/

const M_FUNCTION_PATTERN = /^[A-Z][a-zA-Z]*\.[A-Z0-9][a-zA-Z0-9]*$/;

function codeToHtml(inner: string): string {
if (M_FUNCTION_PATTERN.test(inner)) {
const slug = inner.toLowerCase().replace(/\./g, "-");
return `<a href="/functions/${slug}" class="fn-link"><code>${inner}</code></a>`;
}
return `<code>${inner}</code>`;
}

export function parseInlineMarkdown(text: string): string {
return text
.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>")
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>')
.replace(/`([^`]+)`/g, (_, inner) => codeToHtml(inner));
}
Loading