Repository: platers/obsidian-linter (ts)

Issue:
FR: Move tags to Yaml - option to delete tags completely
As of now there is only an option to `Remove the hashtag from tags in content body`

I would like to request an option to `Remove the tags in content body completely`.
- So all the text is deleted in the body and after the link, the tags only exist in the yaml front matter.

Pull request description:
Add Option for Deleting Tags from Body of File, Prep for Release, and Update Logic for Moving Common Settings
Fixes #444 

Changes Made:
- Changed the option for whether or not to remove the hashtags of the tags in Move Tags to Yaml to be a dropdown that let you choose whether to do nothing to, remove the hashtag of, or remove the tag and the space behind it for tags in the body of the file
- Fixed spacing for part of a test
- Updated docs
- Updated version info as a prep for release
- Updated the common settings logic move to only care about options that are enabled when copying over the yaml array formats

Patch:
diff --git a/docs/rules.md b/docs/rules.md
index d96471c..9ffce94 100644
--- a/docs/rules.md
+++ b/docs/rules.md
@@ -384,8 +384,11 @@ Alias: `move-tags-to-yaml`
 Move all tags to Yaml frontmatter of the document.
 
 Options:
-- Remove the hashtag from tags in content body: Removes `#` from tags in content body after moving them to the Yaml frontmatter
-	- Default: `false`
+- Body tag operation: What to do with non-ignored tags in the body of the file once they have been moved to the frontmatter
+	- Default: `Nothing`
+	- `Nothing`: Leaves tags in the body of the file alone
+	- `Remove hashtag`: Removes `#` from tags in content body after moving them to the YAML frontmatter
+	- `Remove whole tag`: Removes the whole tag in content body after moving them to the YAML frontmatter. _Note that this removes the first space prior to the tag as well_
 - Tags to ignore: The tags that will not be moved to the tags array or removed from the body content if `Remove the hashtag from tags in content body` is enabled. Each tag should be on a new line and without the `#`. **Make sure not to include the hashtag in the tag name.**
 	- Default: ``
 
@@ -425,7 +428,7 @@ This inline code `#ignored content`
 
 #ignored-tag is ignored since it is in the ignored list
 ``````
-Example: Move tags from body to Yaml with existing tags retains the already existing ones and only adds new ones
+Example: Move tags from body to YAML with existing tags retains the already existing ones and only adds new ones
 
 Before:
 
@@ -444,7 +447,7 @@ tags: [test, tag2, markdown]
 ---
 Text has to do with #test and #markdown
 ``````
-Example: Move tags to Yaml frontmatter and then remove hashtags in body content tags `Remove the hashtag from tags in content body = true` with `Tags to ignore = 'yet-another-ignored-tag'`.
+Example: Move tags to YAML frontmatter and then remove hashtags in body content tags when `Body tag operation = 'Remove hashtag'` and `Tags to ignore = 'yet-another-ignored-tag'`.
 
 Before:
 
@@ -467,6 +470,25 @@ Text has to do with test and markdown
 
 The tag at the end of this line stays as a tag since it is ignored #yet-another-ignored-tag
 ``````
+Example: Move tags to YAML frontmatter and then remove body content tags when `Body tag operation = 'Remove whole tag'`.
+
+Before:
+
+``````markdown
+---
+tags: [test, tag2]
+---
+This document will have #tags removed and spacing around tags is left alone except for the space prior to the hashtag #warning
+``````
+
+After:
+
+``````markdown
+---
+tags: [test, tag2, tags, warning]
+---
+This document will have removed and spacing around tags is left alone except for the space prior to the hashtag
+``````
 
 ### Remove YAML Keys
 
diff --git a/manifest.json b/manifest.json
index 317885a..8caba79 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
 {
   "id": "obsidian-linter",
   "name": "Linter",
-  "version": "1.6.0",
+  "version": "1.7.0",
   "minAppVersion": "0.15.6",
   "description": "Enforces consistent markdown styling.",
   "author": "Victor Tao",
diff --git a/package.json b/package.json
index b9777c8..511fc07 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "obsidian-linter",
-  "version": "1.6.0",
+  "version": "1.7.0",
   "description": "Enforces consistent markdown styling for Obsidian (https://obsidian.md)",
   "main": "main.js",
   "scripts": {
diff --git a/src/main.ts b/src/main.ts
index 4af0f45..5ee0028 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -98,7 +98,7 @@ export default class LinterPlugin extends Plugin {
     setLogLevel(this.settings.logLevel);
     this.setOrUpdateMomentInstance();
 
-    const escapeYAMLSpecialCharactersRule = this.settings.ruleConfigs['Escape YAML Special Characters'];
+    const escapeYAMLSpecialCharactersRule = this.settings.ruleConfigs['Move Tags to Yaml'];
     if (escapeYAMLSpecialCharactersRule) {
       const forceYamlEscapeKeys = escapeYAMLSpecialCharactersRule['Force Yaml Escape on Keys'];
       if (forceYamlEscapeKeys) {
@@ -106,12 +106,22 @@ export default class LinterPlugin extends Plugin {
           this.settings.ruleConfigs['Force YAML Escape'] = {};
         }
 
-        this.settings.ruleConfigs['Force YAML Escape']['Force YAML Escape on Keys'] = escapeYAMLSpecialCharactersRule['Force Yaml Escape on Keys'] ?? this.settings.ruleConfigs['Force YAML Escape']['Force YAML Escape on Keys'];
+        this.settings.ruleConfigs['Force YAML Escape']['Force YAML Escape on Keys'] = forceYamlEscapeKeys ?? this.settings.ruleConfigs['Force YAML Escape']['Force YAML Escape on Keys'];
       }
 
       delete this.settings.ruleConfigs['Escape YAML Special Characters']['Force Yaml Escape on Keys'];
     }
 
+    const moveTagsToYamlRule = this.settings.ruleConfigs['Move Tags to Yaml'];
+    if (moveTagsToYamlRule) {
+      const removeHashtag = moveTagsToYamlRule['Remove the hashtag from tags in content body'];
+      if (removeHashtag !== null && removeHashtag !== undefined) {
+        this.settings.ruleConfigs['Move Tags to Yaml']['Body tag operation'] = removeHashtag ? 'Remove hashtag' : 'Nothing';
+
+        delete this.settings.ruleConfigs['Move Tags to Yaml']['Remove the hashtag from tags in content body'];
+      }
+    }
+
     this.moveSettingsToCommonSettings();
 
     // make sure to load the defaults of any missing rules to make sure they do not cause issues on the settings page
@@ -485,58 +495,66 @@ export default class LinterPlugin extends Plugin {
     let newAliasFormat: NormalArrayFormats | SpecialArrayFormats = undefined;
     // alias format
     const YamlTitleAliasRule = this.settings.ruleConfigs['YAML Title Alias'];
-    if (YamlTitleAliasRule) {
-      switch (YamlTitleAliasRule['YAML aliases section style']) {
-        case 'Multi-line array':
-          newAliasFormat = NormalArrayFormats.MultiLine;
-          break;
-        case 'Single-line array':
-          newAliasFormat = NormalArrayFormats.SingleLine;
-          break;
-        case 'Single string that expands to multi-line array if needed':
-          newAliasFormat = SpecialArrayFormats.SingleStringToMultiLine;
-          break;
-        case 'Single string that expands to single-line array if needed':
-          newAliasFormat = SpecialArrayFormats.SingleStringToSingleLine;
-          break;
+    if (YamlTitleAliasRule && YamlTitleAliasRule['YAML aliases section style']) {
+      // if the rule is not enabled it does not matter what the format for the aliases is for copying over the value
+      if (YamlTitleAliasRule['Inserts the title of the file into the YAML frontmatter\'s aliases section. Gets the title from the first H1 or filename.']) {
+        switch (YamlTitleAliasRule['YAML aliases section style']) {
+          case 'Multi-line array':
+            newAliasFormat = NormalArrayFormats.MultiLine;
+            break;
+          case 'Single-line array':
+            newAliasFormat = NormalArrayFormats.SingleLine;
+            break;
+          case 'Single string that expands to multi-line array if needed':
+            newAliasFormat = SpecialArrayFormats.SingleStringToMultiLine;
+            break;
+          case 'Single string that expands to single-line array if needed':
+            newAliasFormat = SpecialArrayFormats.SingleStringToSingleLine;
+            break;
+        }
       }
 
       delete this.settings.ruleConfigs['YAML Title Alias']['YAML aliases section style'];
     }
 
     const formatYamlRule = this.settings.ruleConfigs['Format Yaml Array'];
-    if (formatYamlRule) {
-      const tempYAMLAliasFormat = formatYamlRule['Yaml aliases section style'] as NormalArrayFormats | SpecialArrayFormats;
-      if (!newAliasFormat) {
-        newAliasFormat = tempYAMLAliasFormat;
-      } else {
-        switch (tempYAMLAliasFormat) {
-          case NormalArrayFormats.SingleLine:
-            newAliasFormat = NormalArrayFormats.SingleLine;
-            break;
-          case NormalArrayFormats.MultiLine:
-            if (newAliasFormat != NormalArrayFormats.SingleLine) {
+    if (formatYamlRule && formatYamlRule['Yaml aliases section style']) {
+      // if the rule is enabled and the actual format for aliases is enabled then check the value
+      if (formatYamlRule['Allows for the formatting of regular yaml arrays as either multi-line or single-line and `tags` and `aliases` are allowed to have some Obsidian specific yaml formats. Note that single string to single-line goes from a single string entry to a single-line array if more than 1 entry is present. The same is true for single string to multi-line except it becomes a multi-line array.'] &&
+        formatYamlRule['Format yaml aliases section']) {
+        const tempYAMLAliasFormat = formatYamlRule['Yaml aliases section style'] as NormalArrayFormats | SpecialArrayFormats;
+        if (!newAliasFormat) {
+          newAliasFormat = tempYAMLAliasFormat;
+        } else {
+          switch (tempYAMLAliasFormat) {
+            case NormalArrayFormats.SingleLine:
               newAliasFormat = NormalArrayFormats.SingleLine;
-            }
-            break;
-          case SpecialArrayFormats.SingleStringCommaDelimited:
-            if (newAliasFormat != NormalArrayFormats.SingleLine && newAliasFormat != NormalArrayFormats.MultiLine) {
-              newAliasFormat = SpecialArrayFormats.SingleStringCommaDelimited;
-            }
-            break;
-          case SpecialArrayFormats.SingleStringToMultiLine:
-            if (newAliasFormat != NormalArrayFormats.SingleLine && newAliasFormat != NormalArrayFormats.MultiLine) {
-              newAliasFormat = SpecialArrayFormats.SingleStringToMultiLine;
-            }
-            break;
-          case SpecialArrayFormats.SingleStringToSingleLine:
-            if (newAliasFormat != NormalArrayFormats.SingleLine && newAliasFormat != NormalArrayFormats.MultiLine) {
-              newAliasFormat = SpecialArrayFormats.SingleStringToSingleLine;
-            }
-            break;
+              break;
+            case NormalArrayFormats.MultiLine:
+              if (newAliasFormat != NormalArrayFormats.SingleLine) {
+                newAliasFormat = NormalArrayFormats.SingleLine;
+              }
+              break;
+            case SpecialArrayFormats.SingleStringCommaDelimited:
+              if (newAliasFormat != NormalArrayFormats.SingleLine && newAliasFormat != NormalArrayFormats.MultiLine) {
+                newAliasFormat = SpecialArrayFormats.SingleStringCommaDelimited;
+              }
+              break;
+            case SpecialArrayFormats.SingleStringToMultiLine:
+              if (newAliasFormat != NormalArrayFormats.SingleLine && newAliasFormat != NormalArrayFormats.MultiLine) {
+                newAliasFormat = SpecialArrayFormats.SingleStringToMultiLine;
+              }
+              break;
+            case SpecialArrayFormats.SingleStringToSingleLine:
+              if (newAliasFormat != NormalArrayFormats.SingleLine && newAliasFormat != NormalArrayFormats.MultiLine) {
+                newAliasFormat = SpecialArrayFormats.SingleStringToSingleLine;
+              }
+              break;
+          }
         }
       }
 
+
       delete this.settings.ruleConfigs['Format Yaml Array']['Yaml aliases section style'];
     }
 
@@ -547,56 +565,63 @@ export default class LinterPlugin extends Plugin {
     // tags format
     let newTagFormat: NormalArrayFormats | SpecialArrayFormats | TagSpecificArrayFormats = undefined;
 
-    if (formatYamlRule) {
-      newTagFormat = formatYamlRule['Yaml tags section style'];
+    if (formatYamlRule && formatYamlRule['Yaml tags section style']) {
+      // if the rule is enabled and the actual format for aliases is enabled then check the value
+      if (formatYamlRule['Allows for the formatting of regular yaml arrays as either multi-line or single-line and `tags` and `aliases` are allowed to have some Obsidian specific yaml formats. Note that single string to single-line goes from a single string entry to a single-line array if more than 1 entry is present. The same is true for single string to multi-line except it becomes a multi-line array.'] &&
+       formatYamlRule['Format yaml tags section']) {
+        newTagFormat = formatYamlRule['Yaml tags section style'];
+      }
 
       delete this.settings.ruleConfigs['Format Yaml Array']['Yaml tags section style'];
     }
 
     const moveTagsToYamlRule = this.settings.ruleConfigs['Move Tags to Yaml'];
-    if (moveTagsToYamlRule) {
-      const tempYAMLTagFormat = moveTagsToYamlRule['Yaml tags section style'];
-      if (!newTagFormat) {
-        newTagFormat = tempYAMLTagFormat;
-      } else {
-        switch (tempYAMLTagFormat) {
-          case NormalArrayFormats.SingleLine:
-            newTagFormat = NormalArrayFormats.SingleLine;
-            break;
-          case NormalArrayFormats.MultiLine:
-            if (newTagFormat != NormalArrayFormats.SingleLine) {
+    if (moveTagsToYamlRule && moveTagsToYamlRule['Yaml tags section style']) {
+      // only check the value if the rule is enabled
+      if (moveTagsToYamlRule['Move all tags to Yaml frontmatter of the document.']) {
+        const tempYAMLTagFormat = moveTagsToYamlRule['Yaml tags section style'];
+        if (!newTagFormat) {
+          newTagFormat = tempYAMLTagFormat;
+        } else {
+          switch (tempYAMLTagFormat) {
+            case NormalArrayFormats.SingleLine:
               newTagFormat = NormalArrayFormats.SingleLine;
-            }
-            break;
-          case SpecialArrayFormats.SingleStringCommaDelimited:
-            if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine) {
-              newTagFormat = SpecialArrayFormats.SingleStringCommaDelimited;
-            }
-            break;
-          case SpecialArrayFormats.SingleStringToMultiLine:
-            if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine) {
-              newTagFormat = SpecialArrayFormats.SingleStringToMultiLine;
-            }
-            break;
-          case SpecialArrayFormats.SingleStringToSingleLine:
-            if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine) {
-              newTagFormat = SpecialArrayFormats.SingleStringToSingleLine;
-            }
-            break;
-          case TagSpecificArrayFormats.SingleLineSpaceDelimited:
-            if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine &&
-                newTagFormat != SpecialArrayFormats.SingleStringCommaDelimited && newTagFormat != SpecialArrayFormats.SingleStringToSingleLine &&
-                newTagFormat != SpecialArrayFormats.SingleStringToMultiLine) {
-              newTagFormat = TagSpecificArrayFormats.SingleLineSpaceDelimited;
-            }
-            break;
-          case TagSpecificArrayFormats.SingleStringSpaceDelimited:
-            if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine &&
+              break;
+            case NormalArrayFormats.MultiLine:
+              if (newTagFormat != NormalArrayFormats.SingleLine) {
+                newTagFormat = NormalArrayFormats.SingleLine;
+              }
+              break;
+            case SpecialArrayFormats.SingleStringCommaDelimited:
+              if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine) {
+                newTagFormat = SpecialArrayFormats.SingleStringCommaDelimited;
+              }
+              break;
+            case SpecialArrayFormats.SingleStringToMultiLine:
+              if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine) {
+                newTagFormat = SpecialArrayFormats.SingleStringToMultiLine;
+              }
+              break;
+            case SpecialArrayFormats.SingleStringToSingleLine:
+              if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine) {
+                newTagFormat = SpecialArrayFormats.SingleStringToSingleLine;
+              }
+              break;
+            case TagSpecificArrayFormats.SingleLineSpaceDelimited:
+              if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine &&
                   newTagFormat != SpecialArrayFormats.SingleStringCommaDelimited && newTagFormat != SpecialArrayFormats.SingleStringToSingleLine &&
                   newTagFormat != SpecialArrayFormats.SingleStringToMultiLine) {
-              newTagFormat = TagSpecificArrayFormats.SingleStringSpaceDelimited;
-            }
-            break;
+                newTagFormat = TagSpecificArrayFormats.SingleLineSpaceDelimited;
+              }
+              break;
+            case TagSpecificArrayFormats.SingleStringSpaceDelimited:
+              if (newTagFormat != NormalArrayFormats.SingleLine && newTagFormat != NormalArrayFormats.MultiLine &&
+                    newTagFormat != SpecialArrayFormats.SingleStringCommaDelimited && newTagFormat != SpecialArrayFormats.SingleStringToSingleLine &&
+                    newTagFormat != SpecialArrayFormats.SingleStringToMultiLine) {
+                newTagFormat = TagSpecificArrayFormats.SingleStringSpaceDelimited;
+              }
+              break;
+          }
         }
       }
 
diff --git a/src/rules/move-tags-to-yaml.ts b/src/rules/move-tags-to-yaml.ts
index 515dcc4..14d6cb6 100644
--- a/src/rules/move-tags-to-yaml.ts
+++ b/src/rules/move-tags-to-yaml.ts
@@ -1,5 +1,5 @@
 import {Options, RuleType} from '../rules';
-import RuleBuilder, {BooleanOptionBuilder, ExampleBuilder, OptionBuilderBase, TextAreaOptionBuilder} from './rule-builder';
+import RuleBuilder, {DropdownOptionBuilder, ExampleBuilder, OptionBuilderBase, TextAreaOptionBuilder} from './rule-builder';
 import dedent from 'ts-dedent';
 import {ignoreListOfTypes, IgnoreTypes} from '../utils/ignore-types';
 import {tagRegex} from '../utils/regex';
@@ -17,10 +17,12 @@ import {
   TagSpecificArrayFormats,
 } from '../utils/yaml';
 
+type tagOperations = 'Nothing' | 'Remove hashtag' | 'Remove whole tag';
+
 class MoveTagsToYamlOptions implements Options {
   @RuleBuilder.noSettingControl()
     tagArrayStyle? : TagSpecificArrayFormats | NormalArrayFormats | SpecialArrayFormats = NormalArrayFormats.SingleLine;
-  removeHashtagsFromTagsInBody?: boolean = false;
+  howToHandleExistingTags?: tagOperations = 'Nothing';
   tagsToIgnore?: string[] = [];
 }
 
@@ -75,7 +77,7 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
         return `---\n${newYaml}---`;
       });
 
-      if (options.removeHashtagsFromTagsInBody) {
+      if (options.howToHandleExistingTags === 'Remove hashtag') {
         text = text.replace(tagRegex, (tag: string) => {
           const hashtagIndex = tag.indexOf('#');
 
@@ -86,6 +88,8 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
 
           return tag.substring(0, hashtagIndex) + tagContents;
         });
+      } else if (options.howToHandleExistingTags === 'Remove whole tag') {
+        text = text.replace(tagRegex, '');
       }
 
       return text;
@@ -129,7 +133,7 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
         },
       }),
       new ExampleBuilder({
-        description: 'Move tags from body to Yaml with existing tags retains the already existing ones and only adds new ones',
+        description: 'Move tags from body to YAML with existing tags retains the already existing ones and only adds new ones',
         before: dedent`
           ---
           tags: [test, tag2]
@@ -144,7 +148,7 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
         `,
       }),
       new ExampleBuilder({
-        description: 'Move tags to Yaml frontmatter and then remove hashtags in body content tags `Remove the hashtag from tags in content body = true` with `Tags to ignore = \'yet-another-ignored-tag\'`.',
+        description: 'Move tags to YAML frontmatter and then remove hashtags in body content tags when `Body tag operation = \'Remove hashtag\'` and `Tags to ignore = \'yet-another-ignored-tag\'`.',
         before: dedent`
           ---
           tags: [test, tag2]
@@ -162,19 +166,51 @@ export default class MoveTagsToYaml extends RuleBuilder<MoveTagsToYamlOptions> {
           The tag at the end of this line stays as a tag since it is ignored #yet-another-ignored-tag
         `,
         options: {
-          removeHashtagsFromTagsInBody: true,
+          howToHandleExistingTags: 'Remove hashtag',
           tagsToIgnore: ['yet-another-ignored-tag'],
         },
       }),
+      new ExampleBuilder({
+        description: 'Move tags to YAML frontmatter and then remove body content tags when `Body tag operation = \'Remove whole tag\'`.',
+        before: dedent`
+          ---
+          tags: [test, tag2]
+          ---
+          This document will have #tags removed and spacing around tags is left alone except for the space prior to the hashtag #warning
+        `,
+        after: dedent`
+          ---
+          tags: [test, tag2, tags, warning]
+          ---
+          This document will have removed and spacing around tags is left alone except for the space prior to the hashtag
+        `,
+        options: {
+          howToHandleExistingTags: 'Remove whole tag',
+        },
+      }),
     ];
   }
   get optionBuilders(): OptionBuilderBase<MoveTagsToYamlOptions>[] {
     return [
-      new BooleanOptionBuilder({
+      new DropdownOptionBuilder({
         OptionsClass: MoveTagsToYamlOptions,
-        name: 'Remove the hashtag from tags in content body',
-        description: 'Removes `#` from tags in content body after moving them to the Yaml frontmatter',
-        optionsKey: 'removeHashtagsFromTagsInBody',
+        name: 'Body tag operation',
+        description: 'What to do with non-ignored tags in the body of the file once they have been moved to the frontmatter',
+        optionsKey: 'howToHandleExistingTags',
+        records: [
+          {
+            value: 'Nothing',
+            description: 'Leaves tags in the body of the file alone',
+          },
+          {
+            value: 'Remove hashtag',
+            description: 'Removes `#` from tags in content body after moving them to the YAML frontmatter',
+          },
+          {
+            value: 'Remove whole tag',
+            description: 'Removes the whole tag in content body after moving them to the YAML frontmatter. _Note that this removes the first space prior to the tag as well_',
+          },
+        ],
       }),
       new TextAreaOptionBuilder({
         OptionsClass: MoveTagsToYamlOptions,
diff --git a/versions.json b/versions.json
index 77a926f..0fed9a9 100644
--- a/versions.json
+++ b/versions.json
@@ -1,4 +1,5 @@
 {
+	"1.7.0": "0.15.6",
 	"1.6.0": "0.15.6",
 	"1.5.1": "0.15.6",
 	"1.5.0": "0.15.6",


Test patch:
diff --git a/__tests__/empty-line-around-code-fences.test.ts b/__tests__/empty-line-around-code-fences.test.ts
index 6430bf4..b77b5af 100644
--- a/__tests__/empty-line-around-code-fences.test.ts
+++ b/__tests__/empty-line-around-code-fences.test.ts
@@ -48,7 +48,7 @@ ruleTest({
             upload_max_filesize = 20M
             post_max_size = 20M
             \`\`\`
-          ${''}
+        ${''}
         2. 修改 Nginx 配置文件
         ${''}
             \`\`\`