(
macroName: string,
context?: { label?: string },
)
| 94 | } |
| 95 | |
| 96 | public async runAndGetOutput( |
| 97 | macroName: string, |
| 98 | context?: { label?: string }, |
| 99 | ): Promise<string> { |
| 100 | this.emittedConflictNotice = false; |
| 101 | const { basename, memberAccess } = getUserScriptMemberAccess(macroName); |
| 102 | |
| 103 | // ------------------------------------------------------------------ |
| 104 | // Step 1 – exact match (case-sensitive) on *trimmed* names. |
| 105 | // This preserves historical behaviour where two macros differing |
| 106 | // only by case are treated as distinct entities. |
| 107 | // ------------------------------------------------------------------ |
| 108 | const trimmed = (s: string | undefined) => (s ?? "").trim(); |
| 109 | let macroChoice = flattenChoices(this.choices).find( |
| 110 | (choice): choice is IMacroChoice => |
| 111 | choice.type === "Macro" && trimmed(choice.name) === trimmed(basename), |
| 112 | ); |
| 113 | |
| 114 | // ------------------------------------------------------------------ |
| 115 | // Step 2 – fallback to case-insensitive lookup for user convenience. |
| 116 | // If this yields *multiple* matches we abort to prevent ambiguity. |
| 117 | // ------------------------------------------------------------------ |
| 118 | if (!macroChoice) { |
| 119 | const lower = (s: string | undefined) => trimmed(s).toLowerCase(); |
| 120 | const ciMatches = flattenChoices(this.choices).filter( |
| 121 | (choice): choice is IMacroChoice => |
| 122 | choice.type === "Macro" && lower(choice.name) === lower(basename), |
| 123 | ); |
| 124 | |
| 125 | if (ciMatches.length > 1) { |
| 126 | log.logError( |
| 127 | `Ambiguous macro reference '${macroName}'. Multiple choices match when ignoring case.`, |
| 128 | ); |
| 129 | throw new Error( |
| 130 | `Ambiguous macro reference '${macroName}'. Please disambiguate by renaming macros.`, |
| 131 | ); |
| 132 | } |
| 133 | |
| 134 | macroChoice = ciMatches[0]; |
| 135 | } |
| 136 | |
| 137 | if (!macroChoice) { |
| 138 | log.logError(`macro '${macroName}' does not exist.`); |
| 139 | throw new Error(`macro '${macroName}' does not exist.`); |
| 140 | } |
| 141 | |
| 142 | // Create a dedicated engine for this macro |
| 143 | const engine = new MacroChoiceEngine( |
| 144 | this.app, |
| 145 | this.plugin, |
| 146 | macroChoice, |
| 147 | this.choiceExecutor, |
| 148 | this.variables, |
| 149 | undefined, |
| 150 | context?.label, |
| 151 | ); |
| 152 | |
| 153 | if (memberAccess?.length) { |
no test coverage detected