branch: elpa/adoc-mode
commit 7a87ac9e5c9b584fd5e2b7dce0280ec0aff45d21
Author: Florian Kaufmann <sensor...@gmail.com>
Commit: Florian Kaufmann <sensor...@gmail.com>

    added customization var for delimited block regexps, added tests
    
    refactored functions generating font lock keywords for delimited blocks
---
 adoc-mode-test.el |  35 ++++++++++++
 adoc-mode.el      | 166 ++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 158 insertions(+), 43 deletions(-)

diff --git a/adoc-mode-test.el b/adoc-mode-test.el
index 3d3ddf59e9..f6e28688d5 100644
--- a/adoc-mode-test.el
+++ b/adoc-mode-test.el
@@ -21,6 +21,8 @@
   ;;  Lock Support Mode must be set to nil
   ;;  !!!!!!!!!!!!!
 
+  ;; todo: test for presence of adoc-reserved (we do white-box testing here)
+  
 
   ;; the white after = really is part of the delimiter
   (adoctest-make-buffer
@@ -63,6 +65,39 @@
    "chapter 4" markup-title-4-face "\n" nil
    "+++++++++" markup-meta-hide-face "\n" nil
    "\n" nil
+
+   "////////" markup-meta-hide-face "\n" nil
+   "comment line 1\ncomment line 2" markup-comment-face "\n" nil
+   "////////" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "++++++++" markup-meta-hide-face "\n" nil
+   "passthrouh line 1\npassthrouh line 2" markup-passthrough-face "\n" nil
+   "++++++++" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "--------" markup-meta-hide-face "\n" nil
+   "listing line 1\nlisting line 2" markup-code-face "\n" nil
+   "--------" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "........" markup-meta-hide-face "\n" nil
+   "literal line 1\nliteral line 2" markup-verbatim-face "\n" nil
+   "........" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "________" markup-meta-hide-face "\n" nil
+   "quote line 1\nquote line 2" nil "\n" nil
+   "________" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "========" markup-meta-hide-face "\n" nil
+   "example line 1\nexample line 2" nil "\n" nil
+   "========" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "********" markup-meta-hide-face "\n" nil
+   "sidebar line 1\nsidebar line 2" markup-secondary-text-face "\n" nil
+   "********" markup-meta-hide-face "\n" nil
+   "\n" nil
+   "--" markup-meta-hide-face "\n" nil
+   "open block line 1\nopen block line 2" nil "\n" nil
+   "--" markup-meta-hide-face "\n" nil
+   "\n" nil
    )
 
   (goto-char (point-min))
diff --git a/adoc-mode.el b/adoc-mode.el
index 869e5e0ccc..07ba7096a5 100644
--- a/adoc-mode.el
+++ b/adoc-mode.el
@@ -177,6 +177,58 @@ configuration file."
           (string :tag "level 4") )
   :group 'adoc)
 
+(defcustom adoc-delimited-block-del
+  '("^/\\{4,\\}"        ; 0 comment
+    "^\\+\\{4,\\}"      ; 1 pass
+    "^-\\{4,\\}"        ; 2 listing
+    "^\\.\\{4,\\}"      ; 3 literal
+    "^_\\{4,\\}"        ; 4 quote
+    "^=\\{4,\\}"        ; 5 example
+    "^\\*\\{4,\\}"      ; 6 sidebar
+    "^--")              ; 7 open block
+  "WITHOUT $!"
+  :type '(list
+         (choice :tag "comment"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+         (choice :tag "pass"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+         (choice :tag "listing"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+         (choice :tag "literal"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+         (choice :tag "quote"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+         (choice :tag "example"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+         (choice :tag "sidebar"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))
+          (choice :tag "open"
+                 (regexp :tag "start/end regexp")
+                 (list :tag "separate regexp"
+                       (regexp :tag "start regexp")
+                       (regexp :tag "end regexp")))))
+
 ;; todo: limit value range to 1 or 2
 (defcustom adoc-default-title-type 1
   "Default title type, see `adoc-title-descriptor'."
@@ -458,15 +510,23 @@ Subgroups:
     "^\\(\\)\\(.*[^ \t\n]\\)\\(:-\\)\\(\\)$")
    (t (error "Unknown type/level"))))
 
-;; Ala ^\*{4,}$
-(defun adoc-re-delimited-block-line (charset)
-  (concat "^\\(\\(" charset "\\)\\2\\{3,\\}\\)[ \t]*\n"))
+(defun adoc-re-delimited-block-line ()
+  (concat
+   "\\(?:"
+   (mapconcat
+    (lambda (x)
+      (concat "\\(?:" x "\\)[ \t]*$"))
+    adoc-delimited-block-del "\\|")
+   "\\)"))
 
 (defun adoc-re-delimited-block (del)
-  (concat
-   "\\(^" (regexp-quote del) "\\{4,\\}\\)[ \t]*\n"
-   "\\(\\(?:.*\n\\)*?\\)"
-   "\\(" (regexp-quote del) "\\{4,\\}\\)[ \t]*$"))
+  (let* ((tmp (nth del adoc-delimited-block-del))
+        (start (if (consp tmp) (car tmp) tmp))
+        (end (if (consp tmp) (cdr tmp) tmp)))
+    (concat
+     "\\(" start "\\)[ \t]*\n"
+     "\\(\\(?:.*\n\\)*?\\)"
+     "\\(" end "\\)[ \t]*$")))
 
 ;; TODO: since its multiline, it doesn't yet work properly.
 (defun adoc-re-verbatim-paragraph-sequence ()
@@ -650,6 +710,30 @@ subgroups:
          (style "[demshalv]"))
     (concat "\\(?:" fullspan "\\)?\\(?:" align "\\)?\\(?:" style "\\)?")))
 
+(defun adoc-kwf-std (end regexp &rest must-free-groups)
+  "Standart function for keywords
+
+Intendent to be called from font lock keyword functions. END is
+the limit of the search. REXEXP the regexp to be searched.
+MUST-FREE-GROUPS a list of regexp group numbers which may not
+match text that has an adoc-reserved text-property with a non-nil
+value."
+  (let ((found t) (prevented t) saved-point)
+    (while (and found prevented)
+      (setq saved-point (point))
+      (setq found (re-search-forward regexp end t))
+      (setq prevented ; prevented is only meaningfull wenn found is non-nil
+           (or (not found) ; the following is only needed when found
+               (some (lambda(x)
+                       (and (match-beginning x)
+                            (text-property-not-all (match-beginning 1)
+                                                   (match-end 1)
+                                                   'adoc-reserved nil)))
+                     must-free-groups)))
+      (when (and found prevented)
+       (goto-char (1+ saved-point))))
+    (and found (not prevented))))
+
 (defun adoc-facespec-subscript ()
   `(face adoc-subscript display (raise ,(nth 0 adoc-script-raise))))
 
@@ -686,14 +770,14 @@ subgroups:
   ;; macros
   ;; lists
   ;; blocks
-  ,(list (adoc-re-delimited-block "/") adoc-delimiter adoc-hide-delimiter 
adoc-comment adoc-delimiter adoc-hide-delimiter) ; comment
-  ,(list (adoc-re-delimited-block "+") adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; pass through
-  ,(list (adoc-re-delimited-block "-") adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; listing
-  ,(list (adoc-re-delimited-block ".") adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; literal
-  ,(list (adoc-re-delimited-block "*") adoc-delimiter adoc-hide-delimiter 
adoc-secondary-text adoc-delimiter adoc-hide-delimiter) ; sidebar
-  ,(list (adoc-re-delimited-block "_") adoc-delimiter adoc-hide-delimiter 
adoc-generic adoc-delimiter adoc-hide-delimiter) ; quote
-  ,(list (adoc-re-delimited-block "=") adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; example
-  ("^--[ \t]*$" adoc-delimiter)             ; open block
+  ,(list (adoc-re-delimited-block 0) adoc-delimiter adoc-hide-delimiter 
adoc-comment adoc-delimiter adoc-hide-delimiter) ; comment
+  ,(list (adoc-re-delimited-block 1) adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; pass through
+  ,(list (adoc-re-delimited-block 2) adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; listing
+  ,(list (adoc-re-delimited-block 3) adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; literal
+  ,(list (adoc-re-delimited-block 6) adoc-delimiter adoc-hide-delimiter 
adoc-secondary-text adoc-delimiter adoc-hide-delimiter) ; sidebar
+  ,(list (adoc-re-delimited-block 4) adoc-delimiter adoc-hide-delimiter 
adoc-generic adoc-delimiter adoc-hide-delimiter) ; quote
+  ,(list (adoc-re-delimited-block 5) adoc-delimiter adoc-hide-delimiter 
adoc-monospace adoc-delimiter adoc-hide-delimiter) ; example
+  ((nth 7 adoc-delimited-block-del) adoc-delimiter)             ; open block
   ;; tables OLD
   ;; tables 
   ;; block title
@@ -801,31 +885,28 @@ Concerning TYPE, LEVEL and SUB-TYPE see `adoc-re-llisti'."
     '(3 '(face adoc-list-item adoc-reserved t) t) 
     '(4 adoc-align t)))
 
-(defmacro adoc-kw-delimited-block (del text-face text-prop text-prop-val)
+(defun adoc-kw-delimited-block (del &optional text-face inhibit-text-reserved)
   "Creates a keyword for font-lock which highlights a delimited block."
-  `(list
-    ;; matcher function
-    (lambda (end)
-      (and (re-search-forward ,(adoc-re-delimited-block del) end t)
-           (not (text-property-not-all (match-beginning 1) (match-end 1) 
'adoc-reserved nil))
-           (not (text-property-not-all (match-beginning 3) (match-end 3) 
'adoc-reserved nil))))
-    ;; highlighers
-    '(0 '(face nil font-lock-multiline t) t)
-    '(1 '(face adoc-hide-delimiter adoc-reserved t) t)
-    '(2 '(face ,text-face ,text-prop ,text-prop-val) t)
-    '(3 '(face adoc-hide-delimiter adoc-reserved t) t)))
+  (list
+   `(lambda (end) (adoc-kwf-std end ,(adoc-re-delimited-block del) 1 3))
+   '(0 '(face nil font-lock-multiline t) t)
+   '(1 '(face markup-meta-hide-face adoc-reserved t) t)
+   (if (not inhibit-text-reserved)
+       `(2 '(face ,text-face adoc-reserved t) t)
+     `(2 ,text-face t))
+   '(3 '(face markup-meta-hide-face adoc-reserved t) t)))
 
 ;; if adoc-kw-delimited-block, adoc-kw-two-line-title don't find the whole
 ;; delimited block / two line title, at least 'use up' the delimiter line so it
 ;; is later not conused as a funny serries of unconstrained quotes
-(defmacro adoc-kw-delimtier-line-fallback (charset)
-  `(list
+(defun adoc-kw-delimtier-line-fallback ()
+  (list
     ;; matcher function
-    (lambda (end)
-      (and (re-search-forward ,(adoc-re-delimited-block-line charset) end t)
-           (not (text-property-not-all (match-beginning 1) (match-end 1) 
'adoc-reserved nil))))
+    `(lambda (end)
+      (and (re-search-forward ,(adoc-re-delimited-block-line) end t)
+           (not (text-property-not-all (match-beginning 0) (match-end 0) 
'adoc-reserved nil))))
     ;; highlighters
-    '(1 '(face adoc-hide-delimiter adoc-reserved t) t)))
+    '(0 '(face adoc-hide-delimiter adoc-reserved t) t)))
 
 ;; admonition paragraph. Note that there is also the style with the leading 
attribute list.
 ;; (?s)^\s*(?P<style>NOTE|TIP|IMPORTANT|WARNING|CAUTION):\s+(?P<text>.+)
@@ -1061,16 +1142,15 @@ When LITERAL-P is non-nil, the contained text is 
literal text."
 
    ;; Delimited blocks
    ;; ------------------------------
-   (adoc-kw-delimited-block "/" adoc-comment adoc-reserved t)   ; comment
-   (adoc-kw-delimited-block "+" adoc-monospace adoc-reserved t) ; passthrough
-   (adoc-kw-delimited-block "." adoc-monospace adoc-reserved t) ; literal
-   (adoc-kw-delimited-block "-" adoc-monospace adoc-reserved t) ; listing
-   (adoc-kw-delimited-block "*" adoc-secondary-text nil nil) ; sidebar
-   (adoc-kw-delimited-block "_" nil nil nil) ; quote    
-   (adoc-kw-delimited-block "=" nil nil nil) ; example  
-   (list "^\\(--\\)[ \t]*$" '(1 '(face adoc-delimiter adoc-reserved t))) ; 
open block
-
-   (adoc-kw-delimtier-line-fallback "[-/+.*_=~^]")  
+   (adoc-kw-delimited-block 0 markup-comment-face)   ; comment
+   (adoc-kw-delimited-block 1 markup-passthrough-face) ; passthrough
+   (adoc-kw-delimited-block 2 markup-code-face) ; listing
+   (adoc-kw-delimited-block 3 markup-verbatim-face) ; literal
+   (adoc-kw-delimited-block 4 nil t) ; quote    
+   (adoc-kw-delimited-block 5 nil t) ; example  
+   (adoc-kw-delimited-block 6 adoc-secondary-text) ; sidebar
+   (adoc-kw-delimited-block 7 nil t) ; open block
+   (adoc-kw-delimtier-line-fallback)  
 
 
    ;; tables

Reply via email to