Skip to content

Commit

Permalink
Simplfy header marginalization
Browse files Browse the repository at this point in the history
Make header marginalization compatible with markup hiding.

Remove markdown-marginalize-header-in-header-face.  Always use
markdown-header-delimiter-face instead.

Remove markdown-marginalize-header-margin-size.  Calculate the
required margin size on the fly based on character width of
markdown-header-delimiter-face.

generate-margin-string pollutes global namespace; rename to
markdown--marginalize-string instead.

Rename defcustom to markdown-marginalize-headers and declare safe as
boolean.

Sharp quote function in add-hook.

Update documentation and CHANGES.md.
  • Loading branch information
jrblevin committed Oct 18, 2017
1 parent 39a0c57 commit 0167557
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 63 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
- GFM task list item (checkbox) insertion with `C-c C-s [`, or
as a final fallback for `markdown-do` (`C-c C-d`). Thanks to
Akinori Musha for a patch. ([GH-229][])
- Optionally move leading atx heading markup to the left margin
when `markdown-marginalize-headers` is non-`nil`. Thanks to
Alexis Gallagher for a patch. ([GH-272][], [GH-274][])

* Improvements:

Expand Down Expand Up @@ -51,6 +54,8 @@
[gh-261]: https://github.com/jrblevin/markdown-mode/pull/261
[gh-262]: https://github.com/jrblevin/markdown-mode/pull/262
[gh-263]: https://github.com/jrblevin/markdown-mode/pull/263
[gh-272]: https://github.com/jrblevin/markdown-mode/issues/272
[gh-274]: https://github.com/jrblevin/markdown-mode/pull/274

# Markdown Mode 2.3

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,12 @@ provides an interface to all of the possible customizations:
used when `markdown-header-scaling` is non-nil
(default: `(2.0 1.7 1.4 1.1 1.0 1.0)`).

* `markdown-marginalize-headers` - put opening atx header markup
in the left margin when non-nil (default: `nil`).

* `markdown-marginalize-headers-margin-width` - width of margin
used for marginalized headers (default: 6).

* `markdown-list-indent-width` - depth of indentation for lists
when inserting, promoting, and demoting list items (default: 4).

Expand Down
116 changes: 53 additions & 63 deletions markdown-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,12 @@
;; used when `markdown-header-scaling' is non-nil
;; (default: `(2.0 1.7 1.4 1.1 1.0 1.0)`).
;;
;; * `markdown-marginalize-headers' - put opening atx header markup
;; in the left margin when non-nil (default: `nil').
;;
;; * `markdown-marginalize-headers-margin-width' - width of margin
;; used for marginalized headers (default: 6).
;;
;; * `markdown-list-indent-width' - depth of indentation for lists
;; when inserting, promoting, and demoting list items (default: 4).
;;
Expand Down Expand Up @@ -1087,44 +1093,27 @@ promotion and demotion functions."
:group 'markdown
:type 'boolean)

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

This setting goes well with `markdown-asymmetric-header'. But
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."
:type 'boolean
:safe 'booleanp
:package-version '(markdown-mode . "2.4"))

(defcustom markdown-marginalize-headers-margin-width 6
"Character width of margin used for marginalized headers.
The default value is based on there being six heading levels
defined by Markdown and HTML. Increasing this produces extra
whitespace on the left. Decreasing it may be preferred when
fewer than six nested heading levels are used."
:group 'markdown
:type 'integer)
:type 'natnump
:safe 'natnump
:package-version '(markdown-mode . "2.4"))

(defcustom markdown-asymmetric-header nil
"Determines if atx header style will be asymmetric.
Expand Down Expand Up @@ -4027,19 +4016,25 @@ 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-string (level)
"Generate atx markup string of given LEVEL for left margin."
(let ((margin-left-space-count
(- markdown-marginalize-headers-margin-width level)))
(concat (make-string margin-left-space-count ? )
(make-string level ?#))))

(defun markdown-marginalize-update-current ()
"Update the window configuration to create a left margin."
(set-window-margins nil markdown-marginalize-header-margin-size))
;; Emacs 25 or later is needed for window-font-width and default-font-width.
(if (and (fboundp 'window-font-width) (fboundp 'default-font-width))
(let* ((header-delimiter-font-width
(window-font-width nil 'markdown-header-delimiter-face))
(margin-pixel-width (* markdown-marginalize-headers-margin-width
header-delimiter-font-width))
(margin-char-width (/ margin-pixel-width (default-font-width))))
(set-window-margins nil margin-char-width))
;; As a fallback, simply set margin based on character count.
(set-window-margins nil markdown-marginalize-headers-margin-width)))

(defun markdown-fontify-headings (last)
"Add text properties to headings from point to LAST."
Expand All @@ -4048,22 +4043,17 @@ heading characters."
(heading-face
(intern (format "markdown-header-face-%d" level)))
(heading-props `(face ,heading-face))
(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 "")))))
(left-markup-props
`(face markdown-header-delimiter-face
,@(cond
(markdown-hide-markup
`(display ""))
(markdown-marginalize-headers
`(display ((margin left-margin)
,(markdown--marginalize-string level)))))))
(right-markup-props
`(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 All @@ -4077,12 +4067,12 @@ heading characters."
(match-beginning 3) (match-end 3) rule-props)))
;; atx heading
(add-text-properties
(match-beginning 4) (match-end 4) markup-props)
(match-beginning 4) (match-end 4) left-markup-props)
(add-text-properties
(match-beginning 5) (match-end 5) heading-props)
(when (match-end 6)
(add-text-properties
(match-beginning 6) (match-end 6) markup-props))))
(match-beginning 6) (match-end 6) right-markup-props))))
t))

(defun markdown-fontify-blockquotes (last)
Expand Down Expand Up @@ -9117,10 +9107,10 @@ position."
#'markdown--edit-indirect-after-commit-function
nil 'local)

(when markdown-marginalize-header
;; Marginalized headings
(when markdown-marginalize-headers
(add-hook 'window-configuration-change-hook
'markdown-marginalize-update-current nil t)
)
#'markdown-marginalize-update-current nil t))

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

0 comments on commit 0167557

Please sign in to comment.