branch: elpa/typst-ts-mode commit 34d522c0a0d8eec9a8b3a6855cf394e7d5c8fb84 Author: meowking <mr.meowk...@posteo.com> Commit: meowking <mr.meowk...@posteo.com>
feat: enhance fontification of sub/superscripts in math mode closes: https://codeberg.org/meow_king/typst-ts-mode/issues/43 --- typst-ts-faces.el | 146 +++++++++++++++++++++++++++++++++++++++--------------- typst-ts-mode.el | 47 +++++++++++++++++- 2 files changed, 153 insertions(+), 40 deletions(-) diff --git a/typst-ts-faces.el b/typst-ts-faces.el index ca956ee1d1..8a65994707 100644 --- a/typst-ts-faces.el +++ b/typst-ts-faces.el @@ -46,177 +46,245 @@ (defface typst-ts-shorthand-face '((t :inherit shadow)) - "Face for linebreak.") + "Face for linebreak." + :group 'typst-ts-faces) (defface typst-ts-error-face '((t :inherit font-lock-warning-face)) - "Face for linebreak.") + "Face for linebreak." + :group 'typst-ts-faces) ;; Markup Faces ================================================================= (defface typst-ts-markup-header-indicator-face '((t :weight bold)) - "Face for Typst ts markup header indicator.") + "Face for Typst ts markup header indicator." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face '((t :weight bold)) - "Face for Typst ts markup headers text.") + "Face for Typst ts markup headers text." + :group 'typst-ts-faces) (defface typst-ts-markup-header-indicator-face-1 `((t :inherit typst-ts-markup-header-indicator-face :height ,(nth 0 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-indicator-face'.") + "See `typst-ts-markup-header-indicator-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face-1 `((t :inherit typst-ts-markup-header-face :height ,(nth 0 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-face'.") + "See `typst-ts-markup-header-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-indicator-face-2 `((t :inherit typst-ts-markup-header-indicator-face :height ,(nth 1 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-indicator-face'.") + "See `typst-ts-markup-header-indicator-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face-2 `((t :inherit typst-ts-markup-header-face :height ,(nth 1 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-face'.") + "See `typst-ts-markup-header-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-indicator-face-3 `((t :inherit typst-ts-markup-header-indicator-face :height ,(nth 2 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-indicator-face'.") + "See `typst-ts-markup-header-indicator-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face-3 `((t :inherit typst-ts-markup-header-face :height ,(nth 2 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-face'.") + "See `typst-ts-markup-header-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-indicator-face-4 `((t :inherit typst-ts-markup-header-indicator-face :height ,(nth 3 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-indicator-face'.") + "See `typst-ts-markup-header-indicator-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face-4 `((t :inherit typst-ts-markup-header-face :height ,(nth 3 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-face'.") + "See `typst-ts-markup-header-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-indicator-face-5 `((t :inherit typst-ts-markup-header-indicator-face :height ,(nth 4 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-indicator-face'.") + "See `typst-ts-markup-header-indicator-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face-5 `((t :inherit typst-ts-markup-header-face :height ,(nth 4 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-face'.") + "See `typst-ts-markup-header-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-indicator-face-6 `((t :inherit typst-ts-markup-header-indicator-face :height ,(nth 5 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-indicator-face'.") + "See `typst-ts-markup-header-indicator-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-header-face-6 `((t :inherit typst-ts-markup-header-face :height ,(nth 5 typst-ts-markup-header-scale))) - "See `typst-ts-markup-header-face'.") + "See `typst-ts-markup-header-face'." + :group 'typst-ts-faces) (defface typst-ts-markup-url-face '((t :inherit link)) - "Face for url.") + "Face for url." + :group 'typst-ts-faces) (defface typst-ts-markup-emphasis-indicator-face '((t :inherit italic)) - "Face for emphasis.") + "Face for emphasis." + :group 'typst-ts-faces) (defface typst-ts-markup-emphasis-face '((t :inherit italic)) - "Face for emphasis.") + "Face for emphasis." + :group 'typst-ts-faces) (defface typst-ts-markup-strong-indicator-face '((t :inherit bold)) - "Face for strong.") + "Face for strong." + :group 'typst-ts-faces) (defface typst-ts-markup-strong-face '((t :inherit bold)) - "Face for strong.") + "Face for strong." + :group 'typst-ts-faces) (defface typst-ts-markup-item-indicator-face '((t :inherit shadow)) - "Face for item.") + "Face for item." + :group 'typst-ts-faces) (defface typst-ts-markup-term-indicator-face '((t :inherit shadow)) - "Face for term indicator.") + "Face for term indicator." + :group 'typst-ts-faces) (defface typst-ts-markup-term-term-face '((t :inherit bold)) - "Face for term text.") + "Face for term text." + :group 'typst-ts-faces) (defface typst-ts-markup-term-description-face '((t :inherit italic)) - "Face for term description.") + "Face for term description." + :group 'typst-ts-faces) (defface typst-ts-markup-quote-face '((t :inherit shadow)) - "Face for quote.") + "Face for quote." + :group 'typst-ts-faces) (defface typst-ts-markup-linebreak-face '((t :inherit escape-glyph)) - "Face for linebreak.") + "Face for linebreak." + :group 'typst-ts-faces) (defface typst-ts-markup-escape-face '((t :inherit escape-glyph)) - "Face for linebreak.") + "Face for linebreak." + :group 'typst-ts-faces) (defface typst-ts-markup-raw-indicator-face '((t :inherit shadow)) - "Face for rawblock and rawspan indicator.") + "Face for rawblock and rawspan indicator." + :group 'typst-ts-faces) (defface typst-ts-markup-raw-blob-face '((t :inherit shadow)) - "Face for rawblock and rawspan blob.") + "Face for rawblock and rawspan blob." + :group 'typst-ts-faces) (defface typst-ts-markup-rawblock-indicator-face '((t :inherit typst-ts-markup-raw-indicator-face)) - "Face for rawblock indicator.") + "Face for rawblock indicator." + :group 'typst-ts-faces) (defface typst-ts-markup-rawblock-lang-face '((t :inherit font-lock-type-face)) - "Face for rawspan ident.") + "Face for rawspan ident." + :group 'typst-ts-faces) (defface typst-ts-markup-rawblock-blob-face '((t :inherit typst-ts-markup-raw-blob-face)) - "Face for rawblock blob.") + "Face for rawblock blob." + :group 'typst-ts-faces) (defface typst-ts-markup-rawspan-indicator-face '((t :inherit typst-ts-markup-raw-indicator-face)) - "Face for rawspan indicator.") + "Face for rawspan indicator." + :group 'typst-ts-faces) (defface typst-ts-markup-rawspan-blob-face '((t :inherit typst-ts-markup-raw-blob-face)) - "Face for rawspan blob.") + "Face for rawspan blob." + :group 'typst-ts-faces) (defface typst-ts-markup-label-face '((t :inherit homoglyph)) - "Face for label.") + "Face for label." + :group 'typst-ts-faces) (defface typst-ts-markup-reference-face '((t :inherit homoglyph)) - "Face for reference.") + "Face for reference." + :group 'typst-ts-faces) ;; Code Faces =================================================================== (defface typst-ts-code-indicator-face '((t :inherit shadow)) - "Face for code indicator #.") + "Face for code indicator #." + :group 'typst-ts-faces) ;; Math Faces =================================================================== (defface typst-ts-math-indicator-face '((t :inherit shadow)) - "Face for math indicator $.") + "Face for math indicator $." + :group 'typst-ts-faces) + +;; code from Auctex +(defface typst-ts-superscript-face + '((t (:height 0.85))) + "Face used for superscripts." + :group 'typst-ts-faces) + +;; code from Auctex +(defface typst-ts-subscript-face + '((t (:height 0.85))) + "Face used for subscripts." + :group 'typst-ts-faces) + +;; code from Auctex +(defface typst-ts-script-char-face + (let ((font '(:inherit underline))) + `((((class grayscale) (background light)) + (:foreground "gray25" ,@font)) + (((class grayscale) (background dark)) + (:foreground "gray" ,@font)) + (((class color) (background light)) + (:foreground "DarkRed")) + (((class color) (background dark)) + (:foreground "salmon")) + (t (,@font)))) + "Face used for the script chars ^ and _." + :group 'typst-ts-faces) + + (provide 'typst-ts-faces) diff --git a/typst-ts-mode.el b/typst-ts-mode.el index d0247adc7f..94e01267f2 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -70,6 +70,17 @@ NOTE this option must be set before the first loading(opening typst file)" :type 'boolean :group 'typst-ts) +;; code from Auctex +(defcustom typst-ts-mode-math-script-display '((raise -0.5) . (raise 0.5)) + "Display specification for subscript and superscript content. +The car is used for subscript, the cdr is used for superscripts." + :type '(cons (choice (sexp :tag "Subscript form") + (const :tag "No lowering" nil)) + (choice (sexp :tag "Superscript form") + (const :tag "No raising" nil))) + :group 'typst-ts) + + ;; ============================================================================== ;; TODO typst has three modes (namely 'markup', 'code' and 'math') ;; Currently only add common settings to syntax table @@ -214,7 +225,10 @@ NOTE this option must be set before the first loading(opening typst file)" :language 'typst :feature 'math-standard '((symbol) @font-lock-constant-face - (letter) @font-lock-constant-face) + (letter) @font-lock-constant-face + (attach + ["^" "_"] @typst-ts-script-char-face + (_) @typst-ts-mode-render-math-scripts-fn)) :language 'typst :feature 'math-extended @@ -227,6 +241,36 @@ NOTE this option must be set before the first loading(opening typst file)" If you want to enable/disable specific font lock feature, please change `treesit-font-lock-level' or modify `typst-ts-mode-font-lock-feature-list'.") +;; modified from Auctex +(defun typst-ts-mode-unfontify-region (beg end &rest _ignored) + "Unfontify region from BEG to END." + (font-lock-default-unfontify-region beg end) + (while (< beg end) + (let ((next (next-single-property-change beg 'display nil end)) + (prop (get-text-property beg 'display))) + (when (and (eq (car-safe prop) 'raise) + (null (cddr prop))) + (remove-text-properties beg next '(display rear-nonsticky))) + (setq beg next)))) + + +(defun typst-ts-mode-render-math-scripts-fn (node override start end) + (let* ((ns (treesit-node-start node)) + (ne (treesit-node-end node)) + (prev-node-text (treesit-node-text (treesit-node-prev-sibling node))) + (display-properties (pcase prev-node-text + ("_" (car typst-ts-mode-math-script-display)) + ("^" (cdr typst-ts-mode-math-script-display)))) + (face (pcase prev-node-text + ("_" 'typst-ts-subscript-face) + ("^" 'typst-ts-superscript-face)))) + (add-text-properties + ns ne + `( + rear-nonsticky (display) + display ,display-properties + face ,face)))) + (defun typst-ts-mode-highlight-raw-block-fn (blob-node _override _start _end) "A function used in function `typst-ts-mode-font-lock-rules'. This function assign `typst-ts-markup-rawblock-blob-face' to those raw block @@ -632,6 +676,7 @@ typst tree sitter grammar (at least %s)!" (current-time-string min-time)) (treesit-major-mode-setup) + (setq-local font-lock-unfontify-region-function #'typst-ts-mode-unfontify-region) (setq-local indent-line-function #'typst-ts-mode-indent-line-function)) ;;;###autoload