krisztianb / typedoc-plugin-replace-text

Plugin for TypeDoc that replaces text in the documentation
ISC License
5 stars 2 forks source link

Feature Request: Add path to current file in replacer function #9

Closed treardon17 closed 7 months ago

treardon17 commented 8 months ago

I was hoping to use this package to replace the content of a comment with the contents of a file just like https://github.com/krisztianb/typedoc-plugin-replace-text/issues/4. I can get something to work using the replacer function, but in order to get the path to the file I want to read I would need the path to the current file being observed. For example, if I have a comment defined in a file located in src/my/location/Test.ts and a corresponding src/my/location/README.md I would like to do something like this:

/**
 * My test class.
 *
 * [[include ./README.md]]
 */
class Test {}

In order to resolve the location of ./README.md, I would need to know I'm located in src/my/location/Test.ts. It looks like the replacer function just gives info about the string match. Would it be feasible to add some more info about the match's file path to the replacer function?

krisztianb commented 8 months ago

Hi. Sounds reasonable, but I'm not sure if the plugin has access to this information in the current TypeDoc event it is triggered by. I will have to look into this more deeply.

krisztianb commented 8 months ago

Btw. you can already do this, can't you? https://typedoc.org/options/comments/#includes

But you would have to move the Markdown files to different folder away from the source code. I guess this is what you want to avoid?

treardon17 commented 8 months ago

@krisztianb yes, my goal is to put the README files right next to the source code so it's easier to keep the documentation up to date. I'm working in a monorepo and trying to document how all the parts work together, so keeping the md files close is pretty important. It would be fantastic if I could do something like this:

/**
 * @packageDocumentation
 * [[include ./README.md]]
 */
class Test {}

So that the contents of the README.md file get added as the packageDocumentation (I'm trying to avoid writing all my docs in TSDoc comments). There very well could be a better way to do what I'm trying to achieve, but this seemed like it could be a nice solution. Totally makes sense if it's not possible though if that info isn't made available by Typedoc.

treardon17 commented 8 months ago

It looks like there's a Typedoc PR that might expose this information to the plugin: https://github.com/TypeStrong/typedoc/pull/2309

That appears to confirm this is not currently possible in Typedoc, but could be in the future. With that in mind, I think this FR can be closed.

krisztianb commented 8 months ago

I don't think that PR is adding what you are looking for. To me it looks like it adds some TypeDoc entry point information (from the configuration) to reflections.

But the data you are looking for is actually available as an array on the reflection object: https://typedoc.org/api/classes/Models.DeclarationReflection.html#sources

It is an array because a reflection could be generated out of multiple files (for example by TypeScript's declaration merging feature). So this does seem to be doable, but you will have to deal with an array of strings for the paths and not a single path.

krisztianb commented 8 months ago

I created a branch with the required changes: https://github.com/krisztianb/typedoc-plugin-replace-text/tree/GH-9-source-info-in-replacer-function

Could you test if this works for you? There is an example in the README on how to get the filename. The filename should be relative to the TypeScript project root.

Here is an example on how the sources object looks like:

sources: [
  SourceReference {
    fileName: 'a.ts',
    fullFileName: 'C:/MyProjects/code/typedoc-plugin-replace-text/test/replace-with-function/input/a.ts',
    line: 6,
    character: 16,
    url: 'https://github.com/krisztianb/typedoc-plugin-replace-text/blob/6c2e51f/test/replace-with-function/input/a.ts#L6'
  }
]
treardon17 commented 8 months ago

That was quick! I'll try and test it today! Thank you 🙏 🎉

treardon17 commented 8 months ago

@krisztianb this works great! Had to tweak one thing to get it to work: https://github.com/krisztianb/typedoc-plugin-replace-text/pull/10 -- looked like the result of hasSources was always false for me without that change. Thanks again for jumping on this so quickly!

Here is an example of my config if you're interested (going to figure out a better match pattern later):

const { existsSync, readFileSync } = require('fs');
const path = require('path');

module.exports = {
    out: 'output',
    entryPointStrategy: 'expand',
    entryPoints: ['input/module1.ts', 'input/module2.ts'],
    tsconfig: 'tsconfig.json',
    readme: 'MAIN.md',
    plugin: ['typedoc-plugin-replace-text'],
    replaceText: {
        inCodeCommentText: true,
        inCodeCommentTags: true,
        inIncludedFiles: true,
        replacements: [
            {
                pattern: 'README.MD',
                flags: 'g',
                replace(match) {
                    if (this.sources?.[0]?.fullFileName) {
                        const fPath = path.join(path.dirname(this.sources[0].fullFileName), 'README.md');
                        const readmeExists = existsSync(fPath);

                        return readmeExists ? readFileSync(fPath) : match;
                    }
                    return match;
                },
            },
        ],
    },
};

Example usage (inside a module):

/**
 * @packageDocumentation
 * README.MD
 */
krisztianb commented 7 months ago

Released in 3.3.0 Happy testing. 🎉