branch: elpa/typst-ts-mode commit 6fc7f2ece7b803298caa7a4ff452e5831d793d6f Merge: b1eb84cd2a e0542e3e42 Author: Huan Thieu Nguyen <nguyenthieuh...@gmail.com> Commit: Huan Thieu Nguyen <nguyenthieuh...@gmail.com>
Merge branch 'develop' into 42-nongnu-patch --- typst-ts-compile.el | 12 +++- typst-ts-faces.el | 146 ++++++++++++++++++++++++++++++++++++------------- typst-ts-mode.el | 54 +++++++++++++++++- typst-ts-watch-mode.el | 10 ++-- 4 files changed, 175 insertions(+), 47 deletions(-) diff --git a/typst-ts-compile.el b/typst-ts-compile.el index 9347ac1326..d397a7246b 100644 --- a/typst-ts-compile.el +++ b/typst-ts-compile.el @@ -35,6 +35,11 @@ The compile options will be passed to the end of `<typst-executable> compile <current-file>' command." :type 'string) +(defcustom typst-ts-output-directory "" + "User defined output directory for `typst-ts-compile` and `typst-ts-watch`." + :type 'string + :group 'typst-ts) + (defcustom typst-ts-compile-before-compilation-hook nil "Hook runs after compile." :type 'hook) @@ -76,9 +81,10 @@ When using a prefix argument or the optional argument PREVIEW, (add-hook 'compilation-finish-functions (typst-ts-compile--compilation-finish-function (current-buffer))) (compile - (format "%s compile %s %s" + (format "%s compile %s %s %s" typst-ts-compile-executable-location (file-name-nondirectory buffer-file-name) + (typst-ts-compile-get-result-pdf-filename) typst-ts-compile-options) 'typst-ts-compilation-mode)) @@ -88,8 +94,8 @@ If BUFFER is nil, it means use the current buffer. CHECK: non-nil mean check the file existence. Return nil if the BUFFER has not associated file or the there is no compiled pdf file when CHECK is non-nil." - (when-let* ((typst-file (buffer-file-name buffer))) - (let ((res (concat (file-name-base typst-file) ".pdf"))) + (when-let ((typst-file (buffer-file-name buffer))) + (let ((res (concat (file-name-as-directory typst-ts-output-directory) (file-name-base typst-file) ".pdf"))) (if check (when (file-exists-p res) res) diff --git a/typst-ts-faces.el b/typst-ts-faces.el index 8fe82a002e..5f09186585 100644 --- a/typst-ts-faces.el +++ b/typst-ts-faces.el @@ -45,177 +45,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 973b9fc3c1..001e0f8cce 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -73,6 +73,18 @@ NOTE this option must be set before the first loading(opening typst file)" :type 'boolean) ;; ============================================================================== +;; 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 (defvar typst-ts-mode-syntax-table @@ -214,9 +226,16 @@ NOTE this option must be set before the first loading(opening typst file)" '((math "$" @typst-ts-math-indicator-face)) :language 'typst - :feature 'math-standard + :feature 'math-standard ; part 1 '((symbol) @font-lock-constant-face (letter) @font-lock-constant-face) + + :language 'typst + :feature 'math-standard ; part 2 + :override 'append + '((attach + ["^" "_"] @typst-ts-script-char-face + (_) @typst-ts-mode-render-math-scripts-fn)) :language 'typst :feature 'math-extended @@ -229,6 +248,38 @@ 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)) + (add-face-text-property + ns ne + 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 @@ -636,6 +687,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 diff --git a/typst-ts-watch-mode.el b/typst-ts-watch-mode.el index a27e90107b..c2c337fac7 100644 --- a/typst-ts-watch-mode.el +++ b/typst-ts-watch-mode.el @@ -126,10 +126,12 @@ PROC: process; OUTPUT: new output from PROC." (apply start-process typst-ts-watch-process-name typst-ts-watch-process-buffer-name - typst-ts-compile-executable-location "watch" - (file-name-nondirectory buffer-file-name) - typst-ts-watch-options) - #'typst-ts--watch-process-filter) + (format "%s watch %s %s %s" + typst-ts-compile-executable-location + (file-name-nondirectory buffer-file-name) + (typst-ts-compile-get-result-pdf-filename) + typst-ts-watch-options)) + 'typst-ts--watch-process-filter) (message "Start Watch")) ;;;###autoload