yeet
This commit is contained in:
159
.config/emacs/modules/lang/markdown/README.org
Normal file
159
.config/emacs/modules/lang/markdown/README.org
Normal file
@@ -0,0 +1,159 @@
|
||||
#+TITLE: lang/markdown
|
||||
#+DATE: February 19, 2017
|
||||
#+SINCE: 2.0
|
||||
#+STARTUP: inlineimages
|
||||
|
||||
* Table of Contents :TOC_3:noexport:
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#linters][Linters]]
|
||||
- [[#markdown-preview][Markdown preview]]
|
||||
- [[#markedjs][MarkedJS]]
|
||||
- [[#pandoc][Pandoc]]
|
||||
- [[#markdown][Markdown]]
|
||||
- [[#multimarkdown][MultiMarkdown]]
|
||||
- [[#features][Features]]
|
||||
- [[#markdown-preview-1][Markdown preview]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#changing-how-markdown-is-compiled][Changing how markdown is compiled]]
|
||||
|
||||
* Description
|
||||
This module provides Markdown support for Emacs.
|
||||
|
||||
#+begin_quote
|
||||
Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you
|
||||
to write using an easy-to-read, easy-to-write plain text format, then convert it
|
||||
to structurally valid XHTML (or HTML).
|
||||
|
||||
Thus, “Markdown” is two things: (1) a plain text formatting syntax; and (2) a
|
||||
software tool, written in Perl, that converts the plain text formatting to HTML.
|
||||
See the Syntax page for details pertaining to Markdown’s formatting syntax. You
|
||||
can try it out, right now, using the online Dingus.
|
||||
|
||||
The overriding design goal for Markdown’s formatting syntax is to make it as
|
||||
readable as possible. The idea is that a Markdown-formatted document should be
|
||||
publishable as-is, as plain text, without looking like it’s been marked up with
|
||||
tags or formatting instructions. While Markdown’s syntax has been influenced by
|
||||
several existing text-to-HTML filters, the single biggest source of inspiration
|
||||
for Markdown’s syntax is the format of plain text email. -- John Gruber
|
||||
#+end_quote
|
||||
|
||||
** Module Flags
|
||||
+ =+grip= Enables [[https://github.com/seagle0128/grip-mode][grip support]] (on =<localleader> p=), to provide live
|
||||
github-style previews of your markdown (or org) files.
|
||||
|
||||
** Plugins
|
||||
+ markdown-mode
|
||||
+ markdown-toc
|
||||
|
||||
** Hacks
|
||||
+ Flyspell has been configured not to spell check in code blocks, links, HTML
|
||||
tags or references.
|
||||
|
||||
* Prerequisites
|
||||
This module has two soft dependencies: a linter and a compiler (for previewing
|
||||
markdown).
|
||||
|
||||
** Linters
|
||||
Out of the box, flycheck recognizes these checkers for markdown-mode and
|
||||
gfm-mode:
|
||||
|
||||
+ Markdown-specific
|
||||
+ [[https://github.com/DavidAnson/markdownlint][markdownlint]] (~npm install markdownlint~)
|
||||
+ [[https://github.com/markdownlint/markdownlint][mdl]] (~gem install mdl~)
|
||||
+ General (natural language)
|
||||
+ [[http://proselint.com/][proselint]]
|
||||
- ~pip install proselint~
|
||||
- Or through your OS package manager
|
||||
- MacOS: ~brew install proselint~
|
||||
- Arch Linux: ~pacman -S proselint~
|
||||
+ [[https://github.com/textlint/textlint][textlint]] (~npm install textlint~)
|
||||
|
||||
** Markdown preview
|
||||
This module requires a markdown compiler in order for ~markdown-preview~ to
|
||||
work. It will recognize and use one of the following executables, in this order
|
||||
(you only need one):
|
||||
|
||||
+ [[https://github.com/markedjs/marked][markedjs]]: a markdown compiler "built for speed"
|
||||
+ [[https://github.com/jgm/pandoc][pandoc]]: the universal markup transpiler
|
||||
+ [[http://pell.portland.or.us/~orc/Code/discount/][markdown]]: there are various flavors of this compiler. This module will look
|
||||
for these two:
|
||||
+ John Gruber's [[https://daringfireball.net/projects/markdown/][original perl script]]
|
||||
+ The C implementation called [[http://pell.portland.or.us/~orc/Code/discount/][discount]], by David Parsons
|
||||
+ [[https://fletcher.github.io/MultiMarkdown-6/][multimarkdown]]: a compiler for a language that is a superset of Markdown, with
|
||||
additional output formats and features.
|
||||
|
||||
*** MarkedJS
|
||||
Not to be confused with [[https://marked2app.com/][the Marked 2 app]], marked is an npm package:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
npm install -g marked
|
||||
#+END_SRC
|
||||
|
||||
*** Pandoc
|
||||
Pandoc is the universal markup transpiler. It should be available through your
|
||||
system package manager. For example:
|
||||
|
||||
+ MacOS: ~brew install pandoc~
|
||||
+ Arch Linux: ~pacman -S pandoc~
|
||||
|
||||
*** Markdown
|
||||
The C implementation of Markdown.pl, called =discount=, is available through
|
||||
your OS's package manager:
|
||||
|
||||
+ MacOS: ~brew install discount~
|
||||
+ Arch Linux: ~pacman -S discount~
|
||||
|
||||
The original perl script that discount is inspired from can be found on [[https://daringfireball.net/projects/markdown/][John
|
||||
Gruber's website]].
|
||||
|
||||
*** MultiMarkdown
|
||||
See [[https://fletcher.github.io/MultiMarkdown-6/introduction.html][its documentation]] for details on what MultiMarkdown is. The compiler can be
|
||||
installed through your OS's package manager:
|
||||
|
||||
+ MacOS: ~brew install multimarkdown~
|
||||
+ Arch Linux: [[https://aur.archlinux.org/packages/multimarkdown/][multimarkdown]] is available on the AUR
|
||||
|
||||
* Features
|
||||
** Markdown preview
|
||||
~markdown-preview~ is bound to =<localleader> p=. This will open a preview of
|
||||
your compiled markdown document in your browser.
|
||||
|
||||
Alternatively, you can use ~grip-mode~ through =+grip=.
|
||||
|
||||
* Configuration
|
||||
** Changing how markdown is compiled
|
||||
When ~markdown-preview~ is invoked (=<localleader> p=) it consults
|
||||
~markdown-command~. Its default value (~#'+markdown-compile~) will consult
|
||||
~+markdown-compile-functions~: a list of functions that take three arguments: the
|
||||
start and end point in the current buffer to use as input, and an output buffer
|
||||
to insert the result in.
|
||||
|
||||
By default, the value of ~+markdown-compile-functions~ is:
|
||||
|
||||
#+BEGIN_SRC lisp
|
||||
'(+markdown-compile-marked
|
||||
+markdown-compile-pandoc
|
||||
+markdown-compile-markdown
|
||||
+markdown-compile-multimarkdown)
|
||||
#+END_SRC
|
||||
|
||||
These functions will attempt to use the marked, pandoc and markdown executables,
|
||||
if available. Changing this variable will control how markdown is compiled.
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
;; Add a new one
|
||||
(add-hook '+markdown-compile-functions #'my-compile-function)
|
||||
|
||||
;; Or remove an existing one
|
||||
(remove-hook '+markdown-compile-functions #'+markdown-compile-markdown)
|
||||
#+END_SRC
|
||||
|
||||
Otherwise, you can change ~markdown-command~ directly:
|
||||
|
||||
#+BEGIN_SRC elisp
|
||||
(setq markdown-command "markdown | smartypants")
|
||||
#+END_SRC
|
||||
107
.config/emacs/modules/lang/markdown/autoload.el
Normal file
107
.config/emacs/modules/lang/markdown/autoload.el
Normal file
@@ -0,0 +1,107 @@
|
||||
;;; lang/markdown/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-flyspell-word-p ()
|
||||
"Return t if `flyspell' should check word before point.
|
||||
|
||||
Used for `flyspell-generic-check-word-predicate'. Like
|
||||
`markdown-flyspell-check-word-p', but also:
|
||||
|
||||
a) Performs spell check in code comments and
|
||||
b) Inhibits spell check in html markup"
|
||||
(save-excursion
|
||||
(goto-char (1- (point)))
|
||||
(if (or (and (markdown-code-block-at-point-p)
|
||||
(not (or (markdown-text-property-at-point 'markdown-yaml-metadata-section)
|
||||
(markdown--face-p (point) '(font-lock-comment-face)))))
|
||||
(markdown-inline-code-at-point-p)
|
||||
(markdown-in-comment-p)
|
||||
(markdown--face-p (point) '(markdown-reference-face
|
||||
markdown-markup-face
|
||||
markdown-plain-url-face
|
||||
markdown-inline-code-face
|
||||
markdown-url-face
|
||||
markdown-html-attr-name-face
|
||||
markdown-html-attr-value-face
|
||||
markdown-html-tag-name-face)))
|
||||
(prog1 nil
|
||||
;; If flyspell overlay is put, then remove it
|
||||
(let ((bounds (bounds-of-thing-at-point 'word)))
|
||||
(when bounds
|
||||
(cl-loop for ov in (overlays-in (car bounds) (cdr bounds))
|
||||
when (overlay-get ov 'flyspell-overlay)
|
||||
do
|
||||
(delete-overlay ov)))))
|
||||
t)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Compilation handlers
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-compile (beg end output-buffer)
|
||||
"Compile markdown into html.
|
||||
|
||||
Runs `+markdown-compile-functions' until the first function to return non-nil,
|
||||
otherwise throws an error."
|
||||
(or (run-hook-with-args-until-success '+markdown-compile-functions
|
||||
beg end output-buffer)
|
||||
(user-error "No markdown program could be found. Install marked, pandoc, markdown or multimarkdown.")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-compile-marked (beg end output-buffer)
|
||||
"Compiles markdown with the marked program, if available.
|
||||
Returns its exit code."
|
||||
(when (executable-find "marked")
|
||||
(apply #'call-process-region
|
||||
beg end "marked" nil output-buffer nil
|
||||
(when (eq major-mode 'gfm-mode)
|
||||
(list "--gfm" "--tables" "--breaks")))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-compile-pandoc (beg end output-buffer)
|
||||
"Compiles markdown with the pandoc program, if available.
|
||||
Returns its exit code."
|
||||
(when (executable-find "pandoc")
|
||||
(call-process-region beg end "pandoc" nil output-buffer nil
|
||||
"-f" "markdown"
|
||||
"-t" "html"
|
||||
"--mathjax"
|
||||
"--highlight-style=pygments")))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-compile-multimarkdown (beg end output-buffer)
|
||||
"Compiles markdown with the multimarkdown program, if available. Returns its
|
||||
exit code."
|
||||
(when (executable-find "multimarkdown")
|
||||
(call-process-region beg end "multimarkdown" nil output-buffer)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown-compile-markdown (beg end output-buffer)
|
||||
"Compiles markdown using the Markdown.pl script (or markdown executable), if
|
||||
available. Returns its exit code."
|
||||
(when-let (exe (or (executable-find "Markdown.pl")
|
||||
(executable-find "markdown")))
|
||||
(call-process-region beg end exe nil output-buffer nil)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +markdown/insert-del ()
|
||||
"Surround region in github strike-through delimiters."
|
||||
(interactive)
|
||||
(let ((regexp "\\(^\\|[^\\]\\)\\(\\(~\\{2\\}\\)\\([^ \n \\]\\|[^ \n ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)")
|
||||
(delim "~~"))
|
||||
(if (markdown-use-region-p)
|
||||
;; Active region
|
||||
(cl-destructuring-bind (beg . end)
|
||||
(markdown-unwrap-things-in-region
|
||||
(region-beginning) (region-end)
|
||||
regexp 2 4)
|
||||
(markdown-wrap-or-insert delim delim nil beg end))
|
||||
;; Bold markup removal, bold word at point, or empty markup insertion
|
||||
(if (thing-at-point-looking-at regexp)
|
||||
(markdown-unwrap-thing-at-point nil 2 4)
|
||||
(markdown-wrap-or-insert delim delim 'word nil nil)))))
|
||||
141
.config/emacs/modules/lang/markdown/config.el
Normal file
141
.config/emacs/modules/lang/markdown/config.el
Normal file
@@ -0,0 +1,141 @@
|
||||
;;; lang/markdown/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +markdown-compile-functions
|
||||
'(+markdown-compile-marked
|
||||
+markdown-compile-pandoc
|
||||
+markdown-compile-markdown
|
||||
+markdown-compile-multimarkdown)
|
||||
"A list of commands to try when attempting to build a markdown file with
|
||||
`markdown-open' or `markdown-preview', stopping at the first one to return non-nil.
|
||||
|
||||
Each function takes three argument. The beginning position of the region to
|
||||
capture, the end position, and the output buffer.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! markdown-mode
|
||||
:mode ("/README\\(?:\\.md\\)?\\'" . gfm-mode)
|
||||
:init
|
||||
(setq markdown-enable-math t ; syntax highlighting for latex fragments
|
||||
markdown-enable-wiki-links t
|
||||
markdown-italic-underscore t
|
||||
markdown-asymmetric-header t
|
||||
markdown-gfm-additional-languages '("sh")
|
||||
markdown-make-gfm-checkboxes-buttons t
|
||||
|
||||
;; HACK Due to jrblevin/markdown-mode#578, invoking `imenu' throws a
|
||||
;; 'wrong-type-argument consp nil' error if you use native-comp.
|
||||
markdown-nested-imenu-heading-index (not (ignore-errors (native-comp-available-p)))
|
||||
|
||||
;; `+markdown-compile' offers support for many transpilers (see
|
||||
;; `+markdown-compile-functions'), which it tries until one succeeds.
|
||||
markdown-command #'+markdown-compile
|
||||
;; This is set to `nil' by default, which causes a wrong-type-arg error
|
||||
;; when you use `markdown-open'. These are more sensible defaults.
|
||||
markdown-open-command
|
||||
(cond (IS-MAC "open")
|
||||
(IS-LINUX "xdg-open"))
|
||||
|
||||
;; A sensible and simple default preamble for markdown exports that
|
||||
;; takes after the github asthetic (plus highlightjs syntax coloring).
|
||||
markdown-content-type "application/xhtml+xml"
|
||||
markdown-css-paths
|
||||
'("https://cdn.jsdelivr.net/npm/github-markdown-css/github-markdown.min.css"
|
||||
"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release/build/styles/github.min.css")
|
||||
markdown-xhtml-header-content
|
||||
(concat "<meta name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no'>"
|
||||
"<style> body { box-sizing: border-box; max-width: 740px; width: 100%; margin: 40px auto; padding: 0 10px; } </style>"
|
||||
"<script id='MathJax-script' async src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'></script>"
|
||||
"<script src='https://cdn.jsdelivr.net/gh/highlightjs/cdn-release/build/highlight.min.js'></script>"
|
||||
"<script>document.addEventListener('DOMContentLoaded', () => { document.body.classList.add('markdown-body'); document.querySelectorAll('pre[lang] > code').forEach((code) => { code.classList.add(code.parentElement.lang); }); document.querySelectorAll('pre > code').forEach((code) => { hljs.highlightBlock(code); }); });</script>"))
|
||||
|
||||
;; A shorter alias for org src blocks than "markdown"
|
||||
(after! org-src
|
||||
(add-to-list 'org-src-lang-modes '("md" . markdown)))
|
||||
|
||||
:config
|
||||
(set-flyspell-predicate! '(markdown-mode gfm-mode)
|
||||
#'+markdown-flyspell-word-p)
|
||||
(set-lookup-handlers! '(markdown-mode gfm-mode)
|
||||
;; `markdown-follow-thing-at-point' may open an external program or a
|
||||
;; buffer. No good way to tell, so pretend it's async.
|
||||
:file '(markdown-follow-thing-at-point :async t))
|
||||
|
||||
(sp-local-pair '(markdown-mode gfm-mode) "`" "`"
|
||||
:unless '(:add sp-point-before-word-p sp-point-before-same-p))
|
||||
|
||||
;; Highly rust blocks correctly
|
||||
(when (featurep! :lang rust)
|
||||
(add-to-list 'markdown-code-lang-modes '("rust" . rustic-mode)))
|
||||
|
||||
;; Don't trigger autofill in code blocks (see `auto-fill-mode')
|
||||
(setq-hook! 'markdown-mode-hook
|
||||
fill-nobreak-predicate (cons #'markdown-code-block-at-point-p
|
||||
fill-nobreak-predicate))
|
||||
|
||||
;; HACK Prevent mis-fontification of YAML metadata blocks in `markdown-mode'
|
||||
;; which occurs when the first line contains a colon in it. See
|
||||
;; jrblevin/markdown-mode#328.
|
||||
(defadvice! +markdown-disable-front-matter-fontification-a (&rest _)
|
||||
:override #'markdown-match-generic-metadata
|
||||
(ignore (goto-char (point-max))))
|
||||
|
||||
(map! :map markdown-mode-map
|
||||
:localleader
|
||||
"'" #'markdown-edit-code-block
|
||||
"o" #'markdown-open
|
||||
"p" #'markdown-preview
|
||||
"e" #'markdown-export
|
||||
(:when (featurep! +grip)
|
||||
"p" #'grip-mode)
|
||||
(:prefix ("i" . "insert")
|
||||
:desc "Table Of Content" "T" #'markdown-toc-generate-toc
|
||||
:desc "Image" "i" #'markdown-insert-image
|
||||
:desc "Link" "l" #'markdown-insert-link
|
||||
:desc "<hr>" "-" #'markdown-insert-hr
|
||||
:desc "Heading 1" "1" #'markdown-insert-header-atx-1
|
||||
:desc "Heading 2" "2" #'markdown-insert-header-atx-2
|
||||
:desc "Heading 3" "3" #'markdown-insert-header-atx-3
|
||||
:desc "Heading 4" "4" #'markdown-insert-header-atx-4
|
||||
:desc "Heading 5" "5" #'markdown-insert-header-atx-5
|
||||
:desc "Heading 6" "6" #'markdown-insert-header-atx-6
|
||||
:desc "Code block" "C" #'markdown-insert-gfm-code-block
|
||||
:desc "Pre region" "P" #'markdown-pre-region
|
||||
:desc "Blockquote region" "Q" #'markdown-blockquote-region
|
||||
:desc "Checkbox" "[" #'markdown-insert-gfm-checkbox
|
||||
:desc "Bold" "b" #'markdown-insert-bold
|
||||
:desc "Inline code" "c" #'markdown-insert-code
|
||||
:desc "Italic" "e" #'markdown-insert-italic
|
||||
:desc "Footnote" "f" #'markdown-insert-footnote
|
||||
:desc "Header dwim" "h" #'markdown-insert-header-dwim
|
||||
:desc "Italic" "i" #'markdown-insert-italic
|
||||
:desc "Kbd" "k" #'markdown-insert-kbd
|
||||
:desc "Link" "l" #'markdown-insert-link
|
||||
:desc "Pre" "p" #'markdown-insert-pre
|
||||
:desc "New blockquote" "q" #'markdown-insert-blockquote
|
||||
:desc "Strike through" "s" #'markdown-insert-strike-through
|
||||
:desc "Table" "t" #'markdown-insert-table
|
||||
:desc "Wiki link" "w" #'markdown-insert-wiki-link)))
|
||||
|
||||
(use-package! evil-markdown
|
||||
:when (featurep! :editor evil +everywhere)
|
||||
:hook (markdown-mode . evil-markdown-mode)
|
||||
:config
|
||||
(add-hook 'evil-markdown-mode-hook #'evil-normalize-keymaps)
|
||||
(map! :map evil-markdown-mode-map
|
||||
:n "TAB" #'markdown-cycle
|
||||
:n [backtab] #'markdown-shifttab
|
||||
:i "M-*" #'markdown-insert-list-item
|
||||
:i "M-b" #'markdown-insert-bold
|
||||
:i "M-i" #'markdown-insert-italic
|
||||
:i "M-`" #'+markdown/insert-del
|
||||
:i "M--" #'markdown-insert-hr
|
||||
:n "M-r" #'browse-url-of-file
|
||||
:m "]h" #'markdown-next-visible-heading
|
||||
:m "[h" #'markdown-previous-visible-heading
|
||||
:m "[p" #'markdown-promote
|
||||
:m "]p" #'markdown-demote
|
||||
:m "[l" #'markdown-previous-link
|
||||
:m "]l" #'markdown-next-link))
|
||||
22
.config/emacs/modules/lang/markdown/doctor.el
Normal file
22
.config/emacs/modules/lang/markdown/doctor.el
Normal file
@@ -0,0 +1,22 @@
|
||||
;; -*- lexical-binding: t; no-byte-compile: t; -*-
|
||||
;;; lang/markdown/doctor.el
|
||||
|
||||
(when (require 'markdown-mode nil t)
|
||||
(cond ((eq markdown-command #'+markdown-compile)
|
||||
(unless (cl-loop for (exe . cmd) in (list (cons "marked" '+markdown-compile-marked)
|
||||
(cons "pandoc" '+markdown-compile-pandoc)
|
||||
(cons "markdown" '+markdown-compile-markdown)
|
||||
(cons "multimarkdown" '+markdown-compile-multimarkdown))
|
||||
if (and (memq cmd +markdown-compile-functions)
|
||||
(executable-find exe))
|
||||
return t)
|
||||
(warn! "Couldn't find a markdown compiler, `markdown-preview' won't work")))
|
||||
((stringp markdown-command)
|
||||
(let ((cmd (car (split-string markdown-command " "))))
|
||||
(unless (executable-find cmd)
|
||||
(warn! "Couldn't find %S. markdown-preview command won't work"
|
||||
cmd))))))
|
||||
|
||||
(when (featurep! +grip)
|
||||
(unless (executable-find "grip")
|
||||
(warn! "Couldn't find grip. grip-mode will not work")))
|
||||
14
.config/emacs/modules/lang/markdown/packages.el
Normal file
14
.config/emacs/modules/lang/markdown/packages.el
Normal file
@@ -0,0 +1,14 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; lang/markdown/packages.el
|
||||
|
||||
(package! markdown-mode :pin "862ae8addd29bf6affca1a35fd0176cb0c1392da")
|
||||
(package! markdown-toc :pin "3d724e518a897343b5ede0b976d6fb46c46bcc01")
|
||||
(package! edit-indirect :pin "bdc8f542fe8430ba55f9a24a7910639d4c434422")
|
||||
|
||||
(when (featurep! +grip)
|
||||
(package! grip-mode :pin "1c82e27beec629514a8039e22f4f7c649e77ee2b"))
|
||||
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(package! evil-markdown
|
||||
:recipe (:host github :repo "Somelauw/evil-markdown")
|
||||
:pin "8e6cc68af83914b2fa9fd3a3b8472573dbcef477"))
|
||||
Reference in New Issue
Block a user