Skip to content

Commit e080437

Browse files
fix: Show doubly nested definitions
Resolves #234
1 parent c43a3fa commit e080437

File tree

1 file changed

+80
-49
lines changed

1 file changed

+80
-49
lines changed

website/src/components/templates/FuncTemplate.tsx

Lines changed: 80 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { FC } from "hono/jsx";
2-
import type { FuncBody, Page } from "../../types/model";
2+
import type { Func, FuncBody, Page } from "../../types/model";
33
import {
44
FunctionDefinition,
55
FunctionDisplay,
@@ -70,57 +70,88 @@ export const FuncTemplate: FC<FuncTemplateProps> = ({
7070
<FunctionParameters func={content} />
7171
</div>
7272

73-
{content.scope.length > 0 && (
74-
<div class="mt-8">
75-
<h2 id="definitions" class="flex items-baseline gap-1">
76-
定義
77-
<Tooltip kind="definitions" />
78-
</h2>
79-
80-
{content.scope.map((method, index) => (
81-
<div
82-
key={method.name}
83-
class="mb-8 pb-6 border-b border-gray-100 last:border-0"
84-
>
85-
<h3
86-
id={`definitions-${method.name}`}
87-
class="method-head mb-3 flex items-center gap-2"
73+
<ScopedDefinitions scope={content.scope} />
74+
</BaseTemplate>
75+
);
76+
};
77+
78+
/**
79+
* If the definitions in `scope` are associated with the top scope on this page, then `parent` should be `undefined`.
80+
* Otherwise, `parent` should describe the parent of these definitions.
81+
*/
82+
function ScopedDefinitions({
83+
scope,
84+
parent,
85+
}: { scope: Func[]; parent?: { name: string; id: string } | undefined }) {
86+
if (scope.length === 0) {
87+
return null;
88+
}
89+
90+
/** `parent?.id` as a string */
91+
const parentId = parent ? `${parent.id}-` : "";
92+
93+
// To be consistent with the official typst.app/docs,
94+
// the following heading levels will _not_ increase with the scope level.
95+
return (
96+
<div class="mt-8">
97+
<h2 id={`${parentId}definitions`} class="flex items-baseline gap-1">
98+
{parent ? (
99+
// Currently, the scope has at most two levels.
100+
// Therefore, it is sufficient to only annotate the direct `parent`.
101+
<>
102+
<code>{parent.name}</code>の定義
103+
</>
104+
) : (
105+
"定義"
106+
)}
107+
<Tooltip kind="definitions" />
108+
</h2>
109+
110+
{scope.map((method, index) => {
111+
const methodId = `${parentId}definitions-${method.name}`;
112+
113+
return (
114+
<div
115+
key={method.name}
116+
class="mb-8 pb-6 border-b border-gray-100 last:border-0"
117+
>
118+
<h3 id={methodId} class="method-head mb-3 flex items-center gap-2">
119+
<code
120+
class="text-base font-medium"
121+
style={
122+
method.deprecation
123+
? { textDecoration: "line-through" }
124+
: undefined
125+
}
88126
>
89-
<code
90-
class="text-base font-medium"
91-
style={
92-
method.deprecation
93-
? { textDecoration: "line-through" }
94-
: undefined
95-
}
96-
>
97-
{method.name}
98-
</code>
99-
100-
<small class="flex items-center">
101-
{method.element && <Tooltip kind="element" />}
102-
{method.contextual && <Tooltip kind="contextual" />}
103-
</small>
104-
</h3>
105-
106-
{method.deprecation && (
107-
<div className="mt-1">
108-
<DeprecationWarning message={method.deprecation} />
109-
</div>
110-
)}
111-
112-
<div class="pl-2">
113-
<FunctionDisplay
114-
func={method}
115-
prefix={`definitions-${method.name}`}
116-
/>
127+
{method.name}
128+
</code>
129+
130+
<small class="flex items-center">
131+
{method.element && <Tooltip kind="element" />}
132+
{method.contextual && <Tooltip kind="contextual" />}
133+
</small>
134+
</h3>
135+
136+
{method.deprecation && (
137+
<div className="mt-1">
138+
<DeprecationWarning message={method.deprecation} />
117139
</div>
140+
)}
141+
142+
<div class="pl-2">
143+
<FunctionDisplay func={method} prefix={methodId} />
118144
</div>
119-
))}
120-
</div>
121-
)}
122-
</BaseTemplate>
145+
146+
<ScopedDefinitions
147+
scope={method.scope}
148+
parent={{ name: method.name, id: methodId }}
149+
/>
150+
</div>
151+
);
152+
})}
153+
</div>
123154
);
124-
};
155+
}
125156

126157
export default FuncTemplate;

0 commit comments

Comments
 (0)