Markdown Vscode



Markdown/CommonMark linting and style checking for Visual Studio Code

  1. Markdown的介绍大家可以参考上一篇文章;本文的目的,则是引导大家开始Markdown的写作。 1. 下载和安装vscode 1.1.
  2. Language Identifiers. In Visual Studio Code, each language mode has a unique specific language identifier. That identifier is rarely seen by the user except in the settings, for example, when associating file extensions to a language.

Intro

The Markdown markup language is designed to be easy to read, write, and understand. It succeeds - and its flexibility is both a benefit and a drawback. Many styles are possible, so formatting can be inconsistent. Some constructs don't work well in all parsers and should be avoided. For example, here are some common/troublesome Markdown constructs.

markdownlint is a Visual Studio Code extension that includes a library of rules to encourage standards and consistency for Markdown files. It is powered by markdownlint for Node.js which is based on markdownlint for Ruby.

Feb 20, 2020 Vim keybindings with VSCodeVim Flat markdown file storage on disk in a non-proprietary format, backed up and synced across devices with Google Backup and Sync, searchable with ripgrep, scriptable with bash, python, etc. It seems vscode does not support format markdown file by default. When I use the shortcut command + shift + f to format the markdown file. Vscode give me: Sorry, but there is no formatter for 'markdown'-files installed. Is there a way to format a markdown file without installing an extension?

Install

  1. Open Visual Studio Code
  2. Press Ctrl+P to open the Quick Open dialog
  3. Type ext install markdownlint to find the extension
  4. Click the Install button, then the Enable button

OR

  1. Press Ctrl+Shift+X to open the Extensions tab
  2. Type markdownlint to find the extension
  3. Click the Install button, then the Enable button

OR

  1. Open a command-line prompt
  2. Run code --install-extension DavidAnson.vscode-markdownlint

Use

When editing a Markdown file in Code with markdownlint installed, any lines that violate one of markdownlint's rules (see below) will trigger a Warning in the editor. Warnings are indicated by a wavy green underline and can also be seen by pressing Ctrl+Shift+M to open the Errors and Warnings dialog. Hover the mouse pointer over a green line to see the warning or press F8 and Shift+F8 to cycle through all the warnings (markdownlint warnings all begin with MD###). For more information about a markdownlint warning, place the cursor on a line and click the light bulb icon or press Ctrl+. to open the code action dialog. Clicking one of the warnings in the dialog will display that rule's help entry in the default web browser.

For a tutorial, please see Build an Amazing Markdown Editor Using Visual Studio Code and Pandoc by Dave Johnson.

Rules

  • MD001heading-increment/header-increment - Heading levels should only increment by one level at a time
  • ~~MD002first-heading-h1/first-header-h1 - First heading should be a top level heading~~
  • MD003heading-style/header-style - Heading style
  • MD004ul-style - Unordered list style
  • MD005list-indent - Inconsistent indentation for list items at the same level
  • ~~MD006ul-start-left - Consider starting bulleted lists at the beginning of the line~~
  • MD007ul-indent - Unordered list indentation
  • MD009no-trailing-spaces - Trailing spaces
  • MD010no-hard-tabs - Hard tabs
  • MD011no-reversed-links - Reversed link syntax
  • MD012no-multiple-blanks - Multiple consecutive blank lines
  • MD013line-length - Line length
  • MD014commands-show-output - Dollar signs used before commands without showing output
  • MD018no-missing-space-atx - No space after hash on atx style heading
  • MD019no-multiple-space-atx - Multiple spaces after hash on atx style heading
  • MD020no-missing-space-closed-atx - No space inside hashes on closed atx style heading
  • MD021no-multiple-space-closed-atx - Multiple spaces inside hashes on closed atx style heading
  • MD022blanks-around-headings/blanks-around-headers - Headings should be surrounded by blank lines
  • MD023heading-start-left/header-start-left - Headings must start at the beginning of the line
  • MD024no-duplicate-heading/no-duplicate-header - Multiple headings with the same content
  • MD025single-title/single-h1 - Multiple top level headings in the same document
  • MD026no-trailing-punctuation - Trailing punctuation in heading
  • MD027no-multiple-space-blockquote - Multiple spaces after blockquote symbol
  • MD028no-blanks-blockquote - Blank line inside blockquote
  • MD029ol-prefix - Ordered list item prefix
  • MD030list-marker-space - Spaces after list markers
  • MD031blanks-around-fences - Fenced code blocks should be surrounded by blank lines
  • MD032blanks-around-lists - Lists should be surrounded by blank lines
  • MD033no-inline-html - Inline HTML
  • MD034no-bare-urls - Bare URL used
  • MD035hr-style - Horizontal rule style
  • MD036no-emphasis-as-heading/no-emphasis-as-header - Emphasis used instead of a heading
  • MD037no-space-in-emphasis - Spaces inside emphasis markers
  • MD038no-space-in-code - Spaces inside code span elements
  • MD039no-space-in-links - Spaces inside link text
  • MD040fenced-code-language - Fenced code blocks should have a language specified
  • MD041first-line-heading/first-line-h1 - First line in file should be a top level heading
  • MD042no-empty-links - No empty links
  • MD043required-headings/required-headers - Required heading structure
  • MD044proper-names - Proper names should have the correct capitalization
  • MD045no-alt-text - Images should have alternate text (alt text)
  • MD046code-block-style - Code block style
  • MD047single-trailing-newline - Files should end with a single newline character
  • MD048code-fence-style - Code fence style

See markdownlint's Rules.md file for more details.

The following rules can be automatically fixed by moving the cursor to a rule violation (wavy underlined text) and typing Ctrl+. or clicking the light bulb icon.

  • MD004 ul-style
  • MD005 list-indent
  • MD006 ul-start-left
  • MD007 ul-indent
  • MD009 no-trailing-spaces
  • MD010 no-hard-tabs
  • MD011 no-reversed-links
  • MD012 no-multiple-blanks
  • MD014 commands-show-output
  • MD018 no-missing-space-atx
  • MD019 no-multiple-space-atx
  • MD020 no-missing-space-closed-atx
  • MD021 no-multiple-space-closed-atx
  • MD022 blanks-around-headings
  • MD023 heading-start-left
  • MD026 no-trailing-punctuation
  • MD027 no-multiple-space-blockquote
  • MD030 list-marker-space
  • MD031 blanks-around-fences
  • MD032 blanks-around-lists
  • MD034 no-bare-urls
  • MD037 no-space-in-emphasis
  • MD038 no-space-in-code
  • MD039 no-space-in-links
  • MD044 proper-names
  • MD047 single-trailing-newline

All violations of the above rules in the current document can be fixed at once by running the markdownlint.fixAll command, either from the Command Palette (via View|Command Palette... or Ctrl+Shift+P then search for 'markdownlint') or by binding the command to a keyboard shortcut.

To automatically fix these violations when saving a Markdown document, configure Visual Studio Code's editor.codeActionsOnSave setting like so:

Automatically-applied fixes can be reverted by Edit|Undo or Ctrl+Z.

To temporarily disable linting of Markdown documents, run the markdownlint.toggleLinting command (from the Command Palette or by binding it to a keyboard shortcut). To re-enable linting, run the markdownlint.toggleLinting command again.

Note: The effects of the markdownlint.toggleLinting command are reset when a new workspace is opened; linting defaults to enabled.

Configure

markdownlint.config

The default rule configuration disables MD013/line-length because many files include lines longer than the conventional 80 character limit:

Note: MD002/first-heading-h1 is disabled by default because it has been deprecated in the markdownlint library.

Rules can be enabled, disabled, and customized by creating a JSON file named .markdownlint.jsonc/.markdownlint.json/.markdownlintrc or a YAML file named .markdownlint.yaml/.markdownlint.yml in any directory of a project. The rules defined by .markdownlint{.jsonc,.json,.yaml,.yml,rc} apply to Markdown files in the same directory and any sub-directories without their own .markdownlint{.jsonc,.json,.yaml,.yml,rc}.

Note: .markdownlint{.jsonc,.json,.yaml,.yml,rc} is used only if a project has been opened. When no folder is open or a file is not part of the current project, normal user and workspace settings apply (see below). If multiple of these files are present in the same directory, .markdownlint.jsonc will be used instead of .markdownlint.json will be used instead of .markdownlint.yaml will be used instead of .markdownlint.yml will be used instead of .markdownlintrc.

A custom configuration is often defined by a .markdownlint.json file in the root of the project:

To extend another configuration file, any configuration file can use the extends property to provide a relative path:

Files referenced via extends do not need to be part of the current project (but usually are).

Rules can also be configured using Code's support for user and workspace settings.

The earlier configuration might look like the following in Code's user settings:

File paths referenced by extends from user settings are resolved relative to the user's home directory (ex: %USERPROFILE% on Windows or $HOME on macOS/Linux). File paths referenced by extends from workspace settings are resolved relative to the workspace folder.

Configuration locations have the following precedence (in decreasing order):

  • .markdownlint{.jsonc,.json,.yaml,.yml,rc} file in the same directory
  • .markdownlint{.jsonc,.json,.yaml,.yml,rc} file in a parent directory
  • .markdownlint{.jsonc,.json,.yaml,.yml,rc} file in the root of the project
  • Visual Studio Code user/workspace settings
  • Default configuration (see above)

Once a configuration is found, lower-precedence locations are ignored. Changes saved to any location take effect immediately. Files referenced via extends are not monitored for changes. Only the last two locations apply to files outside a project.

See markdownlint's options.config section for more information about rule configuration. See .markdownlint.jsonc and .markdownlint.yaml for example configurations with all properties set to the default value.

When a workspace is active, running the markdownlint.openConfigFile command (from the Command Palette or by binding it to a keyboard shortcut) will open an editor for the .markdownlint{.jsonc,.json,.yaml,.yml,rc} configuration file in the root of the workspace. If none of those files exist, .markdownlint.json will be created in the 'pending save' state and opened in the editor.

markdownlint.ignore

If a workspace contains generated content or other Markdown files that trigger warnings but cannot be fixed, it may be helpful to ignore (skip) those files when linting. This can be done by creating a file named .markdownlintignore in the root of the project or by updating the user/workspace configuration with a glob expression matching the relevant file names.

When using a .markdownlintignore file, the content of the file follows the rules for gitignore and may look something like:

An example of using Code's workspace configuration to ignore files might be:

The globbing library used for matching markdownlint.ignore configuration values is minimatch with the dot and nocomment options enabled. Matching is case-sensitive and paths are resolved relative to the root of the workspace. The directory separator is /, even on Windows.

markdownlint.run

By default, linting is performed as you type or edit a document. Linting is fast and efficient and should not interfere with typical workflows.

If you find this distracting, linting can be configured to run only when the document is saved. This looks like the following in Code's user settings:

Note: When configured to run onSave, the list of reported issues will become outdated while the document is edited and will update when the document is saved.

markdownlint.customRules

Custom rules can be specified in Code's user/workspace configuration to apply additional linting beyond the default set of rules. Custom rules are specified by the path to a JavaScript file or the path to an npm package exporting one rule or an array of rules.

Paths are normally relative to the root of the current workspace (or the Code install directory when no folder is open). Paths can also be absolute. When adding custom rules to a workspace, consider committing those rules under the .vscode directory where they will be separate from other workspace content and available to everyone who clones the repository.

Paths of the form {extension}/path are relative to the base directory of the Code extension named extension (which must already be installed). This syntax allows custom rules to be included within another extension's package and shared across multiple workspaces.

An example of Code's workspace settings for custom rules might look like the following:

To troubleshoot issues loading or running custom rules, please refer to diagnostic messages from the extension in Code's Output window.

For information about authoring custom rules, see markdownlint/CustomRules.

markdownlint.customRulesAlwaysAllow

A list of workspace paths for which the user's response to the custom rule prompt was 'Always allow'. This setting is updated automatically by the extension, but can be modified to reset the prompt for a workspace.

Note: This setting is only valid as a user setting, not as a workspace setting (where it could be set by a malicious workspace).

Suppress

Individual warnings can be suppressed with inline comments:

The following snippets are available to help (press Ctrl+Space for IntelliSense suggestions):

  • markdownlint-disable
  • markdownlint-enable
  • markdownlint-disable-next-line
  • markdownlint-capture
  • markdownlint-restore
  • markdownlint-disable-file
  • markdownlint-enable-file
  • markdownlint-configure-file

See markdownlint's configuration section for more details.

History

See CHANGELOG.md.

For many years, I have been using Google Docs was the primary repository for all of my notes, drafts, and journals.

Over the past few months, I’ve (1) heard lots of great reviews of new note-taking apps and (2) I have personally been using VS Code a lot more for writing code.

I recently evaluated all of the alternatives and landed on using a suped up VS Code as my primary notebook. This post details the how / why.

tldr; pros
  • Vim keybindings with VSCodeVim
  • Flat markdown file storage on disk in a non-proprietary format, backed up and synced across devices with Google Backup and Sync, searchable with ripgrep, scriptable with bash, python, etc
  • Extremely high level of customization possible via VS Code settings.json, keybindings.json, and Extension API (with TypeScript not Vimscript). I wrote an extension – VS Code Markdown Notes – to add some features I wanted
  • VS Code is free, open source, and has an awesome community of users
tldr; cons
  • No mobile app (see more on why I didn’t really care about this below)
  • No inline image previews / rich formatting of markdown (but there is a live preview side pane)
Outline
  • Suping Up VS Code as a Markdown notebook
    • Note Navigation with [[wiki-links]] and Tags Using my VS Code Markdown Notes Extension
      • Screenshots of the Features of My Extension
    • Alternatives

Suping Up VS Code as a Markdown notebook

Before I do a comparison of some alternative note-taking apps and talk about how I was using Google Docs for years, I’ll talk through the details of how I customized VS Code.

VSCode Vim Extension

One of the main features I wanted with my notebook was vim keybindings. The VSCodeVim Extension provides these.

How I Organize Notes

I basically organize notes into 2 types of files (similar to what I did on Goolge Docs), (1) a journal file for each year, where I record snippets, quotes, and transient thoughts and (2) dedicated topic / post / draft / note files, when there is a particular theme I want to collect a deeper set of organized thoughts around.

All of my notes are in a single workspace at $HOME/Google-Drive/_notebook and I don’t really use subdirectories to group them.

In the workspace settings ($HOME/Google-Drive/_notebook/.vscode/settings.json) I have turned on autoSave:

(1) Journals are in journal-YYYY.md files, one per year, with headings for each date I make an entry.

Markdown PDF - Visual Studio Marketplace

I have a snippet defined in settings.json with VSCodeVim normalMode keybinding:

(2) Longer notes and topics are in notes named topic-name.md in the main workspace folder (which you can see in the above screenshot in the File Explorer in the left Panel).

In my workspace settings ($HOME/Google-Drive/_notebook/.vscode/settings.json) I set the following so the most recently edited notes sort to the top of the File Explorer in the left Panel of VS Code:

Outline View

I also find it extremely helpful to have Outline view open in the File Explorer. This will show all the headings as a tree for easy navigation. By default, for some reason it is not sorted top to bottom, so I set the Sort By: Position setting:

Search Headings Across All files

Another feature I accidentally discovered was the ability to search for headings across all notes with the Command Pallette (cmd+p) and starting a query with the # character:

Global Hotkey to Open Notebook with Alfred

I want to be able to quickly open my notebook from any context, so I have a global hotkey (cmd+shift+o) bound to run the following bash command:

Note Navigation with cmd+p and keyword search

I mentioned I keep all of my notes in the top level of my notebook workspace rather than organizing into subdirectories.

This is because the main way I open notes is through the workbench.action.quickOpen VS Code keybinding (cmd+p):

Or with the workbench.view.search (cmd+shift+f), which is VERY fast:

Turn Off enablePreviewFromQuickOpen

To improve the functionality of the VSCodeVim jumplist (ctrl+o, ctrl+i) in settings.json I turned this off:

Markdown Vscode

Note Navigation with [[wiki-links]] and Tags Using my VS Code Markdown Notes Extension

A popular feature in Roam Research and Bear is the ability to quickly reference other notes using “Cross-Note Links” in the [[wiki-link]] style.

I wrote an extension – VS Code Markdown Notes which adds support for navigation with [[wiki-links]] and #tags.

This gets to my point about the extensibility of VS Code – the Extension API is really powerful and because all my notes are in flat files, it was a matter of a evening coding sessions to roll support for this stuff from scratch. I was even able to take advantage of the fact that VS Code is an IDE with support for things like function/keyword definitions to add bits of ‘flair’ like Peeking linked notes inline.

Screenshots of the Features of My Extension

Intellisense Completion for Wiki Links, uniqueFilenames
Intellisense Completion for Wiki Links, relativePaths
Syntax Highlighting for Tags and Wiki Links
Peek and Go to Definition for Wiki Links
cmd+shift+f to Search Workspace for Notes with #tag

NB: There was a similar VS Code Wiki that I tried out before writing this extension, but I didn’t love the way it still required the link destination in the (parens) after the link title and handle a few other details.

My next thought before building my own extension was I could just use the gf command from VSCodeVim to navigate to these files, which did work, but didn’t help with the autocompletion, syntax highlighting, previews, or tags.

Command and Keyboard Shortcut to Quickly Create New Notes

If The Image Isn't Rendering, In VSC It Needs An Extra Line After The Line Where The Image Is Instantiated, In Other Words It Can't Be An End Of Fi...

One of the features that people rave about in apps like(Notational Velocity, nvalt, Bear, FSNotes) is the “Search or Create” bar, which basically lands you into a search but allows you to quickly create a note if you don’t already have one.

This is sweet and I have not 100% replicated it yet.

I tried the VSNotes extension, but didn’t love the nesting of input boxes in the Command Pallette and the way it used frontmatter for tags (but it is certainly pretty thoughtful, offers a bunch of nice features, and is worth checking out – I think it was just a style thing for me).

OLD: I created a task and bash script to do this, which was OK.

UPDATE: I added a command to the VS Code Markdown Notes Extension that duplicates the functionality I had initially implemented as a workspace task.

I have it setup with a shortcut in my keybindings.json to open a prompt for a “Title Case NoteName” that will create title-case-note-name.md and add a heading:

Markdown All in One Extension

Markdown All in One is an extension I installed from the Marketplace that adds some nice conveniences like automatically starting newlines with a - character when you are adding to a list, shortcuts for creating a table of contents, additional support for reference links and Math functions, etc.

Code Spell Checker Extension

I tried a few different spell check extensions. Spell Right seemed to cause a ton of typing lag so I immediately uninstalled it.

Next I tried Code Spell Checker and it has been awesome.

I bound z= to open the Quick Fix to mirror the shortcut in Vim:

Image Preview Extension

Many apps like Bear and FSNotes have a better inline image preview render in the editor itself. With VS Code, while you can open the rendered Markdown Preview in a tab to the side, you cannot render images inline in the editor.

I don’t always love having the preview open, so I did a little searching and found the Image Preview extension which allows you to view a hover preview with cmd+k cmd+i:

I wanted the image to render as large as possible in the preview without scrolling and found this to be the max I could get working in settings.json:

Customize Colors of Block Quotes, Punctuation, Code, etc.

I use the Tomorrow Night Theme for VS Code, but wanted to mute the color of block quotes and some punctuation. I found some tips for how to really tweak markdown styles in VS Codehere on StackOverflow.

Here are the mods I made:

Manually Setting Modified Dates

After porting all of my journals from Google Docs, I wanted to backdate the modified dates. This was a good example of something I could easily do with bash since these are all flat files:

Notes on Mobile

For years, I was looking around for a notebook that had all the features I wanted on Desktop as wellas a way to edit notes on my phone. I never landed on a notes solution on my phone that I liked, and(even when I was using Google Docs, which does have a decent mobile editor)I ultimately always ended up reverting to just emailing myself notes on the go (typing as little aspossible) and then fleshing out these ideas when at a full keyboard. The two apps I use to emailmyself quick notes from my phone are Drafts andCaptio.

Drafts is a little more customizable, Captio has better support when offline / in airplane mode, soI kind of use both.

Alternatives

Google Docs

I was using Google Docs for all my notes for a long time. It has the best / most clear sync (very obvious when something doesn’t sync to cloud), a good mobile editor, good rich text / inline image support.

The killer feature is really the sharing + commenting and I will still use this to share a draft of a blog post to get comments and feedback before publishing.

It is kind of annoying that it’s not markdown, however, (since I use markdown for blog posts – my flow for translating a draft to a blog post was to copy everything from the Google Doc and then use Paste to Markdown to convert it.).

Also, importantly, Google Docs does not support Vim keybindings.

Also, I have a lot of other stuff in Docs that is not personal notes, so the search index was a little cluttered (but search in Docs is obviously great because it’s Google).

FSNotes

Of all the dedicated notes apps I tried, my favorite wasFSNotes. It self describes as:

File System notes (FSNotes): is modern notational velocity (nvALT) on steroids.

It has a kind of ‘coder ethos’ which I like. Everything is stored in plaintext, you can use textbundle if you want, it is backed by a git repo so you have version history, it is open source, and there is a mobile app.

By default it will use iCloud to sync and is pretty reliable (but you could also use Dropbox or Google Drive to sync as it is filesystem based).

There’s no inline image support (uses a side preview instead) and no vim keybindings.

It’s free.

Bear

Bear is pretty similar to FSNotes with slightly more visual design polish – for example the inline images look great, there is a web clipper, support for cross note linking and tags.

My main gripe with it was that it was backed by a sqlite database rather than flat files, which makes it a little harder to script.

Also, no vim keybindings.

There is a free version and paid version.

Roam Research

I have some friends that really love Roam. It’s very optimized for chunking notes as concepts and linking between them.

It feels very much more like a mind mapping tool / memory extension, designed for bullets and snippets, not as well suited to fleshing out these bits into longer form posts.

It is a web based app, not backed by the local filesystem.

Notational Velocity, nvalt

Notational Velocity andnvalt are some of the classic dedicated note taking apps.

They both have ways to very quickly find or create notes.

My main issue: no Vim keybindings.

Both are free.

Other VS Code Extensions

I looked at some of these but ultimately ended up not using:

  • VSCodeNotebook - port of the popular SublimeNotebook project.
  • VSNotes - adds some commands for quickly creating notes.

Instead I made the VS Code Markdown Notes extension.

It’s on github if you want to submit a PR or feature request.