Skip to content

Commit

Permalink
More work on documents
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit0 committed May 4, 2024
1 parent bc6ae81 commit c2cd78d
Show file tree
Hide file tree
Showing 29 changed files with 249 additions and 189 deletions.
13 changes: 8 additions & 5 deletions CHANGELOG.md
@@ -1,25 +1,28 @@
# Beta (full release: 2024-06-18)
# Beta (full release: 2024-06-21)

### To Do

- Handle YAML (ick, don't want to add a dependency for that, YAML-like?) frontmatter at the top of documents to set the category/group/title
- Handle `@document` tag to add documents to the tree anywhere
- Handle `@document` tag to add documents to the tree for classes, interfaces, enums, functions, variables
- Handle image and relative markdown links within documents
- Update website docs - consider if reworking website to just be a TypeDoc generated site is a good idea
`@license`, `@import`, sitemapBaseUrl, markedOptions -> markdownItOptions, markdownItLoader, navigation
sort - documents-first, documents-last, alphabetical-ignoring-documents
searchInDocuments
- Correctly handle the `html` being set/not set in markdown-it (currently hardcoded to `true`)
- Add option to always create a module, even for a single entry point site.

### Breaking Changes

- Drop support for Node 16.
- Moved from `marked` to `markdown-it` for parsing as marked has moved to an async model which supporting would significantly complicate TypeDoc's rendering code.
This means that any projects setting `markedOptions` needs to be updated to use `markdownItOptions`.
Unlike `marked@4`, `markdown-it` pushes lots of functionality to plugins. To use plugins, a JavaScript config file must be used with the `markdownItLoader` option.
- Updated Shiki from 0.14 to 1.3. This should mostly be a transparent update which adds another 23 supported languages and 13 supported themes.
- Updated Shiki from 0.14 to 1.x. This should mostly be a transparent update which adds another 23 supported languages and 13 supported themes.
- Renamed `--sitemapBaseUrl` to `--hostedBaseUrl` to reflect that it can be used for more than just the sitemap.
- Removed deprecated `navigation.fullTree` option.
- (WIP) Removed `--media` option, TypeDoc will now detect image links within your comments and markdown documents and automatically copy them to the site.
- Removed `--includes` option, use the `@document` tag instead.
- Removed `--stripYamlFrontmatter` option, TypeDoc will always do this now.
- All function-likes may now have comments directly attached to them. This is a change from previous versions of TypeDoc where functions comments
were always moved down to the signature level. This mostly worked, but caused problems with type aliases, so was partially changed in 0.25.13.
This change was extended to apply not only to type aliases, but also other function-likes declared with variables and callable properties.
Expand All @@ -28,7 +31,7 @@
- API: `MapOptionDeclaration.mapError` has been removed.
- API: Deprecated `BindOption` decorator has been removed.
- API: `DeclarationReflection.indexSignature` has been renamed to `DeclarationReflection.indexSignatures`.
Note: This also affects JSON serialization. TypeDoc will support JSON output from 0.25 until 0.28.
Note: This also affects JSON serialization. TypeDoc will support JSON output from 0.25 until at least 0.27.
- API: `DefaultThemeRenderContext.iconsCache` has been removed as it is no longer needed.

### Features
Expand Down
5 changes: 5 additions & 0 deletions internal-docs/internationalization.md
@@ -1,3 +1,8 @@
---
title: "Adding Locales"
group: Guides
---

# Internationalization

TypeDoc 0.26 added support for internationalization in TypeDoc's output.
Expand Down
14 changes: 13 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -27,7 +27,8 @@
"lunr": "^2.3.9",
"markdown-it": "^14.1.0",
"minimatch": "^9.0.4",
"shiki": "^1.4.0"
"shiki": "^1.4.0",
"yaml": "^2.4.2"
},
"peerDependencies": {
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x"
Expand Down
7 changes: 1 addition & 6 deletions src/index.ts
Expand Up @@ -106,12 +106,7 @@ export {
SerializeEvent,
} from "./lib/serialization";

export {
type TranslationProxy,
type TranslatedString,
type TranslatableStrings,
Internationalization,
} from "./lib/internationalization/internationalization";
export * as Internationalization from "./lib/internationalization/index";

import TypeScript from "typescript";
export { TypeScript };
28 changes: 16 additions & 12 deletions src/lib/converter/comments/declarationReferenceResolver.ts
Expand Up @@ -65,7 +65,7 @@ export function resolveDeclarationReference(
} else if (high[0] !== reflection) {
if (reflection.parent instanceof ContainerReflection) {
high.push(
...(reflection.parent.children?.filter(
...(reflection.parent.childrenIncludingDocuments?.filter(
(c) => c.name === reflection.name,
) || []),
);
Expand Down Expand Up @@ -210,7 +210,10 @@ function resolveSymbolReferencePart(
let high: Reflection[] = [];
let low: Reflection[] = [];

if (!(refl instanceof ContainerReflection) || !refl.children) {
if (
!(refl instanceof ContainerReflection) ||
!refl.childrenIncludingDocuments
) {
return { high, low };
}

Expand All @@ -220,12 +223,12 @@ function resolveSymbolReferencePart(
// so that resolution doesn't behave very poorly with projects using JSDoc style resolution.
// Also is more consistent with how TypeScript resolves link tags.
case ".":
high = refl.children.filter(
high = refl.childrenIncludingDocuments.filter(
(r) =>
r.name === path.path &&
(r.kindOf(ReflectionKind.SomeExport) || r.flags.isStatic),
);
low = refl.children.filter(
low = refl.childrenIncludingDocuments.filter(
(r) =>
r.name === path.path &&
(!r.kindOf(ReflectionKind.SomeExport) || !r.flags.isStatic),
Expand All @@ -235,13 +238,14 @@ function resolveSymbolReferencePart(
// Resolve via "members", interface children, class instance properties/accessors/methods,
// enum members, type literal properties
case "#":
high = refl.children.filter((r) => {
return (
r.name === path.path &&
r.kindOf(ReflectionKind.SomeMember) &&
!r.flags.isStatic
);
});
high =
refl.children?.filter((r) => {
return (
r.name === path.path &&
r.kindOf(ReflectionKind.SomeMember) &&
!r.flags.isStatic
);
}) || [];
break;

// Resolve via "locals"... treat this as a stricter `.` which only supports traversing
Expand All @@ -250,7 +254,7 @@ function resolveSymbolReferencePart(
if (
refl.kindOf(ReflectionKind.SomeModule | ReflectionKind.Project)
) {
high = refl.children.filter((r) => r.name === path.path);
high = refl.children?.filter((r) => r.name === path.path) || [];
}
break;
}
Expand Down
12 changes: 9 additions & 3 deletions src/lib/converter/comments/index.ts
Expand Up @@ -246,7 +246,9 @@ function getConstructorParamPropertyComment(

const paramTag = comment?.getIdentifiedTag(symbol.name, "@param");
if (paramTag) {
return new Comment(paramTag.content);
const result = new Comment(paramTag.content);
result.sourcePath = comment!.sourcePath;
return result;
}
}

Expand Down Expand Up @@ -305,7 +307,9 @@ export function getJsDocComment(

// And pull out the tag we actually care about.
if (ts.isJSDocEnumTag(declaration)) {
return new Comment(comment.getTag("@enum")?.content);
const result = new Comment(comment.getTag("@enum")?.content);
result.sourcePath = comment.sourcePath;
return result;
}

if (
Expand Down Expand Up @@ -343,6 +347,8 @@ export function getJsDocComment(
declaration,
);
} else {
return new Comment(Comment.cloneDisplayParts(tag.content));
const result = new Comment(Comment.cloneDisplayParts(tag.content));
result.sourcePath = comment.sourcePath;
return result;
}
}
9 changes: 9 additions & 0 deletions src/lib/converter/comments/linkResolver.ts
Expand Up @@ -65,6 +65,15 @@ export function resolveLinks(
options,
);
}

if (reflection.isDocument()) {
reflection.content = resolvePartLinks(
reflection,
reflection.content,
externalResolver,
options,
);
}
}

export function resolvePartLinks(
Expand Down
48 changes: 47 additions & 1 deletion src/lib/converter/comments/parser.ts
@@ -1,4 +1,5 @@
import assert, { ok } from "assert";
import { parseDocument as parseYamlDoc } from "yaml";
import type { CommentParserConfig } from ".";
import {
Comment,
Expand Down Expand Up @@ -74,6 +75,7 @@ export function parseComment(
const tok = lexer.done() || lexer.peek();

const comment = new Comment();
comment.sourcePath = file.fileName;
comment.summary = blockContent(
comment,
lexer,
Expand Down Expand Up @@ -173,7 +175,51 @@ export function parseCommentString(
}
}

return content;
// Check for frontmatter
let frontmatterData: Record<string, unknown> = {};
const firstBlock = content[0];
if (firstBlock.text.startsWith("---\n")) {
const end = firstBlock.text.indexOf("\n---\n");
if (end !== -1) {
const yamlText = firstBlock.text.slice("---\n".length, end);
firstBlock.text = firstBlock.text
.slice(end + "\n---\n".length)
.trimStart();

const frontmatter = parseYamlDoc(yamlText, { prettyErrors: false });
for (const warning of frontmatter.warnings) {
// Can't translate issues coming from external library...
logger.warn(
warning.message as TranslatedString,
warning.pos[0] + "---\n".length,
file,
);
}
for (const error of frontmatter.errors) {
// Can't translate issues coming from external library...
logger.error(
error.message as TranslatedString,
error.pos[0] + "---\n".length,
file,
);
}

if (frontmatter.errors.length === 0) {
const data = frontmatter.toJS();
if (typeof data === "object") {
frontmatterData = data;
} else {
logger.error(
logger.i18n.yaml_frontmatter_not_an_object(),
5,
file,
);
}
}
}
}

return { content, frontmatter: frontmatterData };
}

const HAS_USER_IDENTIFIER: `@${string}`[] = [
Expand Down
6 changes: 5 additions & 1 deletion src/lib/converter/comments/rawLexer.ts
Expand Up @@ -12,10 +12,14 @@ export function* lexCommentString(
// Wrapper around our real lex function to collapse adjacent text tokens.
let textToken: Token | undefined;
for (const token of lexCommentString2(file)) {
if (token.kind === TokenSyntaxKind.Text) {
if (
token.kind === TokenSyntaxKind.Text ||
token.kind === TokenSyntaxKind.NewLine
) {
if (textToken) {
textToken.text += token.text;
} else {
token.kind = TokenSyntaxKind.Text;
textToken = token;
}
} else {
Expand Down
6 changes: 4 additions & 2 deletions src/lib/converter/converter.ts
Expand Up @@ -253,18 +253,20 @@ export class Converter extends ChildableComponent<
return project;
}

/** @internal */
addProjectDocuments(project: ProjectReflection) {
const projectDocuments = getDocumentEntryPoints(
this.application.logger,
this.application.options,
);
for (const { displayName, path } of projectDocuments) {
const file = new MinimalSourceFile(readFile(path), path);
const content = this.parseRawComment(file);
const { content, frontmatter } = this.parseRawComment(file);
const docRefl = new DocumentReflection(
displayName,
project,
content,
frontmatter,
);
project.addChild(docRefl);
project.registerReflection(docRefl);
Expand Down Expand Up @@ -434,7 +436,7 @@ export class Converter extends ChildableComponent<

if (entryPoint.readmeFile) {
const readme = readFile(entryPoint.readmeFile);
const content = this.parseRawComment(
const { content } = this.parseRawComment(
new MinimalSourceFile(readme, entryPoint.readmeFile),
);
reflection.readme = content;
Expand Down
5 changes: 5 additions & 0 deletions src/lib/converter/plugins/CategoryPlugin.ts
Expand Up @@ -239,6 +239,11 @@ export class CategoryPlugin extends ConverterComponent {
}
}

if (reflection.isDocument() && "category" in reflection.frontmatter) {
categories.add(String(reflection.frontmatter["category"]));
delete reflection.frontmatter["category"];
}

categories.delete("");

for (const cat of categories) {
Expand Down

0 comments on commit c2cd78d

Please sign in to comment.