Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Escape symbols to support MDX 2/3 changes. #121

Merged
merged 3 commits into from
Nov 4, 2023
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
253 changes: 253 additions & 0 deletions fixtures/polyrepo/src/boolean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
// https://github.com/milesj/docusaurus-plugin-typedoc-api/issues/120

/**
* Module interface for values that have equivalence relation
*/
export interface Equal<T> {
/**
* Alias to '=='
*
* @example
* ```ts
* type T = // ...
* const TEqual: Equal<T>;
* TEqual.equals(value, value); // true
* TEqual.equals(value, otherValue); // false
* ```
* @category Comparator
*/
equals(this: void, left: T, right: T): boolean;
/**
* "Not equal to" operator
*
* @example
* ```ts
* const TEqual: Equal<T>;
* TEqual['!='](value, otherValue); // true
* TEqual['!='](value, value); // false
* ```
* @category Comparator
*/
'!='(this: void, left: T, right: T): boolean;
/**
* "Equal to" operator
*
* @example
* ```ts
* type T = // ...
* const TEqual: Equal<T>;
* TEqual['=='](value, value); // true
* TEqual['=='](value, otherValue); // false
* ```
* @category Comparator
*/
'=='(this: void, left: T, right: T): boolean;
}

/**
* Equal module constructor
*
* @example
* ```ts
* type T;
* const TEqual = Equal<T>({
* '==': (left, right) => { /* ... *\/ },
* });
* const value: T;
*
* TEqual['=='](value, value); // true;
* ```
* @category Functor
*/
export function Equal<T>(properties: { equals: (left: T, right: T) => boolean }): Equal<T> {
const equals = (left: T, right: T) => properties.equals(left, right);
const notEquals = (left: T, right: T) => !properties.equals(left, right);
return {
equals: properties.equals,
'==': equals,
'!=': notEquals,
};
}

/**
* Module interface for values that have total order
*/
export interface Comparable<T> extends Equal<T> {
/**
* Return a number that represents comparison
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const sorted = [3, 1, 1].sort(TCompare.compare);
* ```
* @category Comparator
*/
compare(this: void, left: T, right: T): number;
/**
* "Less than or equal to" operator
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const smallerT: T;
* const greaterT: T;
* TCompare['<='](smallerT, smallerT); // true
* TCompare['<='](smallerT, greaterT); // true
* TCompare['<='](greaterT, smallerT); // false
* ```
* @category Comparator
*/
'<='(this: void, left: T, right: T): boolean;
/**
* "Less than" operator
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const smallerT: T;
* const greaterT: T;
* TCompare['<'](smallerT, smallerT); // false
* TCompare['<'](smallerT, greaterT); // true
* TCompare['<'](greaterT, smallerT); // false
* ```
* @category Comparator
*/
'<'(this: void, left: T, right: T): boolean;
/**
* "Greater than or equal to" operator
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const smallerT: T;
* const greaterT: T;
* TCompare['>='](smallerT, smallerT); // true
* TCompare['>='](smallerT, greaterT); // false
* TCompare['>='](greaterT, smallerT); // true
* ```
* @category Comparator
*/
'>='(this: void, left: T, right: T): boolean;
/**
* "Greater than" operator
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const smallerT: T;
* const greaterT: T;
* TCompare['>'](smallerT, smallerT); // false
* TCompare['>'](smallerT, greaterT); // false
* TCompare['>'](greaterT, smallerT); // true
* ```
* @category Comparator
*/
'>'(this: void, left: T, right: T): boolean;
/**
* "minimum" operator
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const smallerT: T;
* const greaterT: T;
* TCompare.min(smallerT, greaterT); // smallerT
* ```
* @category Comparator
*/
min(this: void, left: T, right: T): T;
/**
* "maximum" operator
*
* @example
* ```ts
* type T;
* const TCompare: Comparable<T>;
* const smallerT: T;
* const greaterT: T;
* TCompare.max(smallerT, greaterT); // greaterT
* ```
* @category Comparator
*/
max(this: void, left: T, right: T): T;
}

/**
* Construct Comparable instance
*
* @example
* ```ts
* const NumberComparable = Comparable({
* compare: (left, right) => left - right,
* });
* NumberComparable['=='](0, 0); // true
* NumberComparable['<'](0, 1); // true
* NumberComparable['>'](0, 1); // false
* ```
* @category Functor
* @param properties
* @param properties.compare - the comparison function
*/
export function Comparable<T>(properties: {
compare: (left: T, right: T) => number;
}): Comparable<T> {
const { compare } = properties;
const equals = (left: T, right: T) => compare(left, right) === 0;
return {
compare,
equals,
'==': equals,
'!=': (left: T, right: T) => compare(left, right) !== 0,
'<': (left: T, right: T) => compare(left, right) < 0,
'<=': (left: T, right: T) => compare(left, right) <= 0,
'>': (left: T, right: T) => compare(left, right) > 0,
'>=': (left: T, right: T) => compare(left, right) >= 0,
min: (left: T, right: T) => (compare(left, right) <= 0 ? left : right),
max: (left: T, right: T) => (compare(left, right) > 0 ? left : right),
};
}

const BooleanComparable = Comparable<boolean>({
compare(left, right) {
return left === right ? 0 : left < right ? -1 : 1;
},
});

/**
* A collection of functions to manipulate `boolean`
*
* @example
* ```typescript
* import { Boolean } from '@w5s/core';
*
* if (Boolean.hasInstance(unknownValue)) {
* // typeof unknownValue === 'boolean'
* }
* ```
* @namespace
*/
export const Boolean = {
...BooleanComparable,

/**
* Return true if `anyValue` is a `boolean`
*
* @example
* ```typescript
* Boolean.hasInstance(false) // true
* Boolean.hasInstance(null)) // false
* ```
* @category Guard
* @param anyValue - a tested value
*/
hasInstance(anyValue: unknown): anyValue is boolean {
return typeof anyValue === 'boolean';
},
};
2 changes: 2 additions & 0 deletions fixtures/polyrepo/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export type Type = 'standard';

export function foo() {}

export * from './boolean';
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"devDependencies": {
"@moonrepo/dev": "^2.0.1",
"@types/marked": "^6.0.0",
"@types/react": "^18.2.33",
"eslint": "^8.52.0",
"@types/react": "^18.2.34",
"eslint": "^8.53.0",
"eslint-config-moon": "^2.0.11",
"lerna": "^7.4.2",
"packemon": "^3.2.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@docusaurus/types": "^3.0.0",
"@docusaurus/utils": "^3.0.0",
"@vscode/codicons": "^0.0.35",
"marked": "^9.1.4",
"marked": "^9.1.5",
"marked-smartypants": "^1.1.3",
"typedoc": "^0.25.3"
},
Expand Down
14 changes: 8 additions & 6 deletions packages/plugin/src/components/ApiItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Props as DocItemProps } from '@theme/DocItem';
import { useReflection } from '../hooks/useReflection';
import { useReflectionMap } from '../hooks/useReflectionMap';
import type { TOCItem, TSDDeclarationReflection, TSDDeclarationReflectionMap } from '../types';
import { escapeMdx } from '../utils/helpers';
import { getKindIconHtml } from '../utils/icons';
import ApiItemLayout from './ApiItemLayout';
import { displayPartsToMarkdown } from './Comment';
Expand All @@ -23,14 +24,15 @@ function extractTOC(item: TSDDeclarationReflection, map: TSDDeclarationReflectio
return;
}

const iconHtml = getKindIconHtml(child.kind, child.name);

if (!child.permalink || child.permalink.includes('#')) {
const iconHtml = getKindIconHtml(child.kind, child.name);
const value = escapeMdx(child.name);

toc.push({
// @ts-expect-error Not typed upstream
children: [],
id: child.name,
value: iconHtml ? `${iconHtml} ${child.name}` : child.name,
value: iconHtml ? `${iconHtml} ${value}` : value,
level: 1,
});

Expand Down Expand Up @@ -59,13 +61,13 @@ export default function ApiItem({ readme: Readme, route }: ApiItemProps) {
next: nextItem
? {
permalink: nextItem.permalink,
title: nextItem.name,
title: escapeMdx(nextItem.name),
}
: undefined,
previous: prevItem
? {
permalink: prevItem.permalink,
title: prevItem.name,
title: escapeMdx(prevItem.name),
}
: undefined,
}),
Expand All @@ -79,7 +81,7 @@ export default function ApiItem({ readme: Readme, route }: ApiItemProps) {
<span className="tsd-header-flags">
<Flags flags={item.flags} />
</span>
{item.name} <TypeParametersGeneric params={item.typeParameters} />
{escapeMdx(item.name)} <TypeParametersGeneric params={item.typeParameters} />
</>
}
pageMetadata={
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin/src/components/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Fragment } from 'react';
import Link from '@docusaurus/Link';
import { useReflection } from '../hooks/useReflection';
import type { TSDDeclarationReflection } from '../types';
import { escapeMdx } from '../utils/helpers';
import { AnchorLink } from './AnchorLink';
import { Icon } from './Icon';

Expand All @@ -16,7 +17,7 @@ function IndexChild({ id }: IndexChildProps) {
<li>
<Link className="tsd-kind-icon" to={reflection.permalink ?? `#${reflection.name}`}>
<Icon reflection={reflection} />
{reflection.name}
{escapeMdx(reflection.name)}
</Link>
</li>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin/src/components/Member.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Fragment } from 'react';
import type { JSONOutput } from 'typedoc';
import { useReflection } from '../hooks/useReflection';
import { useReflectionMap } from '../hooks/useReflectionMap';
import { escapeMdx } from '../utils/helpers';
import { hasOwnDocument } from '../utils/visibility';
import { AnchorLink } from './AnchorLink';
import { CommentBadges, isCommentWithModifiers } from './CommentBadges';
Expand Down Expand Up @@ -46,7 +47,7 @@ export function Member({ id }: MemberProps) {
<AnchorLink id={reflection.name} />
<SourceLink sources={reflection.sources} />
<Flags flags={reflection.flags} />
{reflection.name}
{escapeMdx(reflection.name)}
{isCommentWithModifiers(comment) && <CommentBadges comment={comment} />}
</h3>

Expand Down
3 changes: 2 additions & 1 deletion packages/plugin/src/components/MemberDeclaration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { useMinimalLayout } from '../hooks/useMinimalLayout';
import { useReflection } from '../hooks/useReflection';
import { escapeMdx } from '../utils/helpers';
import { Comment, hasComment } from './Comment';
import { DefaultValue } from './DefaultValue';
import { Icon } from './Icon';
Expand All @@ -26,7 +27,7 @@ export function MemberDeclaration({ id }: MemberDeclarationProps) {
<div className="tsd-panel-content">
<div className="tsd-signature tsd-kind-icon">
<Icon reflection={reflection} />
{reflection.name}
{escapeMdx(reflection.name)}
<TypeParametersGeneric params={reflection.typeParameters} />
<span className="tsd-signature-symbol">{reflection.flags?.isOptional && '?'}: </span>{' '}
<Type type={reflection.type} />
Expand Down
Loading