Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for rendering atx headers in the margin #274

Closed
wants to merge 9 commits into from
76 changes: 74 additions & 2 deletions markdown-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,45 @@ promotion and demotion functions."
:group 'markdown
:type 'boolean)

(defcustom markdown-marginalize-header nil
"When non-nil, put opening atx header markup in a left margin.

This setting goes well with `markdown-asymmetric-header'. But
sadly it conflicts with `linum-mode' since they both use the
same margin."
:group 'markdown
:type 'boolean)

(defconst markdown-marginalize-margin-chars-needed 7
"Number of characters needed for marginalized headers.

This is distinct from the size of the left margin, as measured in
a number of text-sized characters, which is needed for rendering
atx headers in header-sized characters into that margin.")

(defcustom markdown-marginalize-header-in-header-face nil
"When non-nil, render marginalized atx header markup in header face.

If enabled, and if your header face is larger than the text face,
then you will likely need also to customize
`markdown-marginalize-header-margin-size' to ensure it is big
enough to show the header marks. That is because this mode is not
smart enough to calculate the margin needed in text-sized
characters for header-sized strings. Sorry!"
:group 'markdown
:type 'boolean)

(defcustom markdown-marginalize-header-margin-size 7
"Size of the window left margin, for marginalized atx headers.

The default, 7, is a suitable number if
`markdown-marginalize-header-in-header-face' is nil. If it is
non-nil, then you may need to experiment with increasing this
number to a larger value, like 10 or 20, to ensure the margin is
large enough to render your marginalized headers."
:group 'markdown
:type 'integer)

(defcustom markdown-asymmetric-header nil
"Determines if atx header style will be asymmetric.
Set to a non-nil value to use asymmetric header styling, placing
Expand Down Expand Up @@ -3993,15 +4032,43 @@ Group 7: closing filename delimiter"

;;; Markdown Font Fontification Functions =====================================

(defun generate-margin-string (margin-width heading-char-count)
"Generate string to place in the left margin.

The string has length MARGIN-WIDTH - 1 and has HEADING-CHAR-COUNT
heading characters."
(let* ((margin-left-space-count (- margin-width heading-char-count))
(margin-string (concat (make-string margin-left-space-count ? )
(make-string heading-char-count ?#))))
margin-string))

(defun markdown-marginalize-update-current ()
"Update the window configuration to create a left margin."
(set-window-margins nil markdown-marginalize-header-margin-size))

(defun markdown-fontify-headings (last)
"Add text properties to headings from point to LAST."
(when (markdown-match-propertized-text 'markdown-heading last)
(let* ((level (markdown-outline-level))
(heading-face
(intern (format "markdown-header-face-%d" level)))
(heading-props `(face ,heading-face))
(markup-props `(face markdown-header-delimiter-face
,@(when markdown-hide-markup `(display ""))))
(markup-props
(if markdown-marginalize-header
;; plist of text property for atx header
;; when markdown-marginalize-header
`(
;; maybe render characters in the header face
,@(when markdown-marginalize-header-in-header-face
`(face ,heading-face))
;; definitely place in the margin
display ((margin left-margin)
,(generate-margin-string
markdown-marginalize-margin-chars-needed level)))

;; plist defining text properties of normal atx headers
`(face markdown-header-delimiter-face
,@(when markdown-hide-markup `(display "")))))
(rule-props `(face markdown-header-rule-face
,@(when markdown-hide-markup `(display "")))))
(if (match-end 1)
Expand Down Expand Up @@ -9054,6 +9121,11 @@ position."
#'markdown--edit-indirect-after-commit-function
nil 'local)

(when markdown-marginalize-header
(add-hook 'window-configuration-change-hook
'markdown-marginalize-update-current nil t)
)

;; add live preview export hook
(add-hook 'after-save-hook #'markdown-live-preview-if-markdown t t)
(add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t))
Expand Down