Skip to content

Commit

Permalink
Make plugin replace in all included markdown files (closes #1)
Browse files Browse the repository at this point in the history
  • Loading branch information
krisztianb committed Oct 26, 2022
1 parent 151a23b commit 053205f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 27 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.1.0] - 2022-10-26
### Changes
- Option value `inIncludedFiles` now also applies to all included markdown files.

## [2.0.0] - 2022-07-09
### Breaking Changes
- Support changed to TypeDoc versions 0.23.x due to a breaking change in TypeDoc's API.

## [1.0.0] - 2022-04-07
First release

[unreleased]: https://github.com/krisztianb/typedoc-plugin-replace-text/compare/v2.0.0...HEAD
[unreleased]: https://github.com/krisztianb/typedoc-plugin-replace-text/compare/v2.1.0...HEAD
[2.1.0]: https://github.com/krisztianb/typedoc-plugin-replace-text/releases/tag/v2.1.0
[2.0.0]: https://github.com/krisztianb/typedoc-plugin-replace-text/releases/tag/v2.0.0
[1.0.0]: https://github.com/krisztianb/typedoc-plugin-replace-text/releases/tag/v1.0.0
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ This is a plugin for [TypeDoc](https://github.com/TypeStrong/typedoc) that repla
This includes:

- Text in code comments
- Text in the README
- Text in the main README
- Text in [included markdown files](https://typedoc.org/guides/options/#includes)

You can specify matching patterns and the text they should be replaced with.

This can be useful for:

- Creating links from ticket IDs (eg: replace "GH-12345" with a link to https://github.com/your-name/the-repo/issues/12345)
- Creating links from author names (eg: link "Your Name" to your GitHub or corporate profile page)
- Replacing internal URLs with external ones
- Replacing internal URLs (domains) with external ones
- Replacing custom placeholders with anything you like (eg: images)
- Remove or replace text in your README.md file that is included by TypeDoc
- Remove URLs or other text
- Removing URLs or other text from your documentation
- etc.

## Installation
Expand Down Expand Up @@ -64,7 +64,7 @@ Explanation:
| --------------------- | ----------------------------------------------------------------------------- |
| **inCodeCommentText** | Specifies if the plugin should replace in the text of comments (not including the text of tags like the description of parameters for a method) in your code. (optional - defaults to `true`) |
| **inCodeCommentTags** | Specifies if the plugin should replace in the text of tags (like the description of parameters for a method) in your code comments. (optional - defaults to `true`) |
| **inIncludedFiles** | Specifies if the plugin should replace in your README file. (optional - defaults to `true`) |
| **inIncludedFiles** | Specifies if the plugin should replace in included markdown files (this includes the main README). (optional - defaults to `true`) |
| **replacements** | The search patterns and texts they should be replaced with. (`pattern` is the search Regex, `flags` are the optional Regex flags that default to `g` and `replace` is the inserted text) |

## Bugs
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typedoc-plugin-replace-text",
"version": "2.0.0",
"version": "2.1.0",
"description": "Plugin for TypeDoc that replaces text in the documentation",
"author": {
"name": "Krisztián Balla",
Expand Down
65 changes: 46 additions & 19 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Application, CommentDisplayPart, Context, Converter } from "typedoc";
import { Application, CommentDisplayPart, Context, Converter, MarkdownEvent } from "typedoc";
import { PluginOptions } from "./plugin_options";

/**
Expand All @@ -10,8 +10,7 @@ import { PluginOptions } from "./plugin_options";
*
* # How does it do it?
*
* The plugin scans through all comments of all reflections and uses the replacment patterns specified
* by the user to replace texts.
* The plugin scans through all comments of all reflections and uses the replacment patterns specified by the user.
*/
export class Plugin {
/** The options of this plugin. */
Expand All @@ -32,48 +31,63 @@ export class Plugin {
* @param typedoc The TypeDoc application.
*/
private subscribeToApplicationEvents(typedoc: Readonly<Application>): void {
typedoc.converter.on(Converter.EVENT_BEGIN, (c: Readonly<Context>) => this.onConverterBegin(c));
typedoc.converter.on(Converter.EVENT_RESOLVE_BEGIN, (c: Readonly<Context>) => this.onConverterResolveBegin(c));
typedoc.converter.on(Converter.EVENT_BEGIN, (c: Readonly<Context>) => this.onTypeDocConverterBegin(c));
typedoc.converter.on(Converter.EVENT_RESOLVE_BEGIN, (c: Readonly<Context>) =>
this.onTypeDocConverterResolveBegin(c),
);

// The priority makes sure that our event handler is called before TypeDoc converts the markdown content
typedoc.renderer.on(MarkdownEvent.PARSE, (e: MarkdownEvent) => this.onTypeDocMarkdownParse(e), typedoc, 100);
}

/**
* Triggered when the converter begins converting a project.
* @param context Describes the current state the converter is in.
* Triggered when the TypeDoc converter begins converting a project.
* @param context Describes the current state the TypeDoc converter is in.
*/
public onConverterBegin(context: Readonly<Context>): void {
this.options.readValuesFromApplication(context.converter.owner);
public onTypeDocConverterBegin(context: Readonly<Context>): void {
this.options.readValuesFromTypeDocApplication(context.converter.owner);
}

/**
* Triggered when the TypeDoc converter begins resolving a project.
* @param context Describes the current state the converter is in.
* @param context Describes the current state the TypeDoc converter is in.
*/
public onConverterResolveBegin(context: Readonly<Context>): void {
public onTypeDocConverterResolveBegin(context: Readonly<Context>): void {
if (!this.hasSomethingTodo) {
return;
}

const project = context.project;

if (this.options.replaceInIncludedFiles && project.readme) {
this.applyReplacementsTo(project.readme);
}

// go through all the reflections' comments
for (const key in project.reflections) {
const reflection = project.reflections[key];

if (reflection.comment) {
if (this.options.replaceInCodeCommentText) {
this.applyReplacementsTo(reflection.comment.summary);
this.applyReplacementsToCommentParts(reflection.comment.summary);
}
if (this.options.replaceInCodeCommentTags) {
reflection.comment.blockTags.forEach((tag) => this.applyReplacementsTo(tag.content));
reflection.comment.blockTags.forEach((tag) => this.applyReplacementsToCommentParts(tag.content));
}
}
}
}

/**
* Triggered when the TypeDoc renderer parses a Markdown file.
* @param event Markdown parsing event information.
*/
public onTypeDocMarkdownParse(event: MarkdownEvent): void {
if (!this.hasSomethingTodo) {
return;
}

if (this.options.replaceInIncludedFiles) {
event.parsedText = this.applyReplacementsToString(event.parsedText);
}
}

/**
* Checks if the plugin is configured in a way that it has something to do.
* @returns True, if the plugin has something to do, otherwise false.
Expand All @@ -91,9 +105,22 @@ export class Plugin {
* Applies the replacements to the given text parts.
* @param parts The text parts on which to apply the replacements.
*/
private applyReplacementsTo(parts: CommentDisplayPart[]): void {
private applyReplacementsToCommentParts(parts: CommentDisplayPart[]): void {
parts.forEach((part) => {
this.options.replacements.forEach((r) => (part.text = part.text.replace(r.regex, r.replace)));
part.text = this.applyReplacementsToString(part.text);
});
}

/**
* Applies the replacements to the given string.
* @param str The string on which to apply the replacements.
* @returns The string with the replacements applied to it.
*/
private applyReplacementsToString(str: string): string {
let result = str;

this.options.replacements.forEach((r) => (result = result.replace(r.regex, r.replace)));

return result;
}
}
2 changes: 1 addition & 1 deletion src/plugin_options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class PluginOptions {
* Reads the values of the plugin options from the application options.
* @param typedoc The TypeDoc application.
*/
public readValuesFromApplication(typedoc: Readonly<Application>): void {
public readValuesFromTypeDocApplication(typedoc: Readonly<Application>): void {
// Yes, this type assertion sucks, but there's something wrong with the Type Definitions of TypeDoc
const config = typedoc.options.getValue("replaceText") as unknown as PluginConfig | undefined;

Expand Down

0 comments on commit 053205f

Please sign in to comment.