2021-03-05 21:00:00 -05:00
|
|
|
;;; srecode/extract.el --- Extract content from previously inserted macro. -*- lexical-binding: t; -*-
|
2009-09-20 21:06:41 +00:00
|
|
|
|
2024-01-02 09:47:10 +08:00
|
|
|
;; Copyright (C) 2008-2024 Free Software Foundation, Inc.
|
2009-09-20 21:06:41 +00:00
|
|
|
|
2019-05-26 00:58:28 -07:00
|
|
|
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
2009-09-20 21:06:41 +00:00
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
;; (at your option) any later version.
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2017-09-13 15:52:52 -07:00
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
2009-09-20 21:06:41 +00:00
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
;;
|
|
|
|
;; Extract content from a previously inserted macro.
|
|
|
|
;;
|
|
|
|
;; The extraction routines can be handy if you want to extract users
|
|
|
|
;; added text from the middle of a template inserted block of text.
|
|
|
|
;; This code will not work for all templates. It will only work for
|
|
|
|
;; templates with unique static text between all the different insert
|
|
|
|
;; macros.
|
|
|
|
;;
|
|
|
|
;; That said, it will handle include and section templates, so complex
|
|
|
|
;; or deep template calls can be extracted.
|
|
|
|
;;
|
|
|
|
;; This code was specifically written for srecode-document, which
|
2023-12-03 23:31:30 +01:00
|
|
|
;; wants to extract user written text, and reuse it in a reformatted
|
2009-09-20 21:06:41 +00:00
|
|
|
;; comment.
|
|
|
|
|
|
|
|
(require 'srecode)
|
|
|
|
(require 'srecode/compile)
|
|
|
|
(require 'srecode/insert)
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
(defclass srecode-extract-state ()
|
|
|
|
((anchor :initform nil
|
|
|
|
:documentation
|
|
|
|
"The last known plain-text end location.")
|
|
|
|
(lastinserter :initform nil
|
|
|
|
:documentation
|
|
|
|
"The last inserter with 'later extraction type.")
|
|
|
|
(lastdict :initform nil
|
|
|
|
:documentation
|
|
|
|
"The dictionary associated with lastinserter.")
|
|
|
|
)
|
|
|
|
"The current extraction state.")
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-extract-state-set ((st srecode-extract-state) ins dict)
|
Fix typos in CEDET docstrings.
* cedet/semantic/analyze.el (semantic-analyze-push-error)
(semantic-analyze-context, semantic-analyze-context-assignment)
(semantic-analyze-find-tag-sequence, semantic-analyze-find-tag):
* cedet/semantic/java.el (java-mode, semantic-tag-include-filename)
(semantic-java-doc-keywords-map):
* cedet/semantic/bovine/c.el (c-mode, semantic-c-member-of-autocast)
(semantic-lex-c-nested-namespace-ignore-second, semantic-parse-region)
(semantic-c-parse-lexical-token, semantic-c-debug-mode-init-pch)
(semantic-c-classname, semantic-format-tag-uml-prototype)
(semantic-c-dereference-namespace, semantic-analyze-type-constants):
* cedet/semantic/bovine/el.el (semantic-elisp-form-to-doc-string)
(semantic-emacs-lisp-obsoleted-doc, semantic-up-context)
(semantic-get-local-variables, semantic-end-of-command)
(semantic-beginning-of-command, semantic-ctxt-current-class-list)
(lisp-mode):
* cedet/semantic/bovine/make.el (makefile-mode):
* cedet/semantic/wisent/python.el (wisent-python-string-re)
(wisent-python-implicit-line-joining-p, wisent-python-forward-string)
(wisent-python-lex-beginning-of-line, wisent-python-lex-end-of-line)
(semantic-lex, semantic-get-local-variables, python-mode):
* cedet/semantic/wisent/python-wy.el (wisent-python-wy--keyword-table):
* cedet/srecode/extract.el (srecode-extract-state-set)
(srecode-extract-method): Fix typos in docstrings.
2010-01-12 05:51:26 +01:00
|
|
|
"Set onto the extract state ST a new inserter INS and dictionary DICT."
|
2009-09-20 21:06:41 +00:00
|
|
|
(oset st lastinserter ins)
|
|
|
|
(oset st lastdict dict))
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-extract-state-set-anchor ((st srecode-extract-state))
|
2011-11-14 15:59:56 -08:00
|
|
|
"Reset the anchor point on extract state ST."
|
2009-09-20 21:06:41 +00:00
|
|
|
(oset st anchor (point)))
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-extract-state-extract ((st srecode-extract-state)
|
2009-09-20 21:06:41 +00:00
|
|
|
endpoint)
|
2011-11-11 02:04:08 -08:00
|
|
|
"Perform an extraction on the extract state ST with ENDPOINT.
|
2009-09-20 21:06:41 +00:00
|
|
|
If there was no waiting inserter, do nothing."
|
|
|
|
(when (oref st lastinserter)
|
|
|
|
(save-match-data
|
|
|
|
(srecode-inserter-extract (oref st lastinserter)
|
|
|
|
(oref st anchor)
|
|
|
|
endpoint
|
|
|
|
(oref st lastdict)
|
|
|
|
st))
|
|
|
|
;; Clear state.
|
|
|
|
(srecode-extract-state-set st nil nil)))
|
|
|
|
|
|
|
|
;;; Extraction
|
|
|
|
;l
|
|
|
|
(defun srecode-extract (template start end)
|
|
|
|
"Extract TEMPLATE from between START and END in the current buffer.
|
|
|
|
Uses TEMPLATE's constant strings to break up the text and guess what
|
|
|
|
the dictionary entries were for that block of text."
|
|
|
|
(save-excursion
|
|
|
|
(save-restriction
|
|
|
|
(narrow-to-region start end)
|
|
|
|
(let ((dict (srecode-create-dictionary t))
|
cedet: remove obsolete name args to constructors
* lisp/cedet/ede/proj-archive.el, lisp/cedet/ede/proj-aux.el:
* lisp/cedet/ede/proj-elisp.el, lisp/cedet/ede/proj-info.el:
* lisp/cedet/ede/proj-misc.el, lisp/cedet/ede/proj-obj.el:
* lisp/cedet/ede/proj-shared.el, lisp/cedet/ede/simple.el:
* lisp/cedet/ede/source.el, lisp/cedet/semantic/:
* lisp/cedet/semantic/analyze.el, lisp/cedet/semantic/complete.el:
* lisp/cedet/semantic/db-javascript.el:
* lisp/cedet/semantic/db-ref.el, lisp/cedet/semantic/debug.el:
* lisp/cedet/semantic/ede-grammar.el:
* lisp/cedet/semantic/mru-bookmark.el, lisp/cedet/semantic/scope.el:
* lisp/cedet/semantic/texi.el, lisp/cedet/semantic/bovine/:
* lisp/cedet/semantic/bovine/c.el:
* lisp/cedet/semantic/bovine/debug.el, lisp/cedet/srecode/:
* lisp/cedet/srecode/extract.el, lisp/cedet/srecode/map.el:
* lisp/cedet/srecode/srt-mode.el:
Remove obsolete name args to constructors.
2018-03-16 20:34:27 -04:00
|
|
|
(state (srecode-extract-state))
|
2009-09-20 21:06:41 +00:00
|
|
|
)
|
|
|
|
(goto-char start)
|
|
|
|
(srecode-extract-method template dict state)
|
|
|
|
dict))))
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-extract-method ((st srecode-template) dictionary
|
2009-09-20 21:06:41 +00:00
|
|
|
state)
|
|
|
|
"Extract template ST and store extracted text in DICTIONARY.
|
|
|
|
Optional STARTRETURN is a symbol in which the start of the first
|
Fix typos in CEDET docstrings.
* cedet/semantic/analyze.el (semantic-analyze-push-error)
(semantic-analyze-context, semantic-analyze-context-assignment)
(semantic-analyze-find-tag-sequence, semantic-analyze-find-tag):
* cedet/semantic/java.el (java-mode, semantic-tag-include-filename)
(semantic-java-doc-keywords-map):
* cedet/semantic/bovine/c.el (c-mode, semantic-c-member-of-autocast)
(semantic-lex-c-nested-namespace-ignore-second, semantic-parse-region)
(semantic-c-parse-lexical-token, semantic-c-debug-mode-init-pch)
(semantic-c-classname, semantic-format-tag-uml-prototype)
(semantic-c-dereference-namespace, semantic-analyze-type-constants):
* cedet/semantic/bovine/el.el (semantic-elisp-form-to-doc-string)
(semantic-emacs-lisp-obsoleted-doc, semantic-up-context)
(semantic-get-local-variables, semantic-end-of-command)
(semantic-beginning-of-command, semantic-ctxt-current-class-list)
(lisp-mode):
* cedet/semantic/bovine/make.el (makefile-mode):
* cedet/semantic/wisent/python.el (wisent-python-string-re)
(wisent-python-implicit-line-joining-p, wisent-python-forward-string)
(wisent-python-lex-beginning-of-line, wisent-python-lex-end-of-line)
(semantic-lex, semantic-get-local-variables, python-mode):
* cedet/semantic/wisent/python-wy.el (wisent-python-wy--keyword-table):
* cedet/srecode/extract.el (srecode-extract-state-set)
(srecode-extract-method): Fix typos in docstrings.
2010-01-12 05:51:26 +01:00
|
|
|
plain-text match occurred."
|
2009-09-20 21:06:41 +00:00
|
|
|
(srecode-extract-code-stream (oref st code) dictionary state))
|
|
|
|
|
|
|
|
(defun srecode-extract-code-stream (code dictionary state)
|
|
|
|
"Extract CODE from buffer text into DICTIONARY.
|
|
|
|
Uses string constants in CODE to split up the buffer.
|
|
|
|
Uses STATE to maintain the current extraction state."
|
|
|
|
(while code
|
|
|
|
(cond
|
|
|
|
|
|
|
|
;; constant strings need mark the end of old inserters that
|
|
|
|
;; need to extract values, or are just there.
|
|
|
|
((stringp (car code))
|
|
|
|
(srecode-extract-state-set-anchor state)
|
|
|
|
;; When we have a string, find it in the collection, then extract
|
|
|
|
;; that start point as the end point of the inserter
|
|
|
|
(unless (re-search-forward (regexp-quote (car code))
|
|
|
|
(point-max) t)
|
|
|
|
(error "Unable to extract all dictionary entries"))
|
|
|
|
|
|
|
|
(srecode-extract-state-extract state (match-beginning 0))
|
|
|
|
(goto-char (match-end 0))
|
|
|
|
)
|
|
|
|
|
|
|
|
;; Some inserters are simple, and need to be extracted after
|
|
|
|
;; we find our next block of static text.
|
|
|
|
((eq (srecode-inserter-do-extract-p (car code)) 'later)
|
|
|
|
(srecode-extract-state-set state (car code) dictionary)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; Some inserter want to start extraction now, such as sections.
|
|
|
|
;; We can't predict the end point till we parse out the middle.
|
|
|
|
((eq (srecode-inserter-do-extract-p (car code)) 'now)
|
|
|
|
(srecode-extract-state-set-anchor state)
|
|
|
|
(srecode-inserter-extract (car code) (point) nil dictionary state))
|
|
|
|
)
|
|
|
|
(setq code (cdr code))
|
|
|
|
))
|
|
|
|
|
|
|
|
;;; Inserter Base Extractors
|
|
|
|
;;
|
2021-03-05 21:00:00 -05:00
|
|
|
(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter))
|
2009-09-20 21:06:41 +00:00
|
|
|
"Return non-nil if this inserter can extract values."
|
|
|
|
nil)
|
|
|
|
|
2021-03-05 21:00:00 -05:00
|
|
|
(cl-defmethod srecode-inserter-extract ((_ins srecode-template-inserter)
|
|
|
|
_start _end _dict _state)
|
2009-09-20 21:06:41 +00:00
|
|
|
"Extract text from START/END and store in DICT.
|
|
|
|
Return nil as this inserter will extract nothing."
|
|
|
|
nil)
|
|
|
|
|
|
|
|
;;; Variable extractor is simple and can extract later.
|
|
|
|
;;
|
2021-03-05 21:00:00 -05:00
|
|
|
(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter-variable))
|
2009-09-20 21:06:41 +00:00
|
|
|
"Return non-nil if this inserter can extract values."
|
|
|
|
'later)
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter-variable)
|
2021-03-05 21:00:00 -05:00
|
|
|
start end vdict _state)
|
2009-09-20 21:06:41 +00:00
|
|
|
"Extract text from START/END and store in VDICT.
|
|
|
|
Return t if something was extracted.
|
|
|
|
Return nil if this inserter doesn't need to extract anything."
|
|
|
|
(srecode-dictionary-set-value vdict
|
2019-06-13 18:01:42 +02:00
|
|
|
(oref ins object-name)
|
2009-09-20 21:06:41 +00:00
|
|
|
(buffer-substring-no-properties
|
2019-06-13 18:01:42 +02:00
|
|
|
start end))
|
2009-09-20 21:06:41 +00:00
|
|
|
t)
|
|
|
|
|
|
|
|
;;; Section Inserter
|
|
|
|
;;
|
2021-03-05 21:00:00 -05:00
|
|
|
(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter-section-start))
|
2009-09-20 21:06:41 +00:00
|
|
|
"Return non-nil if this inserter can extract values."
|
|
|
|
'now)
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter-section-start)
|
2021-03-05 21:00:00 -05:00
|
|
|
_start _end indict state)
|
2009-09-20 21:06:41 +00:00
|
|
|
"Extract text from START/END and store in INDICT.
|
|
|
|
Return the starting location of the first plain-text match.
|
|
|
|
Return nil if nothing was extracted."
|
2019-06-13 18:01:42 +02:00
|
|
|
(let ((name (oref ins object-name))
|
2009-09-20 21:06:41 +00:00
|
|
|
(subdict (srecode-create-dictionary indict))
|
2019-06-13 18:01:42 +02:00
|
|
|
(allsubdict nil))
|
2009-09-20 21:06:41 +00:00
|
|
|
|
|
|
|
;; Keep extracting till we can extract no more.
|
|
|
|
(while (condition-case nil
|
|
|
|
(progn
|
|
|
|
(srecode-extract-method
|
|
|
|
(oref ins template) subdict state)
|
|
|
|
t)
|
|
|
|
(error nil))
|
|
|
|
|
|
|
|
;; Success means keep this subdict, and also make a new one for
|
|
|
|
;; the next iteration.
|
|
|
|
(setq allsubdict (cons subdict allsubdict))
|
|
|
|
(setq subdict (srecode-create-dictionary indict))
|
|
|
|
)
|
|
|
|
|
|
|
|
(srecode-dictionary-set-value indict name (nreverse allsubdict))
|
|
|
|
|
|
|
|
nil))
|
|
|
|
|
|
|
|
;;; Include Extractor must extract now.
|
|
|
|
;;
|
2021-03-05 21:00:00 -05:00
|
|
|
(cl-defmethod srecode-inserter-do-extract-p ((_ins srecode-template-inserter-include))
|
2009-09-20 21:06:41 +00:00
|
|
|
"Return non-nil if this inserter can extract values."
|
|
|
|
'now)
|
|
|
|
|
2015-02-04 13:49:49 -05:00
|
|
|
(cl-defmethod srecode-inserter-extract ((ins srecode-template-inserter-include)
|
2021-03-05 21:00:00 -05:00
|
|
|
start _end dict state)
|
2009-09-20 21:06:41 +00:00
|
|
|
"Extract text from START/END and store in DICT.
|
|
|
|
Return the starting location of the first plain-text match.
|
|
|
|
Return nil if nothing was extracted."
|
|
|
|
(goto-char start)
|
|
|
|
(srecode-insert-include-lookup ins dict)
|
|
|
|
;; There are two modes for includes. One is with no dict,
|
|
|
|
;; so it is inserted straight. If the dict has a name, then
|
2010-01-18 04:58:35 +01:00
|
|
|
;; we need to run once per dictionary occurrence.
|
2019-06-13 18:01:42 +02:00
|
|
|
(if (not (string= (oref ins object-name) ""))
|
2009-09-20 21:06:41 +00:00
|
|
|
;; With a name, do the insertion.
|
|
|
|
(let ((subdict (srecode-dictionary-add-section-dictionary
|
2019-06-13 18:01:42 +02:00
|
|
|
dict (oref ins object-name))))
|
2022-11-20 12:59:39 +01:00
|
|
|
(error "Need to implement include with name extractor")
|
2009-09-20 21:06:41 +00:00
|
|
|
;; Recurse into the new template while no errors.
|
|
|
|
(while (condition-case nil
|
|
|
|
(progn
|
|
|
|
(srecode-extract-method
|
|
|
|
(oref ins includedtemplate) subdict
|
|
|
|
state)
|
|
|
|
t)
|
|
|
|
(error nil))))
|
|
|
|
|
|
|
|
;; No stream, do the extraction into the current dictionary.
|
|
|
|
(srecode-extract-method (oref ins includedtemplate) dict
|
|
|
|
state))
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'srecode/extract)
|
|
|
|
|
|
|
|
;;; srecode/extract.el ends here
|