platers / obsidian-linter

An Obsidian plugin that formats and styles your notes with a focus on configurability and extensibility.
https://platers.github.io/obsidian-linter/
MIT License
1.17k stars 81 forks source link

Bug: can not read a block mapping entry; a multiline key may not be an implicit key #649

Open mengshang918 opened 1 year ago

mengshang918 commented 1 year ago

Describe the Bug

截屏2023-03-13 上午11 47 34

When I delete a tag or delete all yaml comments, no error is reported

How to Reproduce

Example to reproduce issue with

---
#请输入卡片别名
aliases: 
#请输入卡片涉及的标签
tag: 永久笔记
#当前卡片所用的模板
template: Templates/ZK/卡片笔记模板
#该卡片创建日期 用于dataview插件查询过滤
created: 2023-03-13
date created: 2023-03-13 10:50 上午
---

When the above content is saved, an error is reported.

data.json file

{
  "ruleConfigs": {
    "Escape YAML Special Characters": {
      "Escapes colons with a space after them (: ), single quotes ('), and double quotes (\") in YAML.": true,
      "Try to Escape Single Line Arrays": false
    },
    "Format Tags in YAML": {
      "Remove Hashtags from tags in the YAML frontmatter, as they make the tags there invalid.": true
    },
    "Format Yaml Array": {
      "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.": false,
      "Format yaml aliases section": true,
      "Format yaml tags section": true,
      "Default yaml array section style": "single-line",
      "Format yaml array sections": true,
      "Force key values to be single-line arrays": "",
      "Force key values to be multi-line arrays": ""
    },
    "Insert YAML attributes": {
      "Inserts the given YAML attributes into the YAML frontmatter. Put each attribute on a single line.": true,
      "Text to insert": "aliases: \ntag: "
    },
    "Move Tags to Yaml": {
      "Move all tags to Yaml frontmatter of the document.": false,
      "Tags to ignore": "",
      "Body tag operation": "Nothing"
    },
    "Remove YAML Keys": {
      "Removes the YAML keys specified": false,
      "YAML Keys to Remove": ""
    },
    "YAML Key Sort": {
      "Sorts the YAML keys based on the order and priority specified. Note: may remove blank lines as well.": false,
      "YAML Key Priority Sort Order": "",
      "Priority Keys at Start of YAML": true,
      "YAML Sort Order for Other Keys": "None"
    },
    "YAML Timestamp": {
      "Keep track of the date the file was last edited in the YAML front matter. Gets dates from file metadata.": true,
      "Date Created": true,
      "Date Created Key": "date created",
      "Date Modified": true,
      "Date Modified Key": "date modified",
      "Format": "YYYY-MM-DD HH:mm a"
    },
    "YAML Title": {
      "Inserts the title of the file into the YAML frontmatter. Gets the title from the first H1 or filename if there is no H1.": false,
      "Title Key": "aliases",
      "Inserts the title of the file into the YAML frontmatter. Gets the title from the first H1 or filename.": true
    },
    "YAML Title Alias": {
      "Inserts the title of the file into the YAML frontmatter's aliases section. Gets the title from the first H1 or filename.": true,
      "Preserve existing aliases section style": true,
      "Keep alias that matches the filename": false,
      "Use the YAML key `linter-yaml-title-alias` to help with filename and heading changes": true
    },
    "Capitalize Headings": {
      "Headings should be formatted with capitalization": true,
      "Style": "Title Case",
      "Ignore Cased Words": true,
      "Ignore Words": "macOS, iOS, iPhone, iPad, JavaScript, TypeScript, AppleScript",
      "Lowercase Words": "via, a, an, the, and, or, but, for, nor, so, yet, at, by, in, of, on, to, up, as, is, if, it, for, to, with, without, into, onto, per"
    },
    "File Name Heading": {
      "Inserts the file name as a H1 heading if no H1 heading exists.": true
    },
    "Header Increment": {
      "Heading levels should only increment by one level at a time": true
    },
    "Footnote after Punctuation": {
      "Ensures that footnote references are placed after punctuation, not before.": true
    },
    "Move Footnotes to the bottom": {
      "Move all footnotes to the bottom of the document.": true
    },
    "Re-Index Footnotes": {
      "Re-indexes footnote keys and footnote, based on the order of occurrence (NOTE: This rule deliberately does *not* preserve the relation between key and footnote, to be able to re-index duplicate keys.)": false,
      "Re-indexes footnote keys and footnote, based on the order of occurence (NOTE: This rule deliberately does *not* preserve the relation between key and footnote, to be able to re-index duplicate keys.)": false
    },
    "Convert Bullet List Markers": {
      "Converts common bullet list marker symbols to markdown list markers.": true
    },
    "Emphasis Style": {
      "Makes sure the emphasis style is consistent.": true,
      "Style": "asterisk"
    },
    "No Bare URLs": {
      "Encloses bare URLs with angle brackets except when enclosed in back ticks, square braces, or single or double quotes.": true
    },
    "Ordered List Style": {
      "Makes sure that ordered lists follow the style specified. Note that 2 spaces or 1 tab is considered to be an indentation level.": true,
      "Number Style": "lazy",
      "Ordered List Indicator End Style": "."
    },
    "Proper Ellipsis": {
      "Replaces three consecutive dots with an ellipsis.": false
    },
    "Remove Consecutive List Markers": {
      "Removes consecutive list markers. Useful when copy-pasting list items.": false
    },
    "Remove Empty List Markers": {
      "Removes empty list markers, i.e. list items without content.": false
    },
    "Remove Hyphenated Line Breaks": {
      "Removes hyphenated line breaks. Useful when pasting text from textbooks.": false
    },
    "Remove Multiple Spaces": {
      "Removes two or more consecutive spaces. Ignores spaces at the beginning and ending of the line. ": true
    },
    "Strong Style": {
      "Makes sure the strong style is consistent.": true,
      "Style": "asterisk"
    },
    "Two Spaces Between Lines with Content": {
      "Makes sure that two spaces are added to the ends of lines with content continued on the next line for paragraphs, blockquotes, and list items": true
    },
    "Unordered List Style": {
      "Makes sure that unordered lists follow the style specified.": true,
      "List item style": "-"
    },
    "Compact YAML": {
      "Removes leading and trailing blank lines in the YAML front matter.": true,
      "Inner New Lines": true
    },
    "Consecutive blank lines": {
      "There should be at most one consecutive blank line.": true
    },
    "Convert Spaces to Tabs": {
      "Converts leading spaces to tabs.": true,
      "Tabsize": "2"
    },
    "Empty Line Around Blockquotes": {
      "Ensures that there is an empty line around blockquotes unless they start or end a document. **Note that an empty line is either one less level of nesting for blockquotes or a newline character.**": false
    },
    "Empty Line Around Code Fences": {
      "Ensures that there is an empty line around code fences unless they start or end a document.": false
    },
    "Empty Line Around Tables": {
      "Ensures that there is an empty line around github flavored tables unless they start or end a document.": false
    },
    "Heading blank lines": {
      "All headings have a blank line both before and after (except where the heading is at the beginning or end of the document).": true,
      "Bottom": true,
      "Empty Line Between Yaml and Header": true
    },
    "Line Break at Document End": {
      "Ensures that there is exactly one line break at the end of a document.": false
    },
    "Paragraph blank lines": {
      "All paragraphs should have exactly one blank line both before and after.": true
    },
    "Remove Empty Lines Between List Markers and Checklists": {
      "There should not be any empty lines between list markers and checklists.": true
    },
    "Remove link spacing": {
      "Removes spacing around link text.": false
    },
    "Remove Space around Fullwidth Characters": {
      "Ensures that fullwidth characters are not followed by whitespace (either single spaces or a tab). Note that this may causes issues with markdown format in some cases.": false
    },
    "Space after list markers": {
      "There should be a single space after list markers and checkboxes.": true
    },
    "Trailing spaces": {
      "Removes extra spaces after every line.": false,
      "Two Space Linebreak": false
    },
    "Space between Chinese Japanese or Korean and English or numbers": {
      "Ensures that Chinese, Japanese, or Korean and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)": false
    },
    "Force YAML Escape": {
      "Escapes the values for the specified YAML keys.": false,
      "Force YAML Escape on Keys": ""
    },
    "Headings Start Line": {
      "Headings that do not start a line will have their preceding whitespace removed to make sure they get recognized as headers.": false
    },
    "Remove Trailing Punctuation in Heading": {
      "Removes the specified punctuation from the end of headings making sure to ignore the semicolon at the end of [HTML entity references](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references).": false,
      "Trailing Punctuation": ".,;:!。,;:!"
    },
    "Auto-correct Common Misspellings": {
      "Uses a dictionary of common misspellings to automatically convert them to their proper spellings. See [auto-correct map](https://github.com/platers/obsidian-linter/tree/master/src/utils/auto-correct-misspellings.ts) for the full list of auto-corrected words.": false,
      "Ignore Words": ""
    },
    "Empty Line Around Math Blocks": {
      "Ensures that there is an empty line around math blocks using `Number of Dollar Signs to Indicate a Math Block` to determine how many dollar signs indicates a math block for single-line math.": false
    },
    "Move Math Block Indicators to Their Own Line": {
      "Move all starting and ending math block indicators to their own lines using `Number of Dollar Signs to Indicate a Math Block` to determine how many dollar signs indicates a math block for single-line math.": false
    },
    "Remove Space around Characters": {
      "Ensures that certain characters are not surrounded by whitespace (either single spaces or a tab). Note that this may causes issues with markdown format in some cases.": false,
      "Include Fullwidth Forms": true,
      "Include CJK Symbols and Punctuation": true,
      "Include Dashes": true,
      "Other symbols": ""
    },
    "Add Blockquote Indentation on Paste": {
      "Adds blockquotes to all but the first line, when the cursor is in a blockquote/callout line during pasting": false
    },
    "Prevent Double Checklist Indicator on Paste": {
      "Removes starting checklist indicator from the text to paste if the line the cursor is on in the file has a checklist indicator": false
    },
    "Prevent Double List Item Indicator on Paste": {
      "Removes starting list indicator from the text to paste if the line the cursor is on in the file has a list indicator": false
    },
    "Proper Ellipsis on Paste": {
      "Replaces three consecutive dots with an ellipsis even if they have a space between them in the text to paste": false
    },
    "Remove Hyphens on Paste": {
      "Removes hyphens from the text to paste": false
    },
    "Remove Leading or Trailing Whitespace on Paste": {
      "Removes any leading non-tab whitespace and all trailing whitespace for the text to paste": false
    },
    "Remove Leftover Footnotes from Quote on Paste": {
      "Removes any leftover footnote references for the text to paste": false
    },
    "Remove Multiple Blank Lines on Paste": {
      "Condenses multiple blank lines down into one blank line for the text to paste": false
    }
  },
  "lintOnSave": true,
  "recordLintOnSaveLogs": false,
  "displayChanged": true,
  "foldersToIgnore": [
    ".obsidian/",
    "Templates"
  ],
  "linterLocale": "system-default",
  "logLevel": 4,
  "lintCommands": [],
  "customRegexes": [],
  "commonStyles": {
    "aliasArrayStyle": "multi-line",
    "tagArrayStyle": "single-line",
    "minimumNumberOfDollarSignsToBeAMathBlock": 2,
    "escapeCharacter": "\"",
    "removeUnnecessaryEscapeCharsForMultiLineArrays": false
  }
}

Expected Behavior

Expected output if applicable:

Screenshots

Device

Additional Context

pjkaufman commented 1 year ago

I will see about testing this later this week, but I am not sure which part of the YAML you are saying is valid, but that the YAML parser is saying is invalid.

To test this, I will try parsing the YAML block directly using what you have provided. But I will note that tags seems invalid as it does not look like a valid single line or multiline key:

tag: 永久笔记
#当前卡片所用的模板

It would look like the following if it were a multiline array:

tag: 
  - 永久笔记
  - #当前卡片所用的模板
mengshang918 commented 1 year ago

Thanks for such a quick reply, when I deleted #当前卡片所用的模板, no error was reported. But in v1.6.0 this is no problem. Below is the data.json of v1.6.0

{
  "ruleConfigs": {
    "Escape YAML Special Characters": {
      "Escapes colons with a space after them (: ), single quotes ('), and double quotes (\") in YAML.": false,
      "Default Escape Character": "\"",
      "Try to Escape Single Line Arrays": false,
      "Force Yaml Escape on Keys": ""
    },
    "Format Tags in YAML": {
      "Remove Hashtags from tags in the YAML frontmatter, as they make the tags there invalid.": true
    },
    "Format Yaml Array": {
      "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.": false,
      "Yaml aliases section style": "single-line",
      "Format yaml aliases section": true,
      "Yaml tags section style": "single-line",
      "Format yaml tags section": true,
      "Default yaml array section style": "single-line",
      "Format yaml array sections": true,
      "Force key values to be single-line arrays": "",
      "Force key values to be multi-line arrays": ""
    },
    "Insert YAML attributes": {
      "Inserts the given YAML attributes into the YAML frontmatter. Put each attribute on a single line.": true,
      "Text to insert": "aliases: \ntag: "
    },
    "Move Tags to Yaml": {
      "Move all tags to Yaml frontmatter of the document.": false,
      "Yaml tags section style": "single-line",
      "Remove the hashtag from tags in content body": false,
      "Tags to ignore": ""
    },
    "Remove YAML Keys": {
      "Removes the YAML keys specified": false,
      "YAML Keys to Remove": ""
    },
    "YAML Key Sort": {
      "Sorts the YAML keys based on the order and priority specified. Note: may remove blank lines as well.": false,
      "YAML Key Priority Sort Order": "",
      "Priority Keys at Start of YAML": true,
      "YAML Sort Order for Other Keys": "None"
    },
    "YAML Timestamp": {
      "Keep track of the date the file was last edited in the YAML front matter. Gets dates from file metadata.": true,
      "Date Created": true,
      "Date Created Key": "date created",
      "Date Modified": true,
      "Date Modified Key": "date modified",
      "Format": "YYYY-MM-DD HH:mm a"
    },
    "YAML Title": {
      "Inserts the title of the file into the YAML frontmatter. Gets the title from the first H1 or filename if there is no H1.": false,
      "Title Key": "aliases",
      "Inserts the title of the file into the YAML frontmatter. Gets the title from the first H1 or filename.": true
    },
    "YAML Title Alias": {
      "Inserts the title of the file into the YAML frontmatter's aliases section. Gets the title from the first H1 or filename.": true,
      "YAML aliases section style": "Multi-line array",
      "Preserve existing aliases section style": true,
      "Keep alias that matches the filename": false,
      "Use the YAML key `linter-yaml-title-alias` to help with filename and heading changes": true
    },
    "Capitalize Headings": {
      "Headings should be formatted with capitalization": true,
      "Style": "Title Case",
      "Ignore Cased Words": true,
      "Ignore Words": "macOS, iOS, iPhone, iPad, JavaScript, TypeScript, AppleScript",
      "Lowercase Words": "via, a, an, the, and, or, but, for, nor, so, yet, at, by, in, of, on, to, up, as, is, if, it, for, to, with, without, into, onto, per"
    },
    "File Name Heading": {
      "Inserts the file name as a H1 heading if no H1 heading exists.": true
    },
    "Header Increment": {
      "Heading levels should only increment by one level at a time": true
    },
    "Footnote after Punctuation": {
      "Ensures that footnote references are placed after punctuation, not before.": true
    },
    "Move Footnotes to the bottom": {
      "Move all footnotes to the bottom of the document.": true
    },
    "Re-Index Footnotes": {
      "Re-indexes footnote keys and footnote, based on the order of occurrence (NOTE: This rule deliberately does *not* preserve the relation between key and footnote, to be able to re-index duplicate keys.)": false,
      "Re-indexes footnote keys and footnote, based on the order of occurence (NOTE: This rule deliberately does *not* preserve the relation between key and footnote, to be able to re-index duplicate keys.)": false
    },
    "Convert Bullet List Markers": {
      "Converts common bullet list marker symbols to markdown list markers.": true
    },
    "Emphasis Style": {
      "Makes sure the emphasis style is consistent.": true,
      "Style": "asterisk"
    },
    "No Bare URLs": {
      "Encloses bare URLs with angle brackets except when enclosed in back ticks, square braces, or single or double quotes.": true
    },
    "Ordered List Style": {
      "Makes sure that ordered lists follow the style specified. Note that 2 spaces or 1 tab is considered to be an indentation level.": true,
      "Number Style": "lazy",
      "Ordered List Indicator End Style": "."
    },
    "Proper Ellipsis": {
      "Replaces three consecutive dots with an ellipsis.": false
    },
    "Remove Consecutive List Markers": {
      "Removes consecutive list markers. Useful when copy-pasting list items.": false
    },
    "Remove Empty List Markers": {
      "Removes empty list markers, i.e. list items without content.": false
    },
    "Remove Hyphenated Line Breaks": {
      "Removes hyphenated line breaks. Useful when pasting text from textbooks.": false
    },
    "Remove Multiple Spaces": {
      "Removes two or more consecutive spaces. Ignores spaces at the beginning and ending of the line. ": true
    },
    "Strong Style": {
      "Makes sure the strong style is consistent.": true,
      "Style": "asterisk"
    },
    "Two Spaces Between Lines with Content": {
      "Makes sure that two spaces are added to the ends of lines with content continued on the next line for paragraphs, blockquotes, and list items": true
    },
    "Unordered List Style": {
      "Makes sure that unordered lists follow the style specified.": true,
      "List item style": "-"
    },
    "Compact YAML": {
      "Removes leading and trailing blank lines in the YAML front matter.": true,
      "Inner New Lines": true
    },
    "Consecutive blank lines": {
      "There should be at most one consecutive blank line.": true
    },
    "Convert Spaces to Tabs": {
      "Converts leading spaces to tabs.": true,
      "Tabsize": "2"
    },
    "Empty Line Around Blockquotes": {
      "Ensures that there is an empty line around blockquotes unless they start or end a document. **Note that an empty line is either one less level of nesting for blockquotes or a newline character.**": false
    },
    "Empty Line Around Code Fences": {
      "Ensures that there is an empty line around code fences unless they start or end a document.": false
    },
    "Empty Line Around Tables": {
      "Ensures that there is an empty line around github flavored tables unless they start or end a document.": false
    },
    "Heading blank lines": {
      "All headings have a blank line both before and after (except where the heading is at the beginning or end of the document).": true,
      "Bottom": true,
      "Empty Line Between Yaml and Header": true
    },
    "Line Break at Document End": {
      "Ensures that there is exactly one line break at the end of a document.": false
    },
    "Paragraph blank lines": {
      "All paragraphs should have exactly one blank line both before and after.": true
    },
    "Remove Empty Lines Between List Markers and Checklists": {
      "There should not be any empty lines between list markers and checklists.": true
    },
    "Remove link spacing": {
      "Removes spacing around link text.": false
    },
    "Remove Space around Fullwidth Characters": {
      "Ensures that fullwidth characters are not followed by whitespace (either single spaces or a tab). Note that this may causes issues with markdown format in some cases.": false
    },
    "Space after list markers": {
      "There should be a single space after list markers and checkboxes.": true
    },
    "Space between Chinese and English or numbers": {
      "Ensures that Chinese and English or numbers are separated by a single space. Follows these [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)": false,
      "Ensures that Chinese and English or numbers are separated by a single space. Follow this [guidelines](https://github.com/sparanoid/chinese-copywriting-guidelines)": true
    },
    "Trailing spaces": {
      "Removes extra spaces after every line.": false,
      "Two Space Linebreak": false
    }
  },
  "lintOnSave": true,
  "displayChanged": true,
  "foldersToIgnore": [
    ".obsidian/",
    "Templates"
  ],
  "linterLocale": "system-default",
  "logLevel": 4,
  "lintCommands": []
}

invalid

---
#请输入卡片别名
aliases: 
#请输入卡片涉及的标签
tag: 永久笔记
#当前卡片所用的模板
template: Templates/ZK/卡片笔记模板
#该卡片创建日期 用于dataview插件查询过滤
created: 2023-03-13
date created: 2023-03-13 10:50 上午
---

valid

---
#请输入卡片别名
aliases: 
#请输入卡片涉及的标签
#当前卡片所用的模板
template: Templates/ZK/卡片笔记模板
#该卡片创建日期 用于dataview插件查询过滤
created: 2023-03-13
date created: 2023-03-13 10:50 上午
---

or

---
#请输入卡片别名
aliases: 
#请输入卡片涉及的标签
tag: 永久笔记
template: Templates/ZK/卡片笔记模板
#该卡片创建日期 用于dataview插件查询过滤
created: 2023-03-13
date created: 2023-03-13 10:50 上午
---
pjkaufman commented 1 year ago

Looks like the issue is with the underlying parser, but I could be wrong. The reason v1.6.0 may not have had a problem is because how it parsed the YAML was different. We now rely even more on a js-yaml for parsing values. So if they do not support a YAML format or have a bug, it will not really be feasible to make it work with the Linter.