Repository: platers/obsidian-linter
Pull request #648 (2023-03-12 22:50:56)

Fix Language Support for Rule Options that Come from Actual Rules and not General Settings
Relates to #608 

I need to make one more pass at this and just make sure things like fine. I know a couple of variables will likely be renamed, but I am not sure what else will get changed when I make that second pass later on this week.


Patch:
diff --git a/src/docs.ts b/src/docs.ts
index 4cedd28..7a134e1 100644
--- a/src/docs.ts
+++ b/src/docs.ts
@@ -56,7 +56,7 @@ function generateDocs() {
 
     const options_list = rule.options.slice(1).map((option) => {
       let text = dedent`
-        - ${option.name}: ${option.description}
+        - ${option.getName()}: ${option.getDescription()}
         \t- Default: \`${option.defaultValue}\`
       `;
 
@@ -98,11 +98,11 @@ function generateDocs() {
 
     rules_docs += dedent`
       ${''}
-      ### ${rule.name}
+      ### ${rule.getName()}
       ${''}
       Alias: \`${rule.alias}\`
       ${''}
-      ${rule.description}
+      ${rule.getDescription()}
       ${''}
       ${options}
       ${''}
diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts
index 4f8b34a..c2999b7 100644
--- a/src/lang/locale/en.ts
+++ b/src/lang/locale/en.ts
@@ -300,7 +300,6 @@ export default {
       'try-to-escape-single-line-arrays': {
         'name': 'Try to Escape Single Line Arrays',
         'description': 'Tries to escape array values assuming that an array starts with "[", ends with "]", and has items that are delimited by ",".',
-
       },
     },
     // file-name-heading.ts
diff --git a/src/option.ts b/src/option.ts
index 0205470..4a05af2 100644
--- a/src/option.ts
+++ b/src/option.ts
@@ -10,23 +10,32 @@ export type SearchOptionInfo = {name: string, description: string, options?: Dro
 
 export abstract class Option {
   public ruleAlias: string;
-  public searchInfo: SearchOptionInfo;
 
   /**
    * Create an option
-   * @param {string} name - The name of the option
-   * @param {string} description - The description of the option
+   * @param {LanguageStringKey} nameKey - The name key of the option
+   * @param {LanguageStringKey} descriptionKey - The description key of the option
    * @param {any} defaultValue - The default value of the option
    * @param {string?} ruleAlias - The alias of the rule this option belongs to
    */
-  constructor(public configKey: string, public name: string, public description: string, public defaultValue: any, ruleAlias?: string | null) {
-    this.searchInfo = {name: name, description: description};
-
+  constructor(public configKey: string, public nameKey: LanguageStringKey, public descriptionKey: LanguageStringKey, public defaultValue: any, ruleAlias?: string | null) {
     if (ruleAlias) {
       this.ruleAlias = ruleAlias;
     }
   }
 
+  public getName(): string {
+    return getTextInLanguage(this.nameKey) ?? '';
+  }
+
+  public getDescription(): string {
+    return getTextInLanguage(this.descriptionKey) ?? '';
+  }
+
+  public getSearchInfo(): SearchOptionInfo {
+    return {name: this.getName(), description: this.getDescription()};
+  }
+
   public abstract display(containerEl: HTMLElement, settings: LinterSettings, plugin: LinterPlugin): void;
 
   protected setOption(value: any, settings: LinterSettings): void {
@@ -34,8 +43,8 @@ export abstract class Option {
   }
 
   protected parseNameAndDescriptionAndRemoveSettingBorder(setting: Setting) {
-    parseTextToHTMLWithoutOuterParagraph(this.name, setting.nameEl);
-    parseTextToHTMLWithoutOuterParagraph(this.description, setting.descEl);
+    parseTextToHTMLWithoutOuterParagraph(this.getName(), setting.nameEl);
+    parseTextToHTMLWithoutOuterParagraph(this.getDescription(), setting.descEl);
 
     // remove border around every setting item
     setting.settingEl.style.border = 'none';
@@ -116,14 +125,16 @@ export class MomentFormatOption extends Option {
 }
 
 export class DropdownRecord {
-  public value: string;
+  public value: LanguageStringKey;
   public description: string;
-  public displayValue: string;
 
   constructor(value: LanguageStringKey, description: string) {
     this.value = value;
     this.description = description;
-    this.displayValue = getTextInLanguage(value);
+  }
+
+  getDisplayValue(): string {
+    return getTextInLanguage(this.value) ?? '';
   }
 }
 
@@ -131,10 +142,13 @@ export class DropdownOption extends Option {
   public defaultValue: string;
   public options: DropdownRecord[];
 
-  constructor(configKey: string, name: string, description: string, defaultValue: string, options: DropdownRecord[], ruleAlias?: string | null) {
-    super(configKey, name, description, defaultValue, ruleAlias);
+  constructor(configKey: string, nameKey: LanguageStringKey, descriptionKey: LanguageStringKey, defaultValue: string, options: DropdownRecord[], ruleAlias?: string | null) {
+    super(configKey, nameKey, descriptionKey, defaultValue, ruleAlias);
     this.options = options;
-    this.searchInfo.options = options;
+  }
+
+  public getSearchInfo(): SearchOptionInfo {
+    return {name: this.getName(), description: this.getDescription(), options: this.options};
   }
 
   public display(containerEl: HTMLElement, settings: LinterSettings, plugin: LinterPlugin): void {
@@ -142,7 +156,7 @@ export class DropdownOption extends Option {
         .addDropdown((dropdown) => {
           // First, add all the available options
           for (const option of this.options) {
-            dropdown.addOption(option.value, option.displayValue);
+            dropdown.addOption(option.value.replace('enums.', ''), option.getDisplayValue());
           }
 
           // Set currently selected value from existing settings
diff --git a/src/rules.ts b/src/rules.ts
index 1685eba..595e368 100644
--- a/src/rules.ts
+++ b/src/rules.ts
@@ -17,7 +17,7 @@ import {
 } from './utils/yaml';
 import {LintCommand} from './ui/linter-components/custom-command-option';
 import {CustomReplace} from './ui/linter-components/custom-replace-option';
-import {getTextInLanguage} from './lang/helpers';
+import {getTextInLanguage, LanguageStringKey} from './lang/helpers';
 
 // CommonStyles are settings that are used in multiple places and thus need to be external to rules themselves to help facilitate their use
 export type CommonStyles = {
@@ -61,8 +61,9 @@ export enum RuleType {
 export class Rule {
   /**
    * Create a rule
-   * @param {string} name - The name of the rule
-   * @param {string} description - The description of the rule
+   * @param {LanguageStringKey} nameKey - The name key of the rule
+   * @param {LanguageStringKey} descriptionKey - The description key of the rule
+   * @param {string} settingsKey - The settings key of the rule
    * @param {string} alias - The alias of the rule which also is the config key for the rule
    * @param {RuleType} type - The type of the rule
    * @param {ApplyFunction} apply - The function to apply the rule
@@ -71,8 +72,9 @@ export class Rule {
    * @param {boolean} [hasSpecialExecutionOrder=false] - The rule has special execution order
    */
   constructor(
-      public name: string,
-      public description: string,
+      private nameKey: LanguageStringKey,
+      private descriptionKey: LanguageStringKey,
+      public settingsKey: string,
       public alias: string,
       public type: RuleType,
       public apply: ApplyFunction,
@@ -80,7 +82,7 @@ export class Rule {
       public options: Array<Option> = [],
       public readonly hasSpecialExecutionOrder: boolean = false,
   ) {
-    options.unshift(new BooleanOption('enabled', this.description, '', false));
+    options.unshift(new BooleanOption('enabled', this.descriptionKey, '' as LanguageStringKey, false));
     for (const option of options) {
       option.ruleAlias = alias;
     }
@@ -90,14 +92,22 @@ export class Rule {
     const options: { [optionName: string]: any } = {};
 
     for (const option of this.options) {
-      options[option.name] = option.defaultValue;
+      options[option.configKey] = option.defaultValue;
     }
 
     return options;
   }
 
   public getOptions(settings: LinterSettings) {
-    return settings.ruleConfigs[this.name];
+    return settings.ruleConfigs[this.settingsKey];
+  }
+
+  public getName(): string {
+    return getTextInLanguage(this.nameKey);
+  }
+
+  public getDescription(): string {
+    return getTextInLanguage(this.descriptionKey);
   }
 
   public getURL(): string {
@@ -107,7 +117,7 @@ export class Rule {
   }
 
   public enabledOptionName(): string {
-    return this.options[0].name;
+    return this.options[0].configKey;
   }
 }
 
@@ -187,7 +197,7 @@ export const ruleTypeToRules = new Map<RuleType, Rule[]>;
 
 export function registerRule(rule: Rule): void {
   rules.push(rule);
-  rules.sort((a, b) => (RuleTypeOrder.indexOf(a.type) - RuleTypeOrder.indexOf(b.type)) || (a.name.localeCompare(b.name)));
+  rules.sort((a, b) => (RuleTypeOrder.indexOf(a.type) - RuleTypeOrder.indexOf(b.type)) || (a.settingsKey.localeCompare(b.settingsKey)));
   rulesDict[rule.alias] = rule;
 
   if (ruleTypeToRules.has(rule.type)) {
diff --git a/src/rules/auto-correct-common-misspellings.ts b/src/rules/auto-correct-common-misspellings.ts
index 5eeecf9..b685c7d 100644
--- a/src/rules/auto-correct-common-misspellings.ts
+++ b/src/rules/auto-correct-common-misspellings.ts
@@ -13,8 +13,8 @@ class AutoCorrectCommonMisspellingsOptions implements Options {
 export default class AutoCorrectCommonMisspellings extends RuleBuilder<AutoCorrectCommonMisspellingsOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.auto-correct-common-misspellings.name',
-      descriptionTextKey: 'rules.auto-correct-common-misspellings.description',
+      nameKey: 'rules.auto-correct-common-misspellings.name',
+      descriptionKey: 'rules.auto-correct-common-misspellings.description',
       type: RuleType.CONTENT,
     });
   }
@@ -111,8 +111,8 @@ export default class AutoCorrectCommonMisspellings extends RuleBuilder<AutoCorre
     return [
       new TextAreaOptionBuilder({
         OptionsClass: AutoCorrectCommonMisspellingsOptions,
-        nameTextKey: 'rules.auto-correct-common-misspellings.ignore-words.name',
-        descriptionTextKey: 'rules.auto-correct-common-misspellings.ignore-words.description',
+        nameKey: 'rules.auto-correct-common-misspellings.ignore-words.name',
+        descriptionKey: 'rules.auto-correct-common-misspellings.ignore-words.description',
         optionsKey: 'ignoreWords',
         splitter: wordSplitterRegex,
         separator: ', ',
diff --git a/src/rules/blockquotify-on-paste.ts b/src/rules/blockquotify-on-paste.ts
index 059e635..bc221f0 100644
--- a/src/rules/blockquotify-on-paste.ts
+++ b/src/rules/blockquotify-on-paste.ts
@@ -12,8 +12,8 @@ class BlockquotifyOnPasteOptions implements Options {
 export default class BlockquotifyOnPaste extends RuleBuilder<BlockquotifyOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.add-blockquote-indentation-on-paste.name',
-      descriptionTextKey: 'rules.add-blockquote-indentation-on-paste.description',
+      nameKey: 'rules.add-blockquote-indentation-on-paste.name',
+      descriptionKey: 'rules.add-blockquote-indentation-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/capitalize-headings.ts b/src/rules/capitalize-headings.ts
index 541c6f4..b4825b5 100644
--- a/src/rules/capitalize-headings.ts
+++ b/src/rules/capitalize-headings.ts
@@ -400,8 +400,8 @@ class CapitalizeHeadingsOptions implements Options {
 export default class CapitalizeHeadings extends RuleBuilder<CapitalizeHeadingsOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.capitalize-headings.name',
-      descriptionTextKey: 'rules.capitalize-headings.description',
+      nameKey: 'rules.capitalize-headings.name',
+      descriptionKey: 'rules.capitalize-headings.description',
       type: RuleType.HEADING,
     });
   }
@@ -520,8 +520,8 @@ export default class CapitalizeHeadings extends RuleBuilder<CapitalizeHeadingsOp
     return [
       new DropdownOptionBuilder({
         OptionsClass: CapitalizeHeadingsOptions,
-        nameTextKey: 'rules.capitalize-headings.style.name',
-        descriptionTextKey: 'rules.capitalize-headings.style.description',
+        nameKey: 'rules.capitalize-headings.style.name',
+        descriptionKey: 'rules.capitalize-headings.style.description',
         optionsKey: 'style',
         records: [
           {
@@ -540,22 +540,22 @@ export default class CapitalizeHeadings extends RuleBuilder<CapitalizeHeadingsOp
       }),
       new BooleanOptionBuilder({
         OptionsClass: CapitalizeHeadingsOptions,
-        nameTextKey: 'rules.capitalize-headings.ignore-case-words.name',
-        descriptionTextKey: 'rules.capitalize-headings.ignore-case-words.description',
+        nameKey: 'rules.capitalize-headings.ignore-case-words.name',
+        descriptionKey: 'rules.capitalize-headings.ignore-case-words.description',
         optionsKey: 'ignoreCasedWords',
       }),
       new TextAreaOptionBuilder({
         OptionsClass: CapitalizeHeadingsOptions,
-        nameTextKey: 'rules.capitalize-headings.ignore-words.name',
-        descriptionTextKey: 'rules.capitalize-headings.ignore-words.description',
+        nameKey: 'rules.capitalize-headings.ignore-words.name',
+        descriptionKey: 'rules.capitalize-headings.ignore-words.description',
         optionsKey: 'ignoreWords',
         splitter: wordSplitterRegex,
         separator: ', ',
       }),
       new TextAreaOptionBuilder({
         OptionsClass: CapitalizeHeadingsOptions,
-        nameTextKey: 'rules.capitalize-headings.lowercase-words.name',
-        descriptionTextKey: 'rules.capitalize-headings.lowercase-words.description',
+        nameKey: 'rules.capitalize-headings.lowercase-words.name',
+        descriptionKey: 'rules.capitalize-headings.lowercase-words.description',
         optionsKey: 'lowercaseWords',
         splitter: wordSplitterRegex,
         separator: ', ',
diff --git a/src/rules/compact-yaml.ts b/src/rules/compact-yaml.ts
index 557e4a7..0c1d445 100644
--- a/src/rules/compact-yaml.ts
+++ b/src/rules/compact-yaml.ts
@@ -11,8 +11,8 @@ class CompactYamlOptions implements Options {
 export default class CompactYaml extends RuleBuilder<CompactYamlOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.compact-yaml.name',
-      descriptionTextKey: 'rules.compact-yaml.description',
+      nameKey: 'rules.compact-yaml.name',
+      descriptionKey: 'rules.compact-yaml.description',
       type: RuleType.SPACING,
     });
   }
@@ -89,8 +89,8 @@ export default class CompactYaml extends RuleBuilder<CompactYamlOptions> {
     return [
       new BooleanOptionBuilder({
         OptionsClass: CompactYamlOptions,
-        nameTextKey: 'rules.compact-yaml.inner-new-lines.name',
-        descriptionTextKey: 'rules.compact-yaml.inner-new-lines.description',
+        nameKey: 'rules.compact-yaml.inner-new-lines.name',
+        descriptionKey: 'rules.compact-yaml.inner-new-lines.description',
         optionsKey: 'innerNewLines',
       }),
     ];
diff --git a/src/rules/consecutive-blank-lines.ts b/src/rules/consecutive-blank-lines.ts
index 4427f4d..679c48b 100644
--- a/src/rules/consecutive-blank-lines.ts
+++ b/src/rules/consecutive-blank-lines.ts
@@ -9,8 +9,8 @@ class ConsecutiveBlankLinesOptions implements Options {}
 export default class ConsecutiveBlankLines extends RuleBuilder<ConsecutiveBlankLinesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.consecutive-blank-lines.name',
-      descriptionTextKey: 'rules.consecutive-blank-lines.description',
+      nameKey: 'rules.consecutive-blank-lines.name',
+      descriptionKey: 'rules.consecutive-blank-lines.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/convert-bullet-list-markers.ts b/src/rules/convert-bullet-list-markers.ts
index cf7dc9e..08379bd 100644
--- a/src/rules/convert-bullet-list-markers.ts
+++ b/src/rules/convert-bullet-list-markers.ts
@@ -9,8 +9,8 @@ class ConvertBulletListMarkersOptions implements Options {}
 export default class ConvertBulletListMarkers extends RuleBuilder<ConvertBulletListMarkersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.convert-bullet-list-markers.name',
-      descriptionTextKey: 'rules.convert-bullet-list-markers.description',
+      nameKey: 'rules.convert-bullet-list-markers.name',
+      descriptionKey: 'rules.convert-bullet-list-markers.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/convert-spaces-to-tabs.ts b/src/rules/convert-spaces-to-tabs.ts
index 7d25d37..8edfb4c 100644
--- a/src/rules/convert-spaces-to-tabs.ts
+++ b/src/rules/convert-spaces-to-tabs.ts
@@ -11,8 +11,8 @@ class ConvertSpacesToTabsOptions implements Options {
 export default class ConvertSpacesToTabs extends RuleBuilder<ConvertSpacesToTabsOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.convert-spaces-to-tabs.name',
-      descriptionTextKey: 'rules.convert-spaces-to-tabs.description',
+      nameKey: 'rules.convert-spaces-to-tabs.name',
+      descriptionKey: 'rules.convert-spaces-to-tabs.description',
       type: RuleType.SPACING,
     });
   }
@@ -61,8 +61,8 @@ export default class ConvertSpacesToTabs extends RuleBuilder<ConvertSpacesToTabs
     return [
       new NumberOptionBuilder({
         OptionsClass: ConvertSpacesToTabsOptions,
-        nameTextKey: 'rules.convert-spaces-to-tabs.tabsize.name',
-        descriptionTextKey: 'rules.convert-spaces-to-tabs.tabsize.description',
+        nameKey: 'rules.convert-spaces-to-tabs.tabsize.name',
+        descriptionKey: 'rules.convert-spaces-to-tabs.tabsize.description',
         optionsKey: 'tabsize',
       }),
     ];
diff --git a/src/rules/emphasis-style.ts b/src/rules/emphasis-style.ts
index 894674c..f8a7e6f 100644
--- a/src/rules/emphasis-style.ts
+++ b/src/rules/emphasis-style.ts
@@ -14,8 +14,8 @@ class EmphasisStyleOptions implements Options {
 export default class EmphasisStyle extends RuleBuilder<EmphasisStyleOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.emphasis-style.name',
-      descriptionTextKey: 'rules.emphasis-style.description',
+      nameKey: 'rules.emphasis-style.name',
+      descriptionKey: 'rules.emphasis-style.description',
       type: RuleType.CONTENT,
     });
   }
@@ -165,8 +165,8 @@ export default class EmphasisStyle extends RuleBuilder<EmphasisStyleOptions> {
     return [
       new DropdownOptionBuilder<EmphasisStyleOptions, EmphasisStyleValues>({
         OptionsClass: EmphasisStyleOptions,
-        nameTextKey: 'rules.emphasis-style.style.name',
-        descriptionTextKey: 'rules.emphasis-style.style.description',
+        nameKey: 'rules.emphasis-style.style.name',
+        descriptionKey: 'rules.emphasis-style.style.description',
         optionsKey: 'style',
         records: [
           {
diff --git a/src/rules/empty-line-around-blockquotes.ts b/src/rules/empty-line-around-blockquotes.ts
index 70e3b8e..e199f60 100644
--- a/src/rules/empty-line-around-blockquotes.ts
+++ b/src/rules/empty-line-around-blockquotes.ts
@@ -9,8 +9,8 @@ class EmptyLineAroundBlockquotesOptions implements Options {}
 export default class EmptyLineAroundBlockquotes extends RuleBuilder<EmptyLineAroundBlockquotesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.empty-line-around-blockquotes.name',
-      descriptionTextKey: 'rules.empty-line-around-blockquotes.description',
+      nameKey: 'rules.empty-line-around-blockquotes.name',
+      descriptionKey: 'rules.empty-line-around-blockquotes.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/empty-line-around-code-fences.ts b/src/rules/empty-line-around-code-fences.ts
index 885fa28..f49ae50 100644
--- a/src/rules/empty-line-around-code-fences.ts
+++ b/src/rules/empty-line-around-code-fences.ts
@@ -9,8 +9,8 @@ class EmptyLineAroundCodeFencesOptions implements Options {}
 export default class EmptyLineAroundCodeFences extends RuleBuilder<EmptyLineAroundCodeFencesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.empty-line-around-code-fences.name',
-      descriptionTextKey: 'rules.empty-line-around-code-fences.description',
+      nameKey: 'rules.empty-line-around-code-fences.name',
+      descriptionKey: 'rules.empty-line-around-code-fences.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/empty-line-around-math-block.ts b/src/rules/empty-line-around-math-block.ts
index 65f0863..83656dd 100644
--- a/src/rules/empty-line-around-math-block.ts
+++ b/src/rules/empty-line-around-math-block.ts
@@ -13,8 +13,8 @@ class EmptyLineAroundMathBlockOptions implements Options {
 export default class EmptyLineAroundMathBlock extends RuleBuilder<EmptyLineAroundMathBlockOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.empty-line-around-math-blocks.name',
-      descriptionTextKey: 'rules.empty-line-around-math-blocks.description',
+      nameKey: 'rules.empty-line-around-math-blocks.name',
+      descriptionKey: 'rules.empty-line-around-math-blocks.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/empty-line-around-tables.ts b/src/rules/empty-line-around-tables.ts
index 10046f2..cef4e3d 100644
--- a/src/rules/empty-line-around-tables.ts
+++ b/src/rules/empty-line-around-tables.ts
@@ -10,8 +10,8 @@ class EmptyLineAroundTablesOptions implements Options {}
 export default class EmptyLineAroundTables extends RuleBuilder<EmptyLineAroundTablesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.empty-line-around-tables.name',
-      descriptionTextKey: 'rules.empty-line-around-tables.description',
+      nameKey: 'rules.empty-line-around-tables.name',
+      descriptionKey: 'rules.empty-line-around-tables.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/escape-yaml-special-characters.ts b/src/rules/escape-yaml-special-characters.ts
index 3c7c45b..21855a8 100644
--- a/src/rules/escape-yaml-special-characters.ts
+++ b/src/rules/escape-yaml-special-characters.ts
@@ -13,8 +13,8 @@ class EscapeYamlSpecialCharactersOptions implements Options {
 export default class EscapeYamlSpecialCharacters extends RuleBuilder<EscapeYamlSpecialCharactersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.escape-yaml-special-characters.name',
-      descriptionTextKey: 'rules.escape-yaml-special-characters.description',
+      nameKey: 'rules.escape-yaml-special-characters.name',
+      descriptionKey: 'rules.escape-yaml-special-characters.description',
       type: RuleType.YAML,
       hasSpecialExecutionOrder: true,
     });
@@ -199,8 +199,8 @@ export default class EscapeYamlSpecialCharacters extends RuleBuilder<EscapeYamlS
     return [
       new BooleanOptionBuilder({
         OptionsClass: EscapeYamlSpecialCharactersOptions,
-        nameTextKey: 'rules.escape-yaml-special-characters.try-to-escape-single-line-arrays.description',
-        descriptionTextKey: 'rules.escape-yaml-special-characters.try-to-escape-single-line-arrays.name',
+        nameKey: 'rules.escape-yaml-special-characters.try-to-escape-single-line-arrays.description',
+        descriptionKey: 'rules.escape-yaml-special-characters.try-to-escape-single-line-arrays.name',
         optionsKey: 'tryToEscapeSingleLineArrays',
       }),
     ];
diff --git a/src/rules/file-name-heading.ts b/src/rules/file-name-heading.ts
index 81ad261..d3c5ba6 100644
--- a/src/rules/file-name-heading.ts
+++ b/src/rules/file-name-heading.ts
@@ -13,8 +13,8 @@ class FileNameHeadingOptions implements Options {
 export default class FileNameHeading extends RuleBuilder<FileNameHeadingOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.file-name-heading.name',
-      descriptionTextKey: 'rules.file-name-heading.description',
+      nameKey: 'rules.file-name-heading.name',
+      descriptionKey: 'rules.file-name-heading.description',
       type: RuleType.HEADING,
     });
   }
diff --git a/src/rules/footnote-after-punctuation.ts b/src/rules/footnote-after-punctuation.ts
index 2f4de5d..80cbe07 100644
--- a/src/rules/footnote-after-punctuation.ts
+++ b/src/rules/footnote-after-punctuation.ts
@@ -9,8 +9,8 @@ class FootnoteAfterPunctuationOptions implements Options {}
 export default class FootnoteAfterPunctuation extends RuleBuilder<FootnoteAfterPunctuationOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.footnote-after-punctuation.name',
-      descriptionTextKey: 'rules.footnote-after-punctuation.description',
+      nameKey: 'rules.footnote-after-punctuation.name',
+      descriptionKey: 'rules.footnote-after-punctuation.description',
       type: RuleType.FOOTNOTE,
     });
   }
diff --git a/src/rules/force-yaml-escape.ts b/src/rules/force-yaml-escape.ts
index c47d3c0..079ec72 100644
--- a/src/rules/force-yaml-escape.ts
+++ b/src/rules/force-yaml-escape.ts
@@ -13,8 +13,8 @@ class ForceYamlEscapeOptions implements Options {
 export default class ForceYamlEscape extends RuleBuilder<ForceYamlEscapeOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.force-yaml-escape.name',
-      descriptionTextKey: 'rules.force-yaml-escape.description',
+      nameKey: 'rules.force-yaml-escape.name',
+      descriptionKey: 'rules.force-yaml-escape.description',
       type: RuleType.YAML,
       hasSpecialExecutionOrder: true,
     });
@@ -91,8 +91,8 @@ export default class ForceYamlEscape extends RuleBuilder<ForceYamlEscapeOptions>
     return [
       new TextAreaOptionBuilder({
         OptionsClass: ForceYamlEscapeOptions,
-        nameTextKey: 'rules.force-yaml-escape.force-yaml-escape-keys.name',
-        descriptionTextKey: 'rules.force-yaml-escape.force-yaml-escape-keys.description',
+        nameKey: 'rules.force-yaml-escape.force-yaml-escape-keys.name',
+        descriptionKey: 'rules.force-yaml-escape.force-yaml-escape-keys.description',
         optionsKey: 'forceYamlEscape',
       }),
     ];
diff --git a/src/rules/format-tags-in-yaml.ts b/src/rules/format-tags-in-yaml.ts
index dcd5ca6..3d6d17c 100644
--- a/src/rules/format-tags-in-yaml.ts
+++ b/src/rules/format-tags-in-yaml.ts
@@ -9,8 +9,8 @@ class FormatTagsInYamlOptions implements Options {}
 export default class FormatTagsInYaml extends RuleBuilder<FormatTagsInYamlOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.format-tags-in-yaml.name',
-      descriptionTextKey: 'rules.format-tags-in-yaml.description',
+      nameKey: 'rules.format-tags-in-yaml.name',
+      descriptionKey: 'rules.format-tags-in-yaml.description',
       type: RuleType.YAML,
       hasSpecialExecutionOrder: true,
     });
diff --git a/src/rules/format-yaml-arrays.ts b/src/rules/format-yaml-arrays.ts
index 8a40747..3b358c4 100644
--- a/src/rules/format-yaml-arrays.ts
+++ b/src/rules/format-yaml-arrays.ts
@@ -36,8 +36,8 @@ class FormatYamlArrayOptions implements Options {
 export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.format-yaml-array.name',
-      descriptionTextKey: 'rules.format-yaml-array.description',
+      nameKey: 'rules.format-yaml-array.name',
+      descriptionKey: 'rules.format-yaml-array.description',
       type: RuleType.YAML,
     });
   }
@@ -232,20 +232,20 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
     return [
       new BooleanOptionBuilder({
         OptionsClass: FormatYamlArrayOptions,
-        nameTextKey: 'rules.format-yaml-array.alias-key.name',
-        descriptionTextKey: 'rules.format-yaml-array.alias-key.description',
+        nameKey: 'rules.format-yaml-array.alias-key.name',
+        descriptionKey: 'rules.format-yaml-array.alias-key.description',
         optionsKey: 'formatAliasKey',
       }),
       new BooleanOptionBuilder({
         OptionsClass: FormatYamlArrayOptions,
-        nameTextKey: 'rules.format-yaml-array.tag-key.name',
-        descriptionTextKey: 'rules.format-yaml-array.tag-key.description',
+        nameKey: 'rules.format-yaml-array.tag-key.name',
+        descriptionKey: 'rules.format-yaml-array.tag-key.description',
         optionsKey: 'formatTagKey',
       }),
       new DropdownOptionBuilder({
         OptionsClass: FormatYamlArrayOptions,
-        nameTextKey: 'rules.format-yaml-array.default-array-style.name',
-        descriptionTextKey: 'rules.format-yaml-array.default-array-style.description',
+        nameKey: 'rules.format-yaml-array.default-array-style.name',
+        descriptionKey: 'rules.format-yaml-array.default-array-style.description',
         optionsKey: 'defaultArrayStyle',
         records: [
           {
@@ -260,20 +260,20 @@ export default class RuleTemplate extends RuleBuilder<FormatYamlArrayOptions> {
       }),
       new BooleanOptionBuilder({
         OptionsClass: FormatYamlArrayOptions,
-        nameTextKey: 'rules.format-yaml-array.default-array-keys.name',
-        descriptionTextKey: 'rules.format-yaml-array.default-array-keys.description',
+        nameKey: 'rules.format-yaml-array.default-array-keys.name',
+        descriptionKey: 'rules.format-yaml-array.default-array-keys.description',
         optionsKey: 'formatArrayKeys',
       }),
       new TextAreaOptionBuilder({
         OptionsClass: FormatYamlArrayOptions,
-        nameTextKey: 'rules.format-yaml-array.force-single-line-array-style.name',
-        descriptionTextKey: 'rules.format-yaml-array.force-single-line-array-style.description',
+        nameKey: 'rules.format-yaml-array.force-single-line-array-style.name',
+        descriptionKey: 'rules.format-yaml-array.force-single-line-array-style.description',
         optionsKey: 'forceSingleLineArrayStyle',
       }),
       new TextAreaOptionBuilder({
         OptionsClass: FormatYamlArrayOptions,
-        nameTextKey: 'rules.format-yaml-array.force-multi-line-array-style.name',
-        descriptionTextKey: 'rules.format-yaml-array.force-multi-line-array-style.description',
+        nameKey: 'rules.format-yaml-array.force-multi-line-array-style.name',
+        descriptionKey: 'rules.format-yaml-array.force-multi-line-array-style.description',
         optionsKey: 'forceMultiLineArrayStyle',
       }),
     ];
diff --git a/src/rules/header-increment.ts b/src/rules/header-increment.ts
index 67b4928..83ba77c 100644
--- a/src/rules/header-increment.ts
+++ b/src/rules/header-increment.ts
@@ -12,8 +12,8 @@ class HeaderIncrementOptions implements Options {
 export default class HeaderIncrement extends RuleBuilder<HeaderIncrementOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.header-increment.name',
-      descriptionTextKey: 'rules.header-increment.description',
+      nameKey: 'rules.header-increment.name',
+      descriptionKey: 'rules.header-increment.description',
       type: RuleType.HEADING,
     });
   }
@@ -167,8 +167,8 @@ export default class HeaderIncrement extends RuleBuilder<HeaderIncrementOptions>
     return [
       new BooleanOptionBuilder({
         OptionsClass: HeaderIncrementOptions,
-        nameTextKey: 'rules.header-increment.start-at-h2.name',
-        descriptionTextKey: 'rules.header-increment.start-at-h2.description',
+        nameKey: 'rules.header-increment.start-at-h2.name',
+        descriptionKey: 'rules.header-increment.start-at-h2.description',
         optionsKey: 'startAtH2',
       }),
     ];
diff --git a/src/rules/heading-blank-lines.ts b/src/rules/heading-blank-lines.ts
index c04b52e..7fd78ec 100644
--- a/src/rules/heading-blank-lines.ts
+++ b/src/rules/heading-blank-lines.ts
@@ -13,8 +13,8 @@ class HeadingBlankLinesOptions implements Options {
 export default class HeadingBlankLines extends RuleBuilder<HeadingBlankLinesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.heading-blank-lines.name',
-      descriptionTextKey: 'rules.heading-blank-lines.description',
+      nameKey: 'rules.heading-blank-lines.name',
+      descriptionKey: 'rules.heading-blank-lines.description',
       type: RuleType.SPACING,
     });
   }
@@ -120,14 +120,14 @@ export default class HeadingBlankLines extends RuleBuilder<HeadingBlankLinesOpti
     return [
       new BooleanOptionBuilder({
         OptionsClass: HeadingBlankLinesOptions,
-        nameTextKey: 'rules.heading-blank-lines.bottom.name',
-        descriptionTextKey: 'rules.heading-blank-lines.bottom.description',
+        nameKey: 'rules.heading-blank-lines.bottom.name',
+        descriptionKey: 'rules.heading-blank-lines.bottom.description',
         optionsKey: 'bottom',
       }),
       new BooleanOptionBuilder({
         OptionsClass: HeadingBlankLinesOptions,
-        nameTextKey: 'rules.heading-blank-lines.empty-line-after-yaml.name',
-        descriptionTextKey: 'rules.heading-blank-lines.empty-line-after-yaml.description',
+        nameKey: 'rules.heading-blank-lines.empty-line-after-yaml.name',
+        descriptionKey: 'rules.heading-blank-lines.empty-line-after-yaml.description',
         optionsKey: 'emptyLineAfterYaml',
       }),
     ];
diff --git a/src/rules/headings-start-line.ts b/src/rules/headings-start-line.ts
index ba6ef9f..5861ef8 100644
--- a/src/rules/headings-start-line.ts
+++ b/src/rules/headings-start-line.ts
@@ -10,8 +10,8 @@ class HeadingStartLineOptions implements Options {}
 export default class HeadingStartLine extends RuleBuilder<HeadingStartLineOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.headings-start-line.name',
-      descriptionTextKey: 'rules.headings-start-line.description',
+      nameKey: 'rules.headings-start-line.name',
+      descriptionKey: 'rules.headings-start-line.description',
       type: RuleType.HEADING,
     });
   }
diff --git a/src/rules/insert-yaml-attributes.ts b/src/rules/insert-yaml-attributes.ts
index f143d49..582d829 100644
--- a/src/rules/insert-yaml-attributes.ts
+++ b/src/rules/insert-yaml-attributes.ts
@@ -15,8 +15,8 @@ class InsertYamlAttributesOptions implements Options {
 export default class InsertYamlAttributes extends RuleBuilder<InsertYamlAttributesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.insert-yaml-attributes.name',
-      descriptionTextKey: 'rules.insert-yaml-attributes.description',
+      nameKey: 'rules.insert-yaml-attributes.name',
+      descriptionKey: 'rules.insert-yaml-attributes.description',
       type: RuleType.YAML,
     });
   }
@@ -69,8 +69,8 @@ export default class InsertYamlAttributes extends RuleBuilder<InsertYamlAttribut
     return [
       new TextAreaOptionBuilder({
         OptionsClass: InsertYamlAttributesOptions,
-        nameTextKey: 'rules.insert-yaml-attributes.text-to-insert.name',
-        descriptionTextKey: 'rules.insert-yaml-attributes.text-to-insert.description',
+        nameKey: 'rules.insert-yaml-attributes.text-to-insert.name',
+        descriptionKey: 'rules.insert-yaml-attributes.text-to-insert.description',
         optionsKey: 'textToInsert',
       }),
     ];
diff --git a/src/rules/line-break-at-document-end.ts b/src/rules/line-break-at-document-end.ts
index 6714749..4c983b0 100644
--- a/src/rules/line-break-at-document-end.ts
+++ b/src/rules/line-break-at-document-end.ts
@@ -8,8 +8,8 @@ class LineBreakAtDocumentEndOptions implements Options {}
 export default class LineBreakAtDocumentEnd extends RuleBuilder<LineBreakAtDocumentEndOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.line-break-at-document-end.name',
-      descriptionTextKey: 'rules.line-break-at-document-end.description',
+      nameKey: 'rules.line-break-at-document-end.name',
+      descriptionKey: 'rules.line-break-at-document-end.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/move-footnotes-to-the-bottom.ts b/src/rules/move-footnotes-to-the-bottom.ts
index 56d1e02..b3688e8 100644
--- a/src/rules/move-footnotes-to-the-bottom.ts
+++ b/src/rules/move-footnotes-to-the-bottom.ts
@@ -10,8 +10,8 @@ class MoveFootnotesToTheBottomOptions implements Options {}
 export default class MoveFootnotesToTheBottom extends RuleBuilder<MoveFootnotesToTheBottomOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.move-footnotes-to-the-bottom.name',
-      descriptionTextKey: 'rules.move-footnotes-to-the-bottom.description',
+      nameKey: 'rules.move-footnotes-to-the-bottom.name',
+      descriptionKey: 'rules.move-footnotes-to-the-bottom.description',
       type: RuleType.FOOTNOTE,
     });
   }
diff --git a/src/rules/move-math-block-indicators-to-own-line.ts b/src/rules/move-math-block-indicators-to-own-line.ts
index a211174..6485046 100644
--- a/src/rules/move-math-block-indicators-to-own-line.ts
+++ b/src/rules/move-math-block-indicators-to-own-line.ts
@@ -13,8 +13,8 @@ class MoveMathBlockIndicatorsToOwnLineOptions implements Options {
 export default class MoveMathBlockIndicatorsToOwnLine extends RuleBuilder<MoveMathBlockIndicatorsToOwnLineOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.move-math-block-indicators-to-their-own-line.name',
-      descriptionTextKey: 'rules.move-math-block-indicators-to-their-own-line.description',
+      nameKey: 'rules.move-math-block-indicators-to-their-own-line.name',
+      descriptionKey: 'rules.move-math-block-indicators-to-their-own-line.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/move-tags-to-yaml.ts b/src/rules/move-tags-to-yaml.ts
index b608aa2..10fc8eb 100644
--- a/src/rules/move-tags-to-yaml.ts
+++ b/src/rules/move-tags-to-yaml.ts
@@ -35,8 +35,8 @@ class MoveTagsToYamlOptions implements Options {
 export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.move-tags-to-yaml.name',
-      descriptionTextKey: 'rules.move-tags-to-yaml.description',
+      nameKey: 'rules.move-tags-to-yaml.name',
+      descriptionKey: 'rules.move-tags-to-yaml.description',
       type: RuleType.YAML,
     });
   }
@@ -215,8 +215,8 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
     return [
       new DropdownOptionBuilder({
         OptionsClass: MoveTagsToYamlOptions,
-        nameTextKey: 'rules.move-tags-to-yaml.how-to-handle-existing-tags.name',
-        descriptionTextKey: 'rules.move-tags-to-yaml.how-to-handle-existing-tags.description',
+        nameKey: 'rules.move-tags-to-yaml.how-to-handle-existing-tags.name',
+        descriptionKey: 'rules.move-tags-to-yaml.how-to-handle-existing-tags.description',
         optionsKey: 'howToHandleExistingTags',
         records: [
           {
@@ -235,8 +235,8 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
       }),
       new TextAreaOptionBuilder({
         OptionsClass: MoveTagsToYamlOptions,
-        nameTextKey: 'rules.move-tags-to-yaml.tags-to-ignore.name',
-        descriptionTextKey: 'rules.move-tags-to-yaml.tags-to-ignore.description',
+        nameKey: 'rules.move-tags-to-yaml.tags-to-ignore.name',
+        descriptionKey: 'rules.move-tags-to-yaml.tags-to-ignore.description',
         optionsKey: 'tagsToIgnore',
       }),
     ];
diff --git a/src/rules/no-bare-urls.ts b/src/rules/no-bare-urls.ts
index 8a2326d..949ed36 100644
--- a/src/rules/no-bare-urls.ts
+++ b/src/rules/no-bare-urls.ts
@@ -13,8 +13,8 @@ const specialCharsToNotEscapeContentsWithin = `'"‘’“”\`[]`;
 export default class NoBareUrls extends RuleBuilder<NoBareUrlsOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.no-bare-urls.name',
-      descriptionTextKey: 'rules.no-bare-urls.description',
+      nameKey: 'rules.no-bare-urls.name',
+      descriptionKey: 'rules.no-bare-urls.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/ordered-list-style.ts b/src/rules/ordered-list-style.ts
index a532c3c..0af5480 100644
--- a/src/rules/ordered-list-style.ts
+++ b/src/rules/ordered-list-style.ts
@@ -13,8 +13,8 @@ class OrderedListStyleOptions implements Options {
 export default class OrderedListStyle extends RuleBuilder<OrderedListStyleOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.ordered-list-style.name',
-      descriptionTextKey: 'rules.unordered-list-style.description',
+      nameKey: 'rules.ordered-list-style.name',
+      descriptionKey: 'rules.unordered-list-style.description',
       type: RuleType.CONTENT,
     });
   }
@@ -138,8 +138,8 @@ export default class OrderedListStyle extends RuleBuilder<OrderedListStyleOption
     return [
       new DropdownOptionBuilder<OrderedListStyleOptions, OrderListItemStyles>({
         OptionsClass: OrderedListStyleOptions,
-        nameTextKey: 'rules.ordered-list-style.number-style.name',
-        descriptionTextKey: 'rules.ordered-list-style.number-style.description',
+        nameKey: 'rules.ordered-list-style.number-style.name',
+        descriptionKey: 'rules.ordered-list-style.number-style.description',
         optionsKey: 'numberStyle',
         records: [
           {
@@ -154,8 +154,8 @@ export default class OrderedListStyle extends RuleBuilder<OrderedListStyleOption
       }),
       new DropdownOptionBuilder<OrderedListStyleOptions, OrderListItemEndOfIndicatorStyles>({
         OptionsClass: OrderedListStyleOptions,
-        nameTextKey: 'rules.ordered-list-style.list-end-style.name',
-        descriptionTextKey: 'rules.ordered-list-style.list-end-style.description',
+        nameKey: 'rules.ordered-list-style.list-end-style.name',
+        descriptionKey: 'rules.ordered-list-style.list-end-style.description',
         optionsKey: 'listEndStyle',
         records: [
           {
diff --git a/src/rules/paragraph-blank-lines.ts b/src/rules/paragraph-blank-lines.ts
index 61909f5..a003a9f 100644
--- a/src/rules/paragraph-blank-lines.ts
+++ b/src/rules/paragraph-blank-lines.ts
@@ -10,8 +10,8 @@ class ParagraphBlankLinesOptions implements Options {}
 export default class ParagraphBlankLines extends RuleBuilder<ParagraphBlankLinesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.paragraph-blank-lines.name',
-      descriptionTextKey: 'rules.paragraph-blank-lines.description',
+      nameKey: 'rules.paragraph-blank-lines.name',
+      descriptionKey: 'rules.paragraph-blank-lines.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/prevent-double-checklist-indicator-on-paste.ts b/src/rules/prevent-double-checklist-indicator-on-paste.ts
index 02b2d0a..a3d6a94 100644
--- a/src/rules/prevent-double-checklist-indicator-on-paste.ts
+++ b/src/rules/prevent-double-checklist-indicator-on-paste.ts
@@ -13,8 +13,8 @@ class PreventDoubleChecklistIndicatorOnPasteOptions implements Options {
 export default class PreventDoubleChecklistIndicatorOnPaste extends RuleBuilder<PreventDoubleChecklistIndicatorOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.prevent-double-checklist-indicator-on-paste.name',
-      descriptionTextKey: 'rules.prevent-double-checklist-indicator-on-paste.description',
+      nameKey: 'rules.prevent-double-checklist-indicator-on-paste.name',
+      descriptionKey: 'rules.prevent-double-checklist-indicator-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/prevent-double-list-item-indicator-on-paste.ts b/src/rules/prevent-double-list-item-indicator-on-paste.ts
index f368df4..a5e397e 100644
--- a/src/rules/prevent-double-list-item-indicator-on-paste.ts
+++ b/src/rules/prevent-double-list-item-indicator-on-paste.ts
@@ -13,8 +13,8 @@ class PreventDoubleListItemIndicatorOnPasteOptions implements Options {
 export default class PreventDoubleListItemIndicatorOnPaste extends RuleBuilder<PreventDoubleListItemIndicatorOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.prevent-double-list-item-indicator-on-paste.name',
-      descriptionTextKey: 'rules.prevent-double-list-item-indicator-on-paste.description',
+      nameKey: 'rules.prevent-double-list-item-indicator-on-paste.name',
+      descriptionKey: 'rules.prevent-double-list-item-indicator-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/proper-ellipsis-on-paste.ts b/src/rules/proper-ellipsis-on-paste.ts
index 23b3e71..04a1d14 100644
--- a/src/rules/proper-ellipsis-on-paste.ts
+++ b/src/rules/proper-ellipsis-on-paste.ts
@@ -10,8 +10,8 @@ class ProperEllipsisOnPasteOptions implements Options {}
 export default class ProperEllipsisOnPaste extends RuleBuilder<ProperEllipsisOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.proper-ellipsis-on-paste.name',
-      descriptionTextKey: 'rules.proper-ellipsis-on-paste.description',
+      nameKey: 'rules.proper-ellipsis-on-paste.name',
+      descriptionKey: 'rules.proper-ellipsis-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/proper-ellipsis.ts b/src/rules/proper-ellipsis.ts
index f2a9b0a..2c94831 100644
--- a/src/rules/proper-ellipsis.ts
+++ b/src/rules/proper-ellipsis.ts
@@ -10,8 +10,8 @@ class ProperEllipsisOptions implements Options {}
 export default class ProperEllipsis extends RuleBuilder<ProperEllipsisOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.proper-ellipsis.name',
-      descriptionTextKey: 'rules.proper-ellipsis.description',
+      nameKey: 'rules.proper-ellipsis.name',
+      descriptionKey: 'rules.proper-ellipsis.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/re-index-footnotes.ts b/src/rules/re-index-footnotes.ts
index 93732bc..59a0351 100644
--- a/src/rules/re-index-footnotes.ts
+++ b/src/rules/re-index-footnotes.ts
@@ -9,8 +9,8 @@ class ReIndexFootnotesOptions implements Options {}
 export default class ReIndexFootnotes extends RuleBuilder<ReIndexFootnotesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.re-index-footnotes.name',
-      descriptionTextKey: 'rules.re-index-footnotes.description',
+      nameKey: 'rules.re-index-footnotes.name',
+      descriptionKey: 'rules.re-index-footnotes.description',
       type: RuleType.FOOTNOTE,
     });
   }
diff --git a/src/rules/remove-consecutive-list-markers.ts b/src/rules/remove-consecutive-list-markers.ts
index c295e28..15a995d 100644
--- a/src/rules/remove-consecutive-list-markers.ts
+++ b/src/rules/remove-consecutive-list-markers.ts
@@ -9,8 +9,8 @@ class RemoveConsecutiveListMarkersOptions implements Options {}
 export default class RemoveConsecutiveListMarkers extends RuleBuilder<RemoveConsecutiveListMarkersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-consecutive-list-markers.name',
-      descriptionTextKey: 'rules.remove-consecutive-list-markers.description',
+      nameKey: 'rules.remove-consecutive-list-markers.name',
+      descriptionKey: 'rules.remove-consecutive-list-markers.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/remove-empty-lines-between-list-markers-and-checklists.ts b/src/rules/remove-empty-lines-between-list-markers-and-checklists.ts
index f00c97a..10e1caf 100644
--- a/src/rules/remove-empty-lines-between-list-markers-and-checklists.ts
+++ b/src/rules/remove-empty-lines-between-list-markers-and-checklists.ts
@@ -9,8 +9,8 @@ class RemoveEmptyLinesBetweenListMarkersAndChecklistsOptions implements Options
 export default class RemoveEmptyLinesBetweenListMarkersAndChecklists extends RuleBuilder<RemoveEmptyLinesBetweenListMarkersAndChecklistsOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-empty-lines-between-list-markers-and-checklists.name',
-      descriptionTextKey: 'rules.remove-empty-lines-between-list-markers-and-checklists.description',
+      nameKey: 'rules.remove-empty-lines-between-list-markers-and-checklists.name',
+      descriptionKey: 'rules.remove-empty-lines-between-list-markers-and-checklists.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/remove-empty-list-markers.ts b/src/rules/remove-empty-list-markers.ts
index 5be3970..a77ff72 100644
--- a/src/rules/remove-empty-list-markers.ts
+++ b/src/rules/remove-empty-list-markers.ts
@@ -10,8 +10,8 @@ class RemoveEmptyListMarkersOptions implements Options {}
 export default class RemoveEmptyListMarkers extends RuleBuilder<RemoveEmptyListMarkersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-empty-list-markers.name',
-      descriptionTextKey: 'rules.remove-empty-list-markers.description',
+      nameKey: 'rules.remove-empty-list-markers.name',
+      descriptionKey: 'rules.remove-empty-list-markers.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/remove-hyphenated-line-breaks.ts b/src/rules/remove-hyphenated-line-breaks.ts
index 09a9175..137b5f9 100644
--- a/src/rules/remove-hyphenated-line-breaks.ts
+++ b/src/rules/remove-hyphenated-line-breaks.ts
@@ -9,8 +9,8 @@ class RemoveHyphenatedLineBreaksOptions implements Options {}
 export default class RemoveHyphenatedLineBreaks extends RuleBuilder<RemoveHyphenatedLineBreaksOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-hyphenated-line-breaks.name',
-      descriptionTextKey: 'rules.remove-hyphenated-line-breaks.description',
+      nameKey: 'rules.remove-hyphenated-line-breaks.name',
+      descriptionKey: 'rules.remove-hyphenated-line-breaks.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/remove-hyphens-on-paste.ts b/src/rules/remove-hyphens-on-paste.ts
index 9bb38b9..970af20 100644
--- a/src/rules/remove-hyphens-on-paste.ts
+++ b/src/rules/remove-hyphens-on-paste.ts
@@ -9,8 +9,8 @@ class RemoveHyphensOnPasteOptions implements Options {}
 export default class RemoveHyphensOnPaste extends RuleBuilder<RemoveHyphensOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-hyphens-on-paste.name',
-      descriptionTextKey: 'rules.remove-hyphens-on-paste.description',
+      nameKey: 'rules.remove-hyphens-on-paste.name',
+      descriptionKey: 'rules.remove-hyphens-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/remove-leading-or-trailing-whitespace-on-paste.ts b/src/rules/remove-leading-or-trailing-whitespace-on-paste.ts
index 7efcbfe..e00b964 100644
--- a/src/rules/remove-leading-or-trailing-whitespace-on-paste.ts
+++ b/src/rules/remove-leading-or-trailing-whitespace-on-paste.ts
@@ -9,8 +9,8 @@ class RemoveLeadingOrTrailingWhitespaceOnPasteOptions implements Options {}
 export default class RemoveLeadingOrTrailingWhitespaceOnPaste extends RuleBuilder<RemoveLeadingOrTrailingWhitespaceOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-leading-or-trailing-whitespace-on-paste.name',
-      descriptionTextKey: 'rules.remove-leading-or-trailing-whitespace-on-paste.description',
+      nameKey: 'rules.remove-leading-or-trailing-whitespace-on-paste.name',
+      descriptionKey: 'rules.remove-leading-or-trailing-whitespace-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/remove-leftover-footnotes-from-quote-on-paste.ts b/src/rules/remove-leftover-footnotes-from-quote-on-paste.ts
index efd3bc6..6d1ec3f 100644
--- a/src/rules/remove-leftover-footnotes-from-quote-on-paste.ts
+++ b/src/rules/remove-leftover-footnotes-from-quote-on-paste.ts
@@ -9,8 +9,8 @@ class RemoveLeftoverFootnotesFromQuoteOnPasteOptions implements Options {}
 export default class RemoveLeftoverFootnotesFromQuoteOnPaste extends RuleBuilder<RemoveLeftoverFootnotesFromQuoteOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-leftover-footnotes-from-quote-on-paste.name',
-      descriptionTextKey: 'rules.remove-leftover-footnotes-from-quote-on-paste.description',
+      nameKey: 'rules.remove-leftover-footnotes-from-quote-on-paste.name',
+      descriptionKey: 'rules.remove-leftover-footnotes-from-quote-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/remove-link-spacing.ts b/src/rules/remove-link-spacing.ts
index a6dcb75..1fc112e 100644
--- a/src/rules/remove-link-spacing.ts
+++ b/src/rules/remove-link-spacing.ts
@@ -10,8 +10,8 @@ class RemoveLinkSpacingOptions implements Options {}
 export default class RemoveLinkSpacing extends RuleBuilder<RemoveLinkSpacingOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-link-spacing.name',
-      descriptionTextKey: 'rules.remove-link-spacing.description',
+      nameKey: 'rules.remove-link-spacing.name',
+      descriptionKey: 'rules.remove-link-spacing.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/remove-multiple-blank-lines-on-paste.ts b/src/rules/remove-multiple-blank-lines-on-paste.ts
index 42e1f5c..b2f8cf4 100644
--- a/src/rules/remove-multiple-blank-lines-on-paste.ts
+++ b/src/rules/remove-multiple-blank-lines-on-paste.ts
@@ -9,8 +9,8 @@ class RemoveMultipleBlankLinesOnPasteOptions implements Options {}
 export default class RemoveMultipleBlankLinesOnPaste extends RuleBuilder<RemoveMultipleBlankLinesOnPasteOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-multiple-blank-lines-on-paste.name',
-      descriptionTextKey: 'rules.remove-multiple-blank-lines-on-paste.description',
+      nameKey: 'rules.remove-multiple-blank-lines-on-paste.name',
+      descriptionKey: 'rules.remove-multiple-blank-lines-on-paste.description',
       type: RuleType.PASTE,
     });
   }
diff --git a/src/rules/remove-multiple-spaces.ts b/src/rules/remove-multiple-spaces.ts
index 9e4db67..9c41f42 100644
--- a/src/rules/remove-multiple-spaces.ts
+++ b/src/rules/remove-multiple-spaces.ts
@@ -9,8 +9,8 @@ class RemoveMultipleSpacesOptions implements Options {}
 export default class RemoveMultipleSpaces extends RuleBuilder<RemoveMultipleSpacesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-multiple-spaces.name',
-      descriptionTextKey: 'rules.remove-multiple-spaces.description',
+      nameKey: 'rules.remove-multiple-spaces.name',
+      descriptionKey: 'rules.remove-multiple-spaces.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/remove-space-around-characters.ts b/src/rules/remove-space-around-characters.ts
index e65fdd3..87b0657 100644
--- a/src/rules/remove-space-around-characters.ts
+++ b/src/rules/remove-space-around-characters.ts
@@ -16,8 +16,8 @@ class RemoveSpaceAroundCharactersOptions implements Options {
 export default class RemoveSpaceAroundCharacters extends RuleBuilder<RemoveSpaceAroundCharactersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-space-around-characters.name',
-      descriptionTextKey: 'rules.remove-space-around-characters.description',
+      nameKey: 'rules.remove-space-around-characters.name',
+      descriptionKey: 'rules.remove-space-around-characters.description',
       type: RuleType.SPACING,
     });
   }
@@ -137,26 +137,26 @@ export default class RemoveSpaceAroundCharacters extends RuleBuilder<RemoveSpace
   get optionBuilders(): OptionBuilderBase<RemoveSpaceAroundCharactersOptions>[] {
     return [
       new BooleanOptionBuilder({
-        nameTextKey: 'rules.remove-space-around-characters.include-fullwidth-forms.name',
-        descriptionTextKey: 'rules.remove-space-around-characters.include-fullwidth-forms.description',
+        nameKey: 'rules.remove-space-around-characters.include-fullwidth-forms.name',
+        descriptionKey: 'rules.remove-space-around-characters.include-fullwidth-forms.description',
         OptionsClass: RemoveSpaceAroundCharactersOptions,
         optionsKey: 'includeFullwidthForms',
       }),
       new BooleanOptionBuilder({
-        nameTextKey: 'rules.remove-space-around-characters.include-cjk-symbols-and-punctuation.name',
-        descriptionTextKey: 'rules.remove-space-around-characters.include-cjk-symbols-and-punctuation.description',
+        nameKey: 'rules.remove-space-around-characters.include-cjk-symbols-and-punctuation.name',
+        descriptionKey: 'rules.remove-space-around-characters.include-cjk-symbols-and-punctuation.description',
         OptionsClass: RemoveSpaceAroundCharactersOptions,
         optionsKey: 'includeCJKSymbolsAndPunctuation',
       }),
       new BooleanOptionBuilder({
-        nameTextKey: 'rules.remove-space-around-characters.include-dashes.name',
-        descriptionTextKey: 'rules.remove-space-around-characters.include-dashes.description',
+        nameKey: 'rules.remove-space-around-characters.include-dashes.name',
+        descriptionKey: 'rules.remove-space-around-characters.include-dashes.description',
         OptionsClass: RemoveSpaceAroundCharactersOptions,
         optionsKey: 'includeDashes',
       }),
       new TextOptionBuilder({
-        nameTextKey: 'rules.remove-space-around-characters.other-symbols.name',
-        descriptionTextKey: 'rules.remove-space-around-characters.other-symbols.description',
+        nameKey: 'rules.remove-space-around-characters.other-symbols.name',
+        descriptionKey: 'rules.remove-space-around-characters.other-symbols.description',
         OptionsClass: RemoveSpaceAroundCharactersOptions,
         optionsKey: 'otherSymbols',
       }),
diff --git a/src/rules/remove-trailing-punctuation-in-heading.ts b/src/rules/remove-trailing-punctuation-in-heading.ts
index 3763131..85188f5 100644
--- a/src/rules/remove-trailing-punctuation-in-heading.ts
+++ b/src/rules/remove-trailing-punctuation-in-heading.ts
@@ -12,8 +12,8 @@ class RemoveTrailingPunctuationInHeadingOptions implements Options {
 export default class RemoveTrailingPunctuationInHeading extends RuleBuilder<RemoveTrailingPunctuationInHeadingOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-trailing-punctuation-in-heading.name',
-      descriptionTextKey: 'rules.remove-trailing-punctuation-in-heading.description',
+      nameKey: 'rules.remove-trailing-punctuation-in-heading.name',
+      descriptionKey: 'rules.remove-trailing-punctuation-in-heading.description',
       type: RuleType.HEADING,
     });
   }
@@ -69,8 +69,8 @@ export default class RemoveTrailingPunctuationInHeading extends RuleBuilder<Remo
     return [
       new TextOptionBuilder({
         OptionsClass: RemoveTrailingPunctuationInHeadingOptions,
-        nameTextKey: 'rules.remove-trailing-punctuation-in-heading.punctuation-to-remove.name',
-        descriptionTextKey: 'rules.remove-trailing-punctuation-in-heading.punctuation-to-remove.description',
+        nameKey: 'rules.remove-trailing-punctuation-in-heading.punctuation-to-remove.name',
+        descriptionKey: 'rules.remove-trailing-punctuation-in-heading.punctuation-to-remove.description',
         optionsKey: 'punctuationToRemove',
       }),
     ];
diff --git a/src/rules/remove-yaml-keys.ts b/src/rules/remove-yaml-keys.ts
index bceb422..88b0775 100644
--- a/src/rules/remove-yaml-keys.ts
+++ b/src/rules/remove-yaml-keys.ts
@@ -12,8 +12,8 @@ class RemoveYamlKeysOptions implements Options {
 export default class RemoveYamlKeys extends RuleBuilder<RemoveYamlKeysOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.remove-yaml-keys.name',
-      descriptionTextKey: 'rules.remove-yaml-keys.description',
+      nameKey: 'rules.remove-yaml-keys.name',
+      descriptionKey: 'rules.remove-yaml-keys.description',
       type: RuleType.YAML,
     });
   }
@@ -83,8 +83,8 @@ export default class RemoveYamlKeys extends RuleBuilder<RemoveYamlKeysOptions> {
     return [
       new TextAreaOptionBuilder({
         OptionsClass: RemoveYamlKeysOptions,
-        nameTextKey: 'rules.remove-yaml-keys.yaml-keys-to-remove.name',
-        descriptionTextKey: 'rules.remove-yaml-keys.yaml-keys-to-remove.description',
+        nameKey: 'rules.remove-yaml-keys.yaml-keys-to-remove.name',
+        descriptionKey: 'rules.remove-yaml-keys.yaml-keys-to-remove.description',
         optionsKey: 'yamlKeysToRemove',
       }),
     ];
diff --git a/src/rules/rule-builder.ts b/src/rules/rule-builder.ts
index 0fa0b86..62b9fdf 100644
--- a/src/rules/rule-builder.ts
+++ b/src/rules/rule-builder.ts
@@ -11,9 +11,9 @@ export abstract class RuleBuilderBase {
   static getRule<TOptions extends Options>(this: (new() => RuleBuilder<TOptions>)): Rule {
     if (!RuleBuilderBase.#ruleMap.has(this.name)) {
       const builder = new this();
-      const rule = new Rule(builder.name, builder.description, builder.configKey, builder.type, builder.safeApply.bind(builder), builder.exampleBuilders.map((b) => b.example), builder.optionBuilders.map((b) => b.option), builder.hasSpecialExecutionOrder);
+      const rule = new Rule(builder.nameKey, builder.descriptionKey, builder.settingsKey, builder.alias, builder.type, builder.safeApply.bind(builder), builder.exampleBuilders.map((b) => b.example), builder.optionBuilders.map((b) => b.option), builder.hasSpecialExecutionOrder);
       RuleBuilderBase.#ruleMap.set(this.name, rule);
-      RuleBuilderBase.#ruleBuilderMap.set(builder.name, builder);
+      RuleBuilderBase.#ruleBuilderMap.set(builder.alias, builder);
     }
 
     return RuleBuilderBase.#ruleMap.get(this.name);
@@ -23,12 +23,12 @@ export abstract class RuleBuilderBase {
     const optionsFromSettings = rule.getOptions(settings);
     if (optionsFromSettings[rule.enabledOptionName()]) {
       const options = Object.assign({}, optionsFromSettings, extraOptions) as Options;
-      logDebug(`${getTextInLanguage('logs.run-rule-text')} ${rule.name}`);
+      logDebug(`${getTextInLanguage('logs.run-rule-text')} ${rule.getName()}`);
 
       try {
         return [rule.apply(text, options), true];
       } catch (error) {
-        wrapLintError(error, rule.name);
+        wrapLintError(error, rule.getName());
       }
     } else {
       return [text, false];
@@ -52,29 +52,27 @@ export abstract class RuleBuilderBase {
 }
 
 type RuleBuilderConstructorArgs = {
-  nameTextKey: LanguageStringKey
-  descriptionTextKey: LanguageStringKey,
+  nameKey: LanguageStringKey
+  descriptionKey: LanguageStringKey,
   type: RuleType;
   hasSpecialExecutionOrder?: boolean
 };
 
 export default abstract class RuleBuilder<TOptions extends Options> extends RuleBuilderBase {
-  public configKey: string;
-  public name: string;
-  public description: string;
-  public nameTextKey: LanguageStringKey;
-  public descriptionTextKey: LanguageStringKey;
+  public settingsKey: string;
+  public alias: string;
+  public nameKey: LanguageStringKey;
+  public descriptionKey: LanguageStringKey;
   public type: RuleType;
   public hasSpecialExecutionOrder: boolean;
   constructor(args: RuleBuilderConstructorArgs) {
     super();
 
-    this.configKey = args.nameTextKey.replace(/rules\.(.*)\.name/, '$1');
-    this.nameTextKey = args.nameTextKey;
-    this.descriptionTextKey = args.descriptionTextKey;
+    this.alias = args.nameKey.replace(/rules\.(.*)\.name/, '$1');
+    this.settingsKey = args.nameKey.replace(/(rules\..*)\.name/, '$1');
+    this.nameKey = args.nameKey;
+    this.descriptionKey = args.descriptionKey;
     this.type = args.type;
-    this.name = getTextInLanguage(args.nameTextKey);
-    this.description = getTextInLanguage(args.descriptionTextKey);
     this.hasSpecialExecutionOrder = args.hasSpecialExecutionOrder ?? false;
   }
 
@@ -152,8 +150,8 @@ type KeysOfObjectMatchingPropertyValueType<TObject, TValue> = {[TKey in keyof TO
 
 type OptionBuilderConstructorArgs<TOptions extends Options, TValue> = {
   OptionsClass: (new() => TOptions),
-  nameTextKey: LanguageStringKey
-  descriptionTextKey: LanguageStringKey,
+  nameKey: LanguageStringKey
+  descriptionKey: LanguageStringKey,
   optionsKey: KeysOfObjectMatchingPropertyValueType<TOptions, TValue>;
 };
 
@@ -165,27 +163,23 @@ export abstract class OptionBuilderBase<TOptions extends Options> {
 export abstract class OptionBuilder<TOptions extends Options, TValue> {
   readonly OptionsClass: (new() => TOptions);
   readonly configKey: string;
-  readonly name: string;
-  readonly description: string;
-  readonly nameTextKey: LanguageStringKey;
-  readonly descriptionTextKey: LanguageStringKey;
+  readonly nameKey: LanguageStringKey;
+  readonly descriptionKey: LanguageStringKey;
   readonly optionsKey: KeysOfObjectMatchingPropertyValueType<TOptions, TValue>;
   #option: Option;
 
   constructor(args: OptionBuilderConstructorArgs<TOptions, TValue>) {
     this.OptionsClass = args.OptionsClass;
 
-    const keyParts = args.nameTextKey.split('.');
+    const keyParts = args.nameKey.split('.');
     if (keyParts.length == 1) {
       this.configKey = keyParts[0];
     } else {
       this.configKey = keyParts[keyParts.length - 2];
     }
 
-    this.name = getTextInLanguage(args.nameTextKey);
-    this.description = getTextInLanguage(args.descriptionTextKey);
-    this.nameTextKey = args.nameTextKey;
-    this.descriptionTextKey = args.descriptionTextKey;
+    this.nameKey = args.nameKey;
+    this.descriptionKey = args.descriptionKey;
     this.optionsKey = args.optionsKey;
   }
 
@@ -203,7 +197,7 @@ export abstract class OptionBuilder<TOptions extends Options, TValue> {
 
   setRuleOption(ruleOptions: TOptions, options: Options) {
     // `as TValue` is not enough because of the https://github.com/microsoft/TypeScript/issues/48992
-    const optionValue = options[this.name] as TOptions[KeysOfObjectMatchingPropertyValueType<TOptions, TValue>];
+    const optionValue = options[this.configKey] as TOptions[KeysOfObjectMatchingPropertyValueType<TOptions, TValue>];
     if (optionValue !== undefined) {
       ruleOptions[this.optionsKey] = optionValue;
     }
@@ -214,13 +208,13 @@ export abstract class OptionBuilder<TOptions extends Options, TValue> {
 
 export class BooleanOptionBuilder<TOptions extends Options> extends OptionBuilder<TOptions, boolean> {
   protected buildOption(): Option {
-    return new BooleanOption(this.configKey, this.name, this.description, this.defaultValue);
+    return new BooleanOption(this.configKey, this.nameKey, this.descriptionKey, this.defaultValue);
   }
 }
 
 export class NumberOptionBuilder<TOptions extends Options> extends OptionBuilder<TOptions, Number> {
   protected buildOption(): Option {
-    return new TextOption(this.configKey, this.name, this.description, this.defaultValue);
+    return new TextOption(this.configKey, this.nameKey, this.descriptionKey, this.defaultValue);
   }
 }
 
@@ -238,7 +232,7 @@ export class DropdownOptionBuilder<TOptions extends Options, TValue extends stri
   }
 
   protected buildOption(): Option {
-    return new DropdownOption(this.configKey, this.name, this.description, this.defaultValue, this.records);
+    return new DropdownOption(this.configKey, this.nameKey, this.descriptionKey, this.defaultValue, this.records);
   }
 }
 
@@ -256,14 +250,14 @@ export class TextAreaOptionBuilder<TOptions extends Options> extends OptionBuild
 
 
   protected buildOption(): Option {
-    return new TextAreaOption(this.configKey, this.name, this.description, this.defaultValue.join(this.separator));
+    return new TextAreaOption(this.configKey, this.nameKey, this.descriptionKey, this.defaultValue.join(this.separator));
   }
 
   setRuleOption(ruleOptions: TOptions, options: Options) {
-    if (options[this.name] !== undefined) {
+    if (options[this.configKey] !== undefined) {
       // `as string[]` is not enough because of the https://github.com/microsoft/TypeScript/issues/48992
       // make sure to remove any empty strings as well as they are not valid values
-      const optionValue = ((options[this.name] as string).split(this.splitter) as TOptions[KeysOfObjectMatchingPropertyValueType<TOptions, string[]>]).filter(function(el: string) {
+      const optionValue = ((options[this.configKey] as string).split(this.splitter) as TOptions[KeysOfObjectMatchingPropertyValueType<TOptions, string[]>]).filter(function(el: string) {
         return el != '';
       });
       ruleOptions[this.optionsKey] = optionValue;
@@ -273,12 +267,12 @@ export class TextAreaOptionBuilder<TOptions extends Options> extends OptionBuild
 
 export class TextOptionBuilder<TOptions extends Options> extends OptionBuilder<TOptions, string> {
   protected buildOption(): Option {
-    return new TextOption(this.configKey, this.name, this.description, this.defaultValue);
+    return new TextOption(this.configKey, this.nameKey, this.descriptionKey, this.defaultValue);
   }
 }
 
 export class MomentFormatOptionBuilder<TOptions extends Options> extends OptionBuilder<TOptions, string> {
   protected buildOption(): Option {
-    return new MomentFormatOption(this.configKey, this.name, this.description, this.defaultValue);
+    return new MomentFormatOption(this.configKey, this.nameKey, this.descriptionKey, this.defaultValue);
   }
 }
diff --git a/src/rules/space-after-list-markers.ts b/src/rules/space-after-list-markers.ts
index 1c31cde..0a72ced 100644
--- a/src/rules/space-after-list-markers.ts
+++ b/src/rules/space-after-list-markers.ts
@@ -9,8 +9,8 @@ class SpaceAfterListMarkersOptions implements Options {}
 export default class SpaceAfterListMarkers extends RuleBuilder<SpaceAfterListMarkersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.space-after-list-markers.name',
-      descriptionTextKey: 'rules.space-after-list-markers.description',
+      nameKey: 'rules.space-after-list-markers.name',
+      descriptionKey: 'rules.space-after-list-markers.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts b/src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts
index f2d1024..f319e10 100644
--- a/src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts
+++ b/src/rules/space-between-chinese-japanese-or-korean-and-english-or-numbers.ts
@@ -10,8 +10,8 @@ class SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions implements O
 export default class SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbers extends RuleBuilder<SpaceBetweenChineseJapaneseOrKoreanAndEnglishOrNumbersOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.space-between-chinese-japanese-or-korean-and-english-or-numbers.name',
-      descriptionTextKey: 'rules.space-between-chinese-japanese-or-korean-and-english-or-numbers.description',
+      nameKey: 'rules.space-between-chinese-japanese-or-korean-and-english-or-numbers.name',
+      descriptionKey: 'rules.space-between-chinese-japanese-or-korean-and-english-or-numbers.description',
       type: RuleType.SPACING,
     });
   }
diff --git a/src/rules/strong-style.ts b/src/rules/strong-style.ts
index 6631f58..79fac65 100644
--- a/src/rules/strong-style.ts
+++ b/src/rules/strong-style.ts
@@ -14,8 +14,8 @@ class StrongStyleOptions implements Options {
 export default class StrongStyle extends RuleBuilder<StrongStyleOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.strong-style.name',
-      descriptionTextKey: 'rules.strong-style.description',
+      nameKey: 'rules.strong-style.name',
+      descriptionKey: 'rules.strong-style.description',
       type: RuleType.CONTENT,
     });
   }
@@ -165,8 +165,8 @@ export default class StrongStyle extends RuleBuilder<StrongStyleOptions> {
     return [
       new DropdownOptionBuilder<StrongStyleOptions, StrongStyleValues>({
         OptionsClass: StrongStyleOptions,
-        nameTextKey: 'rules.strong-style.style.name',
-        descriptionTextKey: 'rules.strong-style.style.description',
+        nameKey: 'rules.strong-style.style.name',
+        descriptionKey: 'rules.strong-style.style.description',
         optionsKey: 'style',
         records: [
           {
diff --git a/src/rules/trailing-spaces.ts b/src/rules/trailing-spaces.ts
index 588342e..8a09f36 100644
--- a/src/rules/trailing-spaces.ts
+++ b/src/rules/trailing-spaces.ts
@@ -11,8 +11,8 @@ class TrailingSpacesOptions implements Options {
 export default class TrailingSpaces extends RuleBuilder<TrailingSpacesOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.trailing-spaces.name',
-      descriptionTextKey: 'rules.trailing-spaces.description',
+      nameKey: 'rules.trailing-spaces.name',
+      descriptionKey: 'rules.trailing-spaces.description',
       type: RuleType.SPACING,
     });
   }
@@ -66,8 +66,8 @@ export default class TrailingSpaces extends RuleBuilder<TrailingSpacesOptions> {
     return [
       new BooleanOptionBuilder({
         OptionsClass: TrailingSpacesOptions,
-        nameTextKey: 'rules.trailing-spaces.twp-space-line-break.name',
-        descriptionTextKey: 'rules.trailing-spaces.twp-space-line-break.description',
+        nameKey: 'rules.trailing-spaces.twp-space-line-break.name',
+        descriptionKey: 'rules.trailing-spaces.twp-space-line-break.description',
         optionsKey: 'twoSpaceLineBreak',
       }),
     ];
diff --git a/src/rules/two-spaces-between-lines-with-content.ts b/src/rules/two-spaces-between-lines-with-content.ts
index e3b159c..706a98d 100644
--- a/src/rules/two-spaces-between-lines-with-content.ts
+++ b/src/rules/two-spaces-between-lines-with-content.ts
@@ -10,8 +10,8 @@ class TwoSpacesBetweenLinesWithContentOptions implements Options {}
 export default class TwoSpacesBetweenLinesWithContent extends RuleBuilder<TwoSpacesBetweenLinesWithContentOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.two-spaces-between-lines-with-content.name',
-      descriptionTextKey: 'rules.two-spaces-between-lines-with-content.description',
+      nameKey: 'rules.two-spaces-between-lines-with-content.name',
+      descriptionKey: 'rules.two-spaces-between-lines-with-content.description',
       type: RuleType.CONTENT,
     });
   }
diff --git a/src/rules/unordered-list-style.ts b/src/rules/unordered-list-style.ts
index 3e48750..6d28072 100644
--- a/src/rules/unordered-list-style.ts
+++ b/src/rules/unordered-list-style.ts
@@ -12,8 +12,8 @@ class UnorderedListStyleOptions implements Options {
 export default class UnorderedListStyle extends RuleBuilder<UnorderedListStyleOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.unordered-list-style.name',
-      descriptionTextKey: 'rules.unordered-list-style.description',
+      nameKey: 'rules.unordered-list-style.name',
+      descriptionKey: 'rules.unordered-list-style.description',
       type: RuleType.CONTENT,
     });
   }
@@ -172,8 +172,8 @@ export default class UnorderedListStyle extends RuleBuilder<UnorderedListStyleOp
     return [
       new DropdownOptionBuilder<UnorderedListStyleOptions, UnorderedListItemStyles>({
         OptionsClass: UnorderedListStyleOptions,
-        nameTextKey: 'rules.unordered-list-style.list-style.name',
-        descriptionTextKey: 'rules.unordered-list-style.list-style.description',
+        nameKey: 'rules.unordered-list-style.list-style.name',
+        descriptionKey: 'rules.unordered-list-style.list-style.description',
         optionsKey: 'listStyle',
         records: [
           {
diff --git a/src/rules/yaml-key-sort.ts b/src/rules/yaml-key-sort.ts
index 63ed481..97c21fc 100644
--- a/src/rules/yaml-key-sort.ts
+++ b/src/rules/yaml-key-sort.ts
@@ -26,8 +26,8 @@ class YamlKeySortOptions implements Options {
 export default class YamlKeySort extends RuleBuilder<YamlKeySortOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.yaml-key-sort.name',
-      descriptionTextKey: 'rules.yaml-key-sort.description',
+      nameKey: 'rules.yaml-key-sort.name',
+      descriptionKey: 'rules.yaml-key-sort.description',
       type: RuleType.YAML,
       hasSpecialExecutionOrder: true,
     });
@@ -261,20 +261,20 @@ export default class YamlKeySort extends RuleBuilder<YamlKeySortOptions> {
     return [
       new TextAreaOptionBuilder({
         OptionsClass: YamlKeySortOptions,
-        nameTextKey: 'rules.yaml-key-sort.yaml-key-priority-sort-order.name',
-        descriptionTextKey: 'rules.yaml-key-sort.yaml-key-priority-sort-order.description',
+        nameKey: 'rules.yaml-key-sort.yaml-key-priority-sort-order.name',
+        descriptionKey: 'rules.yaml-key-sort.yaml-key-priority-sort-order.description',
         optionsKey: 'yamlKeyPrioritySortOrder',
       }),
       new BooleanOptionBuilder({
         OptionsClass: YamlKeySortOptions,
-        nameTextKey: 'rules.yaml-key-sort.priority-keys-at-start-of-yaml.name',
-        descriptionTextKey: 'rules.yaml-key-sort.priority-keys-at-start-of-yaml.description',
+        nameKey: 'rules.yaml-key-sort.priority-keys-at-start-of-yaml.name',
+        descriptionKey: 'rules.yaml-key-sort.priority-keys-at-start-of-yaml.description',
         optionsKey: 'priorityKeysAtStartOfYaml',
       }),
       new DropdownOptionBuilder<YamlKeySortOptions, YamlSortOrderForOtherKeys>({
         OptionsClass: YamlKeySortOptions,
-        nameTextKey: 'rules.yaml-key-sort.yaml-sort-order-for-other-keys.name',
-        descriptionTextKey: 'rules.yaml-key-sort.yaml-sort-order-for-other-keys.description',
+        nameKey: 'rules.yaml-key-sort.yaml-sort-order-for-other-keys.name',
+        descriptionKey: 'rules.yaml-key-sort.yaml-sort-order-for-other-keys.description',
         optionsKey: 'yamlSortOrderForOtherKeys',
         records: [
           {
diff --git a/src/rules/yaml-timestamp.ts b/src/rules/yaml-timestamp.ts
index 0609d34..d305211 100644
--- a/src/rules/yaml-timestamp.ts
+++ b/src/rules/yaml-timestamp.ts
@@ -40,8 +40,8 @@ class YamlTimestampOptions implements Options {
 export default class YamlTimestamp extends RuleBuilder<YamlTimestampOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.yaml-timestamp.name',
-      descriptionTextKey: 'rules.yaml-timestamp.description',
+      nameKey: 'rules.yaml-timestamp.name',
+      descriptionKey: 'rules.yaml-timestamp.description',
       type: RuleType.YAML,
       hasSpecialExecutionOrder: true,
     });
@@ -283,38 +283,38 @@ export default class YamlTimestamp extends RuleBuilder<YamlTimestampOptions> {
     return [
       new BooleanOptionBuilder({
         OptionsClass: YamlTimestampOptions,
-        nameTextKey: 'rules.yaml-timestamp.date-created.name',
-        descriptionTextKey: 'rules.yaml-timestamp.date-created.description',
+        nameKey: 'rules.yaml-timestamp.date-created.name',
+        descriptionKey: 'rules.yaml-timestamp.date-created.description',
         optionsKey: 'dateCreated',
       }),
       new TextOptionBuilder({
         OptionsClass: YamlTimestampOptions,
-        nameTextKey: 'rules.yaml-timestamp.date-created-key.name',
-        descriptionTextKey: 'rules.yaml-timestamp.date-created-key.description',
+        nameKey: 'rules.yaml-timestamp.date-created-key.name',
+        descriptionKey: 'rules.yaml-timestamp.date-created-key.description',
         optionsKey: 'dateCreatedKey',
       }),
       new BooleanOptionBuilder({
         OptionsClass: YamlTimestampOptions,
-        nameTextKey: 'rules.yaml-timestamp.force-retention-of-create-value.name',
-        descriptionTextKey: 'rules.yaml-timestamp.force-retention-of-create-value.description',
+        nameKey: 'rules.yaml-timestamp.force-retention-of-create-value.name',
+        descriptionKey: 'rules.yaml-timestamp.force-retention-of-create-value.description',
         optionsKey: 'forceRetentionOfCreatedValue',
       }),
       new BooleanOptionBuilder({
         OptionsClass: YamlTimestampOptions,
-        nameTextKey: 'rules.yaml-timestamp.date-modified.name',
-        descriptionTextKey: 'rules.yaml-timestamp.date-modified.description',
+        nameKey: 'rules.yaml-timestamp.date-modified.name',
+        descriptionKey: 'rules.yaml-timestamp.date-modified.description',
         optionsKey: 'dateModified',
       }),
       new TextOptionBuilder({
         OptionsClass: YamlTimestampOptions,
-        nameTextKey: 'rules.yaml-timestamp.date-modified-key.name',
-        descriptionTextKey: 'rules.yaml-timestamp.date-modified-key.description',
+        nameKey: 'rules.yaml-timestamp.date-modified-key.name',
+        descriptionKey: 'rules.yaml-timestamp.date-modified-key.description',
         optionsKey: 'dateModifiedKey',
       }),
       new MomentFormatOptionBuilder({
         OptionsClass: YamlTimestampOptions,
-        nameTextKey: 'rules.yaml-timestamp.format.name',
-        descriptionTextKey: 'rules.yaml-timestamp.format.description',
+        nameKey: 'rules.yaml-timestamp.format.name',
+        descriptionKey: 'rules.yaml-timestamp.format.description',
         optionsKey: 'format',
       }),
     ];
diff --git a/src/rules/yaml-title-alias.ts b/src/rules/yaml-title-alias.ts
index a49cc1d..138c330 100644
--- a/src/rules/yaml-title-alias.ts
+++ b/src/rules/yaml-title-alias.ts
@@ -27,8 +27,8 @@ class YamlTitleAliasOptions implements Options {
 export default class YamlTitleAlias extends RuleBuilder<YamlTitleAliasOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.yaml-title-alias.name',
-      descriptionTextKey: 'rules.yaml-title-alias.description',
+      nameKey: 'rules.yaml-title-alias.name',
+      descriptionKey: 'rules.yaml-title-alias.description',
       type: RuleType.YAML,
     });
   }
@@ -267,20 +267,20 @@ export default class YamlTitleAlias extends RuleBuilder<YamlTitleAliasOptions> {
     return [
       new BooleanOptionBuilder({
         OptionsClass: YamlTitleAliasOptions,
-        nameTextKey: 'rules.yaml-title-alias.preserve-existing-alias-section-style.name',
-        descriptionTextKey: 'rules.yaml-title-alias.preserve-existing-alias-section-style.description',
+        nameKey: 'rules.yaml-title-alias.preserve-existing-alias-section-style.name',
+        descriptionKey: 'rules.yaml-title-alias.preserve-existing-alias-section-style.description',
         optionsKey: 'preserveExistingAliasesSectionStyle',
       }),
       new BooleanOptionBuilder({
         OptionsClass: YamlTitleAliasOptions,
-        nameTextKey: 'rules.yaml-title-alias.keep-alias-that-matches-the-filename.name',
-        descriptionTextKey: 'rules.yaml-title-alias.keep-alias-that-matches-the-filename.description',
+        nameKey: 'rules.yaml-title-alias.keep-alias-that-matches-the-filename.name',
+        descriptionKey: 'rules.yaml-title-alias.keep-alias-that-matches-the-filename.description',
         optionsKey: 'keepAliasThatMatchesTheFilename',
       }),
       new BooleanOptionBuilder({
         OptionsClass: YamlTitleAliasOptions,
-        nameTextKey: 'rules.yaml-title-alias.use-yaml-key-to-keep-track-of-old-filename-or-heading.name',
-        descriptionTextKey: 'rules.yaml-title-alias.use-yaml-key-to-keep-track-of-old-filename-or-heading.description',
+        nameKey: 'rules.yaml-title-alias.use-yaml-key-to-keep-track-of-old-filename-or-heading.name',
+        descriptionKey: 'rules.yaml-title-alias.use-yaml-key-to-keep-track-of-old-filename-or-heading.description',
         optionsKey: 'useYamlKeyToKeepTrackOfOldFilenameOrHeading',
       }),
     ];
diff --git a/src/rules/yaml-title.ts b/src/rules/yaml-title.ts
index 3fe9e92..ce2aa87 100644
--- a/src/rules/yaml-title.ts
+++ b/src/rules/yaml-title.ts
@@ -20,8 +20,8 @@ class YamlTitleOptions implements Options {
 export default class YamlTitle extends RuleBuilder<YamlTitleOptions> {
   constructor() {
     super({
-      nameTextKey: 'rules.yaml-title.name',
-      descriptionTextKey: 'rules.yaml-title.description',
+      nameKey: 'rules.yaml-title.name',
+      descriptionKey: 'rules.yaml-title.description',
       type: RuleType.YAML,
     });
   }
@@ -101,8 +101,8 @@ export default class YamlTitle extends RuleBuilder<YamlTitleOptions> {
     return [
       new TextOptionBuilder({
         OptionsClass: YamlTitleOptions,
-        nameTextKey: 'rules.yaml-title.title-key.name',
-        descriptionTextKey: 'rules.yaml-title.title-key.description',
+        nameKey: 'rules.yaml-title.title-key.name',
+        descriptionKey: 'rules.yaml-title.title-key.description',
         optionsKey: 'titleKey',
       }),
     ];
diff --git a/src/ui/linter-components/tab-components/rule-tab.ts b/src/ui/linter-components/tab-components/rule-tab.ts
index 4eaf74c..76fe4ff 100644
--- a/src/ui/linter-components/tab-components/rule-tab.ts
+++ b/src/ui/linter-components/tab-components/rule-tab.ts
@@ -14,16 +14,16 @@ export class RuleTab extends Tab {
       const ruleDiv = this.contentEl.createDiv();
       ruleDiv.id = rule.alias;
       ruleDiv.createEl(this.isMobile ? 'h4' : 'h3', {}, (el) => {
-        el.innerHTML = `<a href="${rule.getURL()}">${rule.name}</a>`;
+        el.innerHTML = `<a href="${rule.getURL()}">${rule.getName()}</a>`;
       });
 
       const optionInfo = [] as SearchOptionInfo[];
       for (const option of rule.options) {
         option.display(ruleDiv, this.plugin.settings, this.plugin);
-        optionInfo.push(option.searchInfo);
+        optionInfo.push(option.getSearchInfo());
       }
 
-      this.addSettingSearchInfo(ruleDiv, rule.name.toLowerCase(), rule.description.toLowerCase(), optionInfo, ruleDiv.id);
+      this.addSettingSearchInfo(ruleDiv, rule.getName().toLowerCase(), rule.getDescription().toLowerCase(), optionInfo, ruleDiv.id);
     }
   }
 }
diff --git a/src/utils/nested-keyof.ts b/src/utils/nested-keyof.ts
index f315230..e3537a7 100644
--- a/src/utils/nested-keyof.ts
+++ b/src/utils/nested-keyof.ts
@@ -13,7 +13,14 @@ export function getString<ObjectType>(object: Partial<ObjectType>, path: string)
     return null;
   }
 
+  path = path.replace('..', '.'); // convert 2 periods in a row to a single period so we can properly account for the blank key value later on
   const keys = path.split('.');
+
+  // the value of '.' is an actual key as well so I need to make sure that if the last value is blank that it is set to a period
+  if (keys != null && keys[keys.length - 1] == '') {
+    keys[keys.length - 1] = '.';
+  }
+
   let result = object;
   for (const key of keys) {
     // @ts-ignore ignore the fact that result is technically of type any


Test patch:
diff --git a/__tests__/common.ts b/__tests__/common.ts
index 51b5185..578b779 100644
--- a/__tests__/common.ts
+++ b/__tests__/common.ts
@@ -15,7 +15,7 @@ export function ruleTest<TOptions extends Options>(args: {
 }): void {
   const rule = args.RuleBuilderClass.getRule();
 
-  describe(rule.name, () => {
+  describe(rule.getName(), () => {
     for (const testCase of args.testCases) {
       it(testCase.testName, () => {
         const options = testCase.options instanceof Function ? testCase.options() : testCase.options;
diff --git a/__tests__/examples.test.ts b/__tests__/examples.test.ts
index 3f1b5a9..844d26f 100644
--- a/__tests__/examples.test.ts
+++ b/__tests__/examples.test.ts
@@ -5,7 +5,7 @@ import '../src/rules-registry';
 
 describe('Examples pass', () => {
   for (const rule of rules) {
-    describe(rule.name, () => {
+    describe(rule.getName(), () => {
       test.each(rule.examples)('$description', (example: Example) => {
         expect(rule.apply(example.before, example.options)).toBe(example.after);
       });
@@ -15,7 +15,7 @@ describe('Examples pass', () => {
 
 describe('Augmented examples pass', () => {
   for (const rule of rules) {
-    describe(rule.name, () => {
+    describe(rule.getName(), () => {
       test.each(rule.examples)('$description', (example: Example) => {
         // Add YAML
         if (rule.type !== RuleType.YAML && rule.type !== RuleType.PASTE && !example.before.match(yamlRegex)) {
diff --git a/__tests__/missing-fields.test.ts b/__tests__/missing-fields.test.ts
index 043a814..d2712e1 100644
--- a/__tests__/missing-fields.test.ts
+++ b/__tests__/missing-fields.test.ts
@@ -3,8 +3,8 @@ import '../src/rules-registry';
 
 describe('Check missing fields', () => {
   test.each(rules)('$name', (rule: Rule) => {
-    expect(rule.name).toBeTruthy();
-    expect(rule.description).toBeTruthy();
+    expect(rule.getName()).toBeTruthy();
+    expect(rule.getDescription()).toBeTruthy();
     expect(rule.examples.length).toBeGreaterThan(0);
   });
 });
diff --git a/__tests__/setting-controls.test.ts b/__tests__/setting-controls.test.ts
index 8cf5f87..645f84f 100644
--- a/__tests__/setting-controls.test.ts
+++ b/__tests__/setting-controls.test.ts
@@ -4,8 +4,8 @@ import '../src/rules-registry';
 
 describe('Setting controls initialize all options class keys', () => {
   for (const rule of rules) {
-    describe(rule.name, () => {
-      const builder = RuleBuilderBase.getBuilderByName(rule.name) as RuleBuilder<Options>;
+    describe(rule.getName(), () => {
+      const builder = RuleBuilderBase.getBuilderByName(rule.alias) as RuleBuilder<Options>;
       const optionsInstance = new builder.OptionsClass();
       const optionsClassKeys = Object.getOwnPropertyNames(optionsInstance);
       const optionsControlKeys = new Set(builder.optionBuilders.map((optionBuilder) => (optionBuilder as OptionBuilder<Options, unknown>).optionsKey));