123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- (require 'srecode)
- (require 'srecode/compile)
- (require 'srecode/insert)
- (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.")
- (defmethod srecode-extract-state-set ((st srecode-extract-state) ins dict)
- "Set onto the extract state ST a new inserter INS and dictionary DICT."
- (oset st lastinserter ins)
- (oset st lastdict dict))
- (defmethod srecode-extract-state-set-anchor ((st srecode-extract-state))
- "Reset the anchor point on extract state ST."
- (oset st anchor (point)))
- (defmethod srecode-extract-state-extract ((st srecode-extract-state)
- endpoint)
- "Perform an extraction on the extract state ST with ENDPOINT.
- 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))
-
- (srecode-extract-state-set st nil nil)))
- (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))
- (state (srecode-extract-state "state"))
- )
- (goto-char start)
- (srecode-extract-method template dict state)
- dict))))
- (defmethod srecode-extract-method ((st srecode-template) dictionary
- state)
- "Extract template ST and store extracted text in DICTIONARY.
- Optional STARTRETURN is a symbol in which the start of the first
- plain-text match occurred."
- (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
-
-
- ((stringp (car code))
- (srecode-extract-state-set-anchor state)
-
-
- (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))
- )
-
-
- ((eq (srecode-inserter-do-extract-p (car code)) 'later)
- (srecode-extract-state-set state (car code) dictionary)
- )
-
-
- ((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))
- ))
- (defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter))
- "Return non-nil if this inserter can extract values."
- nil)
- (defmethod srecode-inserter-extract ((ins srecode-template-inserter)
- start end dict state)
- "Extract text from START/END and store in DICT.
- Return nil as this inserter will extract nothing."
- nil)
- (defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter-variable))
- "Return non-nil if this inserter can extract values."
- 'later)
- (defmethod srecode-inserter-extract ((ins srecode-template-inserter-variable)
- start end vdict state)
- "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
- (oref ins :object-name)
- (buffer-substring-no-properties
- start end)
- )
- t)
- (defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter-section-start))
- "Return non-nil if this inserter can extract values."
- 'now)
- (defmethod srecode-inserter-extract ((ins srecode-template-inserter-section-start)
- start end indict state)
- "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."
- (let ((name (oref ins :object-name))
- (subdict (srecode-create-dictionary indict))
- (allsubdict nil)
- )
-
- (while (condition-case nil
- (progn
- (srecode-extract-method
- (oref ins template) subdict state)
- t)
- (error nil))
-
-
- (setq allsubdict (cons subdict allsubdict))
- (setq subdict (srecode-create-dictionary indict))
- )
- (srecode-dictionary-set-value indict name (nreverse allsubdict))
- nil))
- (defmethod srecode-inserter-do-extract-p ((ins srecode-template-inserter-include))
- "Return non-nil if this inserter can extract values."
- 'now)
- (defmethod srecode-inserter-extract ((ins srecode-template-inserter-include)
- start end dict state)
- "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)
-
-
-
- (if (not (string= (oref ins :object-name) ""))
-
- (let ((subdict (srecode-dictionary-add-section-dictionary
- dict (oref ins :object-name))))
- (error "Need to implement include w/ name extractor")
-
- (while (condition-case nil
- (progn
- (srecode-extract-method
- (oref ins includedtemplate) subdict
- state)
- t)
- (error nil))))
-
- (srecode-extract-method (oref ins includedtemplate) dict
- state))
- )
- (provide 'srecode/extract)
|