aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--generic/proof-config.el22
-rw-r--r--lib/unicode-tokens.el170
2 files changed, 159 insertions, 33 deletions
diff --git a/generic/proof-config.el b/generic/proof-config.el
index aca9ff8d..11ae77bf 100644
--- a/generic/proof-config.el
+++ b/generic/proof-config.el
@@ -601,8 +601,7 @@ Warning messages can come from proof assistant or from Proof General itself."
"*Face for showing active areas (clickable regions), outside of subterm markup."
:group 'proof-faces)
-
-;;; Compatibility: these are required for use in GNU Emacs/font-lock-keywords
+;;; Compatibility: these are required for use in onder GNU Emacs/font-lock-keywords
(defconst proof-face-compat-doc "Evaluates to a face name, for compatibility.")
(defconst proof-queue-face 'proof-queue-face proof-face-compat-doc)
(defconst proof-locked-face 'proof-locked-face proof-face-compat-doc)
@@ -620,6 +619,25 @@ Warning messages can come from proof assistant or from Proof General itself."
(defconst proof-active-area-face 'proof-active-area-face proof-face-compat-doc)
+;;
+;; Faces used by unicode-tokens.
+;;
+;; TODO: make these into faces but extract attributes
+;; to use in `unicode-tokens-annotation-translations'.
+;; Let that be dynamically changeable
+;; TODO: choose family acccording to likely architecture and what's available
+(defconst proof-script-font-face-attributes
+ '((t :family "Lucida Calligraphy"))
+ "Script font face")
+
+(defconst proof-fraktur-font-face-attributes
+ '((t :family "Lucida Blackletter"))
+ "Fraktur font face")
+
+
+
+
+
;;
;; START OF CONFIGURATION VARIABLES
diff --git a/lib/unicode-tokens.el b/lib/unicode-tokens.el
index 8b81fd6a..7d97a359 100644
--- a/lib/unicode-tokens.el
+++ b/lib/unicode-tokens.el
@@ -37,11 +37,10 @@
;; TODO:
;; -- add input methods for subscript/superscripts (further props in general)
-;; -- after change function so inserting control sequences works?
-;; -- long sub/sups should be sticky so typing inside inherits props
+;; -- after change function so inserting control sequences works? or other support
+;; -- one-char subs should not be sticky so doesn't extend
;; -- make property removal more accurate/patch in font-lock
;; -- disentangle Isabelle specific code
-;; -- liaise with font-lock to allow face setting (e.g., bold, italic)
;; -- perhaps separate out short-cut input method and don't use for tokens
;; -- cleanup insertion functions
;; -- investigate testing for an appropriate glyph
@@ -313,12 +312,18 @@ This function may only work reliably for GNU Emacs >= 23."
(quail-define-package
"Unicode tokens" "UTF-8" "u" t
"Unicode characters input method using application specific token names"
- nil t nil nil nil nil nil nil nil nil t)
+ nil t nil nil nil nil nil ; max shortest, could try t
+ nil nil nil t)
(defun unicode-tokens-map-ordering (s1 s2)
"Ordering on (car S1, car S2): order longer strings first."
(>= (length (car s1)) (length (car s2))))
+(defun unicode-tokens-propertise-after-quail (tostring)
+ (add-text-properties (- (point) (length tostring)) (point)
+ (list 'utoks tostring)))
+
+
(defun unicode-tokens-quail-define-rules ()
"Define the token and shortcut input rules.
Calculated from `unicode-tokens-token-name-alist' and
@@ -326,6 +331,10 @@ Calculated from `unicode-tokens-token-name-alist' and
Also sets `unicode-tokens-token-alist'."
(let ((unicode-tokens-quail-define-rules
(list 'quail-define-rules)))
+;; failed experiment (wrong place for rule/wrong type?): attempt to propertise
+;; after translation
+;; '((advice . unicode-tokens-propertise-after-quail
+;; (face . proof-declaration-name-face)))))
(let ((ulist (copy-list unicode-tokens-token-name-alist))
ustring tokname token)
;; sort in case of non-terminated token syntax (empty suffix)
@@ -390,28 +399,32 @@ Also sets `unicode-tokens-token-alist'."
(add-to-list 'format-alist unicode-tokens-format-entry)
(defconst unicode-tokens-ignored-properties
- '(vanilla type fontified face auto-composed)
+ '(vanilla type fontified face auto-composed
+ rear-nonsticky field inhibit-line-move-field-capture
+ utoks)
"Text properties to ignore when saving files.")
(defconst unicode-tokens-annotation-translations
- '((face (bold "bold") ;; NB: clashes with font lock!
- (default )) ;; not saved now, need another way
- (display ((raise 0.4) "superscript")
- ((raise -0.4) "subscript")
- ((raise 0.35) "superscript1")
- ((raise -0.35) "subscript1")
- ((raise -0.3) "idsubscript1")
- (default ))))
+ `((font-lock-face
+ (bold "bold")
+ (italic "italic")
+ (,proof-script-font-face-attributes "script")
+ (,proof-fraktur-font-face-attributes "frak")
+ (default ))
+ (display
+ ((raise 0.4) "superscript")
+ ((raise -0.4) "subscript")
+ ((raise 0.35) "superscript1")
+ ((raise -0.35) "subscript1")
+ ((raise -0.3) "idsubscript1")
+ (default ))))
(defun unicode-tokens-remove-properties (start end)
"Remove text properties we manage between START and END."
- ;; TODO: this is very approximate! It removes too much (face)
(remove-text-properties
- start end
- (mapcar 'car
- unicode-tokens-annotation-translations))
- ;; Let's put face back in from fontify
- (font-lock-fontify-buffer))
+ ;; NB: this is approximate and clashes with anyone else who
+ ;; looks after font-lock-face or display
+ start end (mapcar 'car unicode-tokens-annotation-translations)))
(defun unicode-tokens-tokens-to-unicode (&optional start end)
@@ -426,6 +439,8 @@ Also sets `unicode-tokens-token-alist'."
(setq unicode-tokens-next-control-token-seen-token nil)
(format-replace-strings unicode-tokens-token-alist nil (point-min)
(point-max))
+;; alternative experiment: store original tokens inside text properties
+;; (unicode-tokens-replace-strings-propertise unicode-tokens-token-alist)
(format-deannotate-region (point-min)
(point-max)
unicode-tokens-annotation-translations
@@ -453,12 +468,18 @@ after next character (single character control sequence)."
((tok (match-string 1))
(annot
(cond
- ((equal tok "bsup") '("superscript" t))
- ((equal tok "esup") '("superscript" nil))
- ((equal tok "bsub") '("subscript" t))
- ((equal tok "esub") '("subscript" nil))
- ((equal tok "bbold") '("bold" t))
- ((equal tok "ebold") '("bold" nil))
+ ((equal tok "bsup") '("superscript" t))
+ ((equal tok "esup") '("superscript" nil))
+ ((equal tok "bsub") '("subscript" t))
+ ((equal tok "esub") '("subscript" nil))
+ ((equal tok "bbold") '("bold" t))
+ ((equal tok "ebold") '("bold" nil))
+ ((equal tok "bitalic") '("italic" t))
+ ((equal tok "eitalic") '("italic" nil))
+ ((equal tok "bscript") '("script" t))
+ ((equal tok "escript") '("script" nil))
+ ((equal tok "bfrak") '("frak" t))
+ ((equal tok "efrak") '("frak" nil))
((equal tok "sup")
(list (setq unicode-tokens-next-control-token-seen-token
"superscript1") t))
@@ -474,12 +495,16 @@ after next character (single character control sequence)."
(list (match-beginning 0) (match-end 0))
annot)))))
result))
-
+
+;; TODO: this should be instance specific
(defconst unicode-tokens-annotation-control-token-alist
- '(("bold" . ("bbold" . "ebold"))
- ("subscript" . ("bsub" . "esub"))
- ("superscript" . ("bsup" . "esup"))
- ("subscript1" . ("sub"))
+ '(("bold" . ("bbold" . "ebold"))
+ ("italic" . ("bitalic" . "eitalic"))
+ ("script" . ("bscript" . "escript"))
+ ("frak" . ("bfrak" . "efrak"))
+ ("subscript" . ("bsub" . "esub"))
+ ("superscript" . ("bsup" . "esup"))
+ ("subscript1" . ("sub"))
("superscript1" . ("sup"))))
(defun unicode-tokens-make-token-annotation (annot positive)
@@ -493,6 +518,38 @@ after next character (single character control sequence)."
(format unicode-tokens-control-token-format (cdr toks)))
(t ""))))
+(defun unicode-tokens-find-property (name)
+ (let ((props unicode-tokens-annotation-translations)
+ prop vals val vname)
+ (catch 'return
+ (while props
+ (setq prop (caar props))
+ (setq vals (cdar props))
+ (while vals
+ (setq val (car vals))
+ (if (member name (cdr val))
+ (throw 'return (list prop (car val))))
+ (setq vals (cdr vals)))
+ (setq props (cdr props))))))
+
+(defun unicode-tokens-annotate-region (beg end &optional type)
+ (interactive "r")
+ (or type
+ (if (interactive-p)
+ (setq type
+ (completing-read "Annotate region as: "
+ unicode-tokens-annotation-control-token-alist
+ nil t))
+ (error "In unicode-tokens-annotation-control-token-alist: TYPE must be given.")))
+ (add-text-properties beg end
+ (unicode-tokens-find-property type)))
+
+
+
+
+
+
+
(defun unicode-tokens-unicode-to-tokens (&optional start end buffer)
"Encode a buffer to save as a tokenised file."
(let ((case-fold-search proof-case-fold-search)
@@ -506,10 +563,61 @@ after next character (single character control sequence)."
unicode-tokens-annotation-translations
'unicode-tokens-make-token-annotation
unicode-tokens-ignored-properties))
- (format-replace-strings unicode-tokens-ustring-alist nil (point-min) (point-max))
+ (unicode-tokens-replace-strings-unpropertise)
+ ;; was: format-replace-strings unicode-tokens-ustring-alist nil (point-min) (point-max))
(set-buffer-modified-p modified)))))
+(defun unicode-tokens-replace-strings-propertise (alist &optional beg end)
+ "Do multiple replacements on the buffer.
+ALIST is a list of (FROM . TO) pairs, which should be proper arguments to
+`search-forward' and `replace-match', respectively.
+The original contents FROM are retained in the buffer in the text property `utoks'.
+Optional args BEG and END specify a region of the buffer on which to operate."
+ (save-excursion
+ (save-restriction
+ (or beg (setq beg (point-min)))
+ (if end (narrow-to-region (point-min) end))
+ (while alist
+ (let ((from (car (car alist)))
+ (to (cdr (car alist))))
+ (goto-char beg)
+ (while (search-forward from nil t)
+ (goto-char (match-beginning 0))
+ (insert to)
+ (set-text-properties (- (point) (length to)) (point)
+ (cons 'utoks
+ (cons from
+ (text-properties-at (point)))))
+ (delete-region (point) (+ (point) (- (match-end 0)
+ (match-beginning 0)))))
+ (setq alist (cdr alist)))))))
+
+;; NB: this is OK, except that now if we edit with raw symbols, we
+;; don't get desired effect but instead rely on hidden annotations.
+;; Also doesn't work as easily with quail.
+;; Can we have a sensible mixture of both things?
+(defun unicode-tokens-replace-strings-unpropertise (&optional beg end)
+ "Reverse the effect of `unicode-tokens-replace-strings-unpropertise'.
+Replaces contiguous text with 'utoks' property with property value."
+ (let ((pos (or beg (point-min)))
+ (lim (or end (point-max)))
+ start to)
+ (save-excursion
+ (while (and
+ (setq pos (next-single-property-change pos 'utoks nil lim))
+ (< pos lim))
+ (if start
+ (progn
+ (setq to (get-text-property start 'utoks))
+ (goto-char start)
+ (insert to)
+ (set-text-properties start (point)
+ (text-properties-at start))
+ (delete-region (point) (+ (point) (- pos start)))
+ (setq start nil))
+ (setq start pos))))))
+