Skip to content
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
56 changes: 54 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,62 @@ There are hooks for both Markdown and Changelog operations (but not for OpenApi)

#### Markdown Hooks

##### **macros**

Allows defining custom macros that can be used in the documentation.

Macros are reusable pieces of text that can be injected into the documentation,
allowing you to define common pieces of text that you can use across multiple files.

A common use case is injecting copyright or license information, without
having to copy-paste the same text across multiple classes, polluting your
source code.

A macro can be defined in your documentation using the `{{macro_name}}` syntax.
In the configuration file, you can then define the macro behavior as a key-value pair, where the key is the name of the macro, and the value is a function that returns the text to inject in place of the macro.

**Type**

```typescript
type MacroSourceMetadata = {
type: 'apex' | 'customobject' | 'customfield' | 'custommetadata' | 'trigger';
name: string;
filePath: string;
};

type MacroFunction = (metadata: MacroSourceMetadata) => string;
```

Notice that the `metadata` object contains information about the source of the file for which the macro is being injected. This allows you to optionally
return different text based on the source of the file.

Example: Injecting a copyright notice

```typescript
//...
macros: {
copyright: () => {
return `Copyright (c) ${new Date().getFullYear()} My Name`;
}
}
//...
```

And then in your source code, you can use the macro like this:

```apex
/**
* {{copyright}}
* @description This is a class
*/
public class MyClass {
//...
}
```

##### **transformReferenceGuide**

Allows changing the Allows changing the frontmatter and content of the reference guide, or even if creating a reference
guide page should be skipped.
Allows changing the frontmatter and content of the reference guide, or if creating a reference guide page altogether should be skipped.

**Type**

Expand Down
3 changes: 3 additions & 0 deletions examples/docsify/apexdocs.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default defineMarkdownConfig({
targetDir: 'docs',
scope: ['public', 'global'],
linkingStrategy: 'none',
macros: {
copyright: () => `@copyright All rights reserved. Cesar Parra ${new Date().getFullYear()}`,
},
transformReferenceGuide: () => {
return {
outputDocPath: 'README.md',
Expand Down
6 changes: 6 additions & 0 deletions examples/docsify/docs/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Reference Guide

## Miscellaneous

### [ASampleClass](miscellaneous/ASampleClass.md)

This is a class description SomeDto .

## Triggers

### [PaymentDeviceTrigger](triggers/PaymentDeviceTrigger.md)
Expand Down
10 changes: 7 additions & 3 deletions examples/docsify/docs/miscellaneous/ASampleClass.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# ASampleClass Class

This is a class description.
This is a class description SomeDto .

**Copyright**

All rights reserved. Cesar Parra 2025

**Mermaid**

Expand All @@ -17,9 +21,9 @@ sequenceDiagram
iframe->>iframe: render mermaid
```

**See** [SomeDto](miscellaneous/SomeDto.md)
**See** SomeDto

**See** [SampleInterface](sample-interfaces/SampleInterface.md)
**See** SampleInterface

## Methods
### `getActiveSurveySettings(surveyType2)`
Expand Down
2 changes: 1 addition & 1 deletion examples/docsify/docs/triggers/PaymentDeviceTrigger.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

This trigger is used to handle the logic for the Payment Device object.

**Events**
**Run**
* Before Insert
* Before Update
3 changes: 2 additions & 1 deletion examples/docsify/src/classes/ASampleClass.cls
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* @description This is a class description.
* @description This is a class description <<SomeDto>>.
* {{copyright}}
* @see SomeDto
* @see SampleInterface
* @mermaid
Expand Down
5 changes: 5 additions & 0 deletions examples/docsify/src/classes/ASampleClass.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>62.0</apiVersion>
<status>Active</status>
</ApexClass>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cparra/apexdocs",
"version": "3.10.0",
"version": "3.11.0",
"description": "Library with CLI capabilities to generate documentation for Salesforce Apex classes.",
"keywords": [
"apex",
Expand Down
29 changes: 28 additions & 1 deletion src/core/markdown/generate-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ParsedFile,
UnparsedSourceBundle,
TopLevelType,
MacroFunction,
} from '../shared/types';
import { parsedFilesToRenderableBundle } from './adapters/renderable-bundle';
import { reflectApexSource } from '../reflection/apex/reflect-apex-source';
Expand Down Expand Up @@ -64,7 +65,8 @@ export function generateDocs(unparsedBundles: UnparsedSourceBundle[], config: Ma
}

return pipe(
generateForApex(filterApexSourceFiles(unparsedBundles), config),
TE.right(replaceMacros(unparsedBundles, config.macros)),
TE.flatMap((unparsedBundles) => generateForApex(filterApexSourceFiles(unparsedBundles), config)),
TE.chain((parsedApexFiles) => {
return pipe(
reflectCustomFieldsAndObjectsAndMetadataRecords(
Expand Down Expand Up @@ -98,6 +100,31 @@ export function generateDocs(unparsedBundles: UnparsedSourceBundle[], config: Ma
);
}

function replaceMacros(
unparsedBundles: UnparsedSourceBundle[],
macros: Record<string, MacroFunction> | undefined,
): UnparsedSourceBundle[] {
if (!macros) {
return unparsedBundles;
}

return unparsedBundles.map((bundle) => {
return {
...bundle,
content: Object.entries(macros).reduce((acc, [macroName, macroFunction]) => {
return acc.replace(
new RegExp(`{{${macroName}}}`, 'g'),
macroFunction({
type: bundle.type,
name: bundle.name,
filePath: bundle.filePath,
}),
);
}, bundle.content),
};
});
}

function generateForApex(apexBundles: UnparsedApexBundle[], config: MarkdownGeneratorConfig) {
const filterOutOfScope = apply(filterScope, config.scope);
const removeExcluded = apply(removeExcludedTags, config.excludeTags);
Expand Down
9 changes: 9 additions & 0 deletions src/core/shared/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ type LinkingStrategy =
// No logic will be applied, the reference path will be used as is.
| 'none';

export type MacroSourceMetadata = {
type: 'apex' | 'customobject' | 'customfield' | 'custommetadata' | 'trigger';
name: string;
filePath: string;
};

export type MacroFunction = (metadata: MacroSourceMetadata) => string;

export type CliConfigurableMarkdownConfig = {
sourceDir: string;
targetDir: string;
Expand Down Expand Up @@ -232,6 +240,7 @@ export type PostHookDocumentationBundle = {
* The configurable hooks that can be used to modify the output of the Markdown generator.
*/
export type MarkdownConfigurableHooks = {
macros: Record<string, MacroFunction>;
transformReferenceGuide: TransformReferenceGuide;
transformDocs: TransformDocs;
transformDocPage: TransformDocPage;
Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type {
MarkdownConfigurableHooks,
MacroFunction,
MacroSourceMetadata,
Skip,
UserDefinedMarkdownConfig,
ReferenceGuidePageData,
Expand Down Expand Up @@ -67,6 +69,8 @@ function defineChangelogConfig(config: ConfigurableChangelogConfig): Partial<Use
export {
defineMarkdownConfig,
ConfigurableMarkdownConfig,
MacroFunction,
MacroSourceMetadata,
defineOpenApiConfig,
ConfigurableOpenApiConfig,
defineChangelogConfig,
Expand Down