12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025 |
- (eval-when-compile
- (require 'cl))
- (require 'srecode/compile)
- (require 'srecode/find)
- (require 'srecode/dictionary)
- (require 'srecode/args)
- (require 'srecode/filters)
- (defvar srecode-template-inserter-point)
- (declare-function srecode-overlaid-activate "srecode/fields")
- (declare-function srecode-template-inserted-region "srecode/fields")
- (defcustom srecode-insert-ask-variable-method 'ask
- "Determine how to ask for a dictionary value when inserting a template.
- Only the ASK style inserter will query the user for a value.
- Dictionary value references that ask begin with the ? character.
- Possible values are:
- 'ask - Prompt in the minibuffer as the value is inserted.
- 'field - Use the dictionary macro name as the inserted value,
- and place a field there. Matched fields change together.
- NOTE: The field feature does not yet work with XEmacs."
- :group 'srecode
- :type '(choice (const :tag "Ask" ask)
- (const :tag "Field" field)))
- (defvar srecode-insert-with-fields-in-progress nil
- "Non-nil means that we are actively inserting a template with fields.")
- (defvar srecode-insertion-start-context nil
- "The context that was at point at the beginning of the template insertion.")
- (defun srecode-insert-again ()
- "Insert the previously inserted template (by name) again."
- (interactive)
- (let ((prev (car srecode-read-template-name-history)))
- (if prev
- (srecode-insert prev)
- (call-interactively 'srecode-insert))))
- (defun srecode-insert (template-name &rest dict-entries)
- "Insert the template TEMPLATE-NAME into the current buffer at point.
- DICT-ENTRIES are additional dictionary values to add."
- (interactive (list (srecode-read-template-name "Template Name: ")))
- (if (not (srecode-table))
- (error "No template table found for mode %s" major-mode))
- (let ((newdict (srecode-create-dictionary))
- (temp (srecode-template-get-table (srecode-table) template-name))
- (srecode-insertion-start-context (srecode-calculate-context))
- )
- (if (not temp)
- (error "No Template named %s" template-name))
- (while dict-entries
- (srecode-dictionary-set-value newdict
- (car dict-entries)
- (car (cdr dict-entries)))
- (setq dict-entries (cdr (cdr dict-entries))))
- (srecode-insert-fcn temp newdict)
-
-
- ))
- (defun srecode-insert-fcn (template dictionary &optional stream skipresolver)
- "Insert TEMPLATE using DICTIONARY into STREAM.
- Optional SKIPRESOLVER means to avoid refreshing the tag list,
- or resolving any template arguments. It is assumed the caller
- has set everything up already."
-
- (let ((standard-output (or stream (current-buffer)))
- (end-mark nil))
-
- (when (slot-boundp template 'dictionary)
- (srecode-dictionary-merge dictionary (oref template dictionary)))
- (unless skipresolver
-
- (semantic-fetch-tags)
-
- (srecode-resolve-arguments template dictionary))
-
- (if (bufferp standard-output)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (let ((start (point)))
- (let ((inhibit-point-motion-hooks t)
- (inhibit-modification-hooks t)
- )
- (srecode--insert-into-buffer template dictionary)
- )
-
- (run-hook-with-args 'after-change-functions
- start (point) 0)
- )
- (srecode-insert-method template dictionary))
-
- (when (and (bufferp standard-output)
- (slot-boundp 'srecode-template-inserter-point 'point)
- )
- (set-buffer standard-output)
- (setq end-mark (point-marker))
- (goto-char (oref srecode-template-inserter-point point)))
- (oset-default 'srecode-template-inserter-point point eieio-unbound)
-
- (or end-mark (point)))
- )
- (defun srecode--insert-into-buffer (template dictionary)
- "Insert a TEMPLATE with DICTIONARY into a buffer.
- Do not call this function yourself. Instead use:
- `srecode-insert' - Inserts by name.
- `srecode-insert-fcn' - Insert with objects.
- This function handles the case from one of the above functions when
- the template is inserted into a buffer. It looks
- at `srecode-insert-ask-variable-method' to decide if unbound dictionary
- entries ask questions or insert editable fields.
- Buffer based features related to change hooks is handled one level up."
-
-
-
- (when (eq srecode-insert-ask-variable-method 'field)
- (require 'srecode/fields))
- (let ((srecode-field-archive nil)
- (start (point))
- )
-
-
- (let ((srecode-insert-with-fields-in-progress
- (if (eq srecode-insert-ask-variable-method 'field) t nil))
- )
- (srecode-insert-method template dictionary)
- )
-
-
- (when (and (not srecode-insert-with-fields-in-progress)
- (eq srecode-insert-ask-variable-method 'field)
- srecode-field-archive
- )
- (let ((reg
-
- (srecode-template-inserted-region
- "TEMPLATE" :start start :end (point))))
- (srecode-overlaid-activate reg))
- )
-
-
- ))
- (defun srecode-resolve-arguments (temp dict)
- "Resolve all the arguments needed by the template TEMP.
- Apply anything learned to the dictionary DICT."
- (srecode-resolve-argument-list (oref temp args) dict temp))
- (defun srecode-resolve-argument-list (args dict &optional temp)
- "Resolve arguments in the argument list ARGS.
- ARGS is a list of symbols, such as :blank, or :file.
- Apply values to DICT.
- Optional argument TEMP is the template that is getting its arguments resolved."
- (let ((fcn nil))
- (while args
- (setq fcn (intern-soft (concat "srecode-semantic-handle-"
- (symbol-name (car args)))))
- (if (not fcn)
- (error "Error resolving template argument %S" (car args)))
- (if temp
- (condition-case nil
-
-
- (funcall fcn dict temp)
- (wrong-number-of-arguments (funcall fcn dict)))
- (funcall fcn dict))
- (setq args (cdr args)))
- ))
- (defmethod srecode-push ((st srecode-template))
- "Push the srecoder template ST onto the active stack."
- (oset st active (cons st (oref st active))))
- (defmethod srecode-pop :STATIC ((st srecode-template))
- "Pop the srecoder template ST onto the active stack.
- ST can be a class, or an object."
- (oset st active (cdr (oref st active))))
- (defmethod srecode-peek :STATIC ((st srecode-template))
- "Fetch the topmost active template record. ST can be a class."
- (car (oref st active)))
- (defmethod srecode-insert-method ((st srecode-template) dictionary)
- "Insert the srecoder template ST."
-
-
-
-
- (when (slot-boundp st 'dictionary)
- (srecode-dictionary-merge dictionary (oref st dictionary)))
-
- (unwind-protect
- (let ((c (oref st code)))
- (srecode-push st)
- (srecode-insert-code-stream c dictionary))
-
- (srecode-pop st)))
- (defun srecode-insert-code-stream (code dictionary)
- "Insert the CODE from a template into `standard-output'.
- Use DICTIONARY to resolve any macros."
- (while code
- (cond ((stringp (car code))
- (princ (car code)))
- (t
- (srecode-insert-method (car code) dictionary)))
- (setq code (cdr code))))
- (defclass srecode-template-inserter-newline (srecode-template-inserter)
- ((key :initform "\n"
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- (hard :initform nil
- :initarg :hard
- :documentation
- "Is this a hard newline (always inserted) or optional?
- Optional newlines don't insert themselves if they are on a blank line
- by themselves.")
- )
- "Insert a newline, and possibly do indenting.
- Specify the :indent argument to enable automatic indentation when newlines
- occur in your template.")
- (defmethod srecode-insert-method ((sti srecode-template-inserter-newline)
- dictionary)
- "Insert the STI inserter."
-
-
- (let ((i (srecode-dictionary-lookup-name dictionary "INDENT"))
- (inbuff (bufferp standard-output))
- (doit t)
- (pm (point-marker)))
- (when (and inbuff (not (oref sti hard)))
-
-
- (beginning-of-line)
- (save-restriction
- (narrow-to-region (point) pm)
- (when (looking-at "\\s-*$")
- (setq doit nil)))
- (goto-char pm)
- )
-
- (when (and (eq i t) inbuff)
- (indent-according-to-mode)
- (goto-char pm))
- (when doit
- (princ "\n")
-
- (cond ((and (eq i t) (bufferp standard-output))
-
-
-
- (setq pm (point-marker))
- (indent-according-to-mode)
- (goto-char pm))
- ((numberp i)
- (princ (make-string i " ")))
- ((stringp i)
- (princ i))))))
- (defmethod srecode-dump ((ins srecode-template-inserter-newline) indent)
- "Dump the state of the SRecode template inserter INS."
- (call-next-method)
- (when (oref ins hard)
- (princ " : hard")
- ))
- (defclass srecode-template-inserter-blank (srecode-template-inserter)
- ((key :initform "\r"
- :allocation :class
- :documentation
- "The character representing this inserter style.
- Can't be blank, or it might be used by regular variable insertion.")
- (where :initform 'begin
- :initarg :where
- :documentation
- "This should be 'begin or 'end, indicating where to insert a CR.
- When set to 'begin, it will insert a CR if we are not at 'bol'.
- When set to 'end it will insert a CR if we are not at 'eol'.")
-
-
- )
- "Insert a newline before and after a template, and possibly do indenting.
- Specify the :blank argument to enable this inserter.")
- (defmethod srecode-insert-method ((sti srecode-template-inserter-blank)
- dictionary)
- "Make sure there is no text before or after point."
- (let ((i (srecode-dictionary-lookup-name dictionary "INDENT"))
- (inbuff (bufferp standard-output))
- (pm (point-marker)))
- (when (and inbuff
-
- (= (length (oref srecode-template active)) 1))
- (when (and (eq i t) inbuff (not (eq (oref sti where) 'begin)))
- (indent-according-to-mode)
- (goto-char pm))
- (cond ((and (eq (oref sti where) 'begin) (not (bolp)))
- (princ "\n"))
- ((eq (oref sti where) 'end)
-
- (when (looking-at "\\s-*$")
- (delete-region (point) (point-at-eol)))
- (when (not (eolp))
- (princ "\n")))
- )
- (setq pm (point-marker))
- (when (and (eq i t) inbuff (not (eq (oref sti where) 'end)))
- (indent-according-to-mode)
- (goto-char pm))
- )))
- (defclass srecode-template-inserter-comment (srecode-template-inserter)
- ((key :initform ?!
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- )
- "Allow comments within template coding. This inserts nothing.")
- (defmethod srecode-inserter-prin-example :STATIC ((ins srecode-template-inserter-comment)
- escape-start escape-end)
- "Insert an example using inserter INS.
- Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
- (princ " ")
- (princ escape-start)
- (princ "! Miscellaneous text commenting in your template. ")
- (princ escape-end)
- (terpri)
- )
- (defmethod srecode-insert-method ((sti srecode-template-inserter-comment)
- dictionary)
- "Don't insert anything for comment macros in STI."
- nil)
- (defclass srecode-template-inserter-variable (srecode-template-inserter)
- ((key :initform nil
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style."))
- "Insert the value of a dictionary entry.
- If there is no entry, insert nothing.")
- (defvar srecode-inserter-variable-current-dictionary nil
- "The active dictionary when calling a variable filter.")
- (defmethod srecode-insert-variable-secondname-handler
- ((sti srecode-template-inserter-variable) dictionary value secondname)
- "For VALUE handle SECONDNAME behaviors for this variable inserter.
- Return the result as a string.
- By default, treat as a function name.
- If SECONDNAME is nil, return VALUE."
- (if secondname
- (let ((fcnpart (read secondname)))
- (if (fboundp fcnpart)
- (let ((srecode-inserter-variable-current-dictionary dictionary))
- (funcall fcnpart value))
-
- (error "Variable insertion second arg %s is not a function"
- secondname)))
- value))
- (defmethod srecode-insert-method ((sti srecode-template-inserter-variable)
- dictionary)
- "Insert the STI inserter."
-
- (let* ((name (oref sti :object-name))
- (fcnpart (oref sti :secondname))
- (val (srecode-dictionary-lookup-name
- dictionary name))
- (do-princ t)
- )
-
- (when (not val)
- (message "Warning: macro %S was not found in the dictionary." name)
- (setq val ""))
-
- (cond
- ((stringp val)
- (setq val (srecode-insert-variable-secondname-handler
- sti dictionary val fcnpart)))
-
- ((srecode-dictionary-compound-value-child-p val)
-
- (when fcnpart (setq fcnpart (read fcnpart)))
-
- (setq val (srecode-compound-toString val fcnpart dictionary))
-
-
- (when (not val)
- (setq do-princ nil)
- )
- )
-
- ((srecode-dictionary-child-p val)
- (error "Macro %s cannot insert a dictionary - use section macros instead"
- name))
-
- (t
- (error "Macro %s cannot insert arbitrary data" name)
-
-
- ))
-
-
- (when do-princ
- (princ val))))
- (defclass srecode-template-inserter-ask (srecode-template-inserter-variable)
- ((key :initform ??
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- (prompt :initarg :prompt
- :initform nil
- :documentation
- "The prompt used to query for this dictionary value.")
- (defaultfcn :initarg :defaultfcn
- :initform nil
- :documentation
- "The function which can calculate a default value.")
- (read-fcn :initarg :read-fcn
- :initform 'read-string
- :documentation
- "The function used to read in the text for this prompt.")
- )
- "Insert the value of a dictionary entry.
- If there is no entry, prompt the user for the value to use.
- The prompt text used is derived from the previous PROMPT command in the
- template file.")
- (defmethod srecode-inserter-apply-state
- ((ins srecode-template-inserter-ask) STATE)
- "For the template inserter INS, apply information from STATE.
- Loop over the prompts to see if we have a match."
- (let ((prompts (oref STATE prompts))
- )
- (while prompts
- (when (string= (semantic-tag-name (car prompts))
- (oref ins :object-name))
- (oset ins :prompt
- (semantic-tag-get-attribute (car prompts) :text))
- (oset ins :defaultfcn
- (semantic-tag-get-attribute (car prompts) :default))
- (oset ins :read-fcn
- (or (semantic-tag-get-attribute (car prompts) :read)
- 'read-string))
- )
- (setq prompts (cdr prompts)))
- ))
- (defmethod srecode-insert-method ((sti srecode-template-inserter-ask)
- dictionary)
- "Insert the STI inserter."
- (let ((val (srecode-dictionary-lookup-name
- dictionary (oref sti :object-name))))
- (if val
-
- (call-next-method)
-
- (if srecode-insert-with-fields-in-progress
-
- (setq val (srecode-insert-method-field sti dictionary))
-
- (setq val (srecode-insert-method-ask sti dictionary)))
-
-
- (srecode-dictionary-set-value
- (srecode-root-dictionary dictionary)
- (oref sti :object-name) val)
-
-
- (call-next-method))))
- (defmethod srecode-insert-ask-default ((sti srecode-template-inserter-ask)
- dictionary)
- "Derive the default value for an askable inserter STI.
- DICTIONARY is used to derive some values."
- (let ((defaultfcn (oref sti :defaultfcn)))
- (cond ((stringp defaultfcn)
- defaultfcn)
- ((functionp defaultfcn)
- (funcall defaultfcn))
- ((and (listp defaultfcn)
- (eq (car defaultfcn) 'macro))
- (srecode-dictionary-lookup-name
- dictionary (cdr defaultfcn)))
- ((null defaultfcn)
- "")
- (t
- (error "Unknown default for prompt: %S"
- defaultfcn)))))
- (defmethod srecode-insert-method-ask ((sti srecode-template-inserter-ask)
- dictionary)
- "Do the \"asking\" for the template inserter STI.
- Use DICTIONARY to resolve values."
- (let* ((prompt (oref sti prompt))
- (default (srecode-insert-ask-default sti dictionary))
- (reader (oref sti :read-fcn))
- (val nil)
- )
- (cond ((eq reader 'y-or-n-p)
- (if (y-or-n-p (or prompt
- (format "%s? "
- (oref sti :object-name))))
- (setq val default)
- (setq val "")))
- ((eq reader 'read-char)
- (setq val (format
- "%c"
- (read-char (or prompt
- (format "Char for %s: "
- (oref sti :object-name))))))
- )
- (t
- (save-excursion
- (setq val (funcall reader
- (or prompt
- (format "Specify %s: "
- (oref sti :object-name)))
- default
- )))))
-
- val)
- )
- (defmethod srecode-insert-method-field ((sti srecode-template-inserter-ask)
- dictionary)
- "Create an editable field for the template inserter STI.
- Use DICTIONARY to resolve values."
- (let* ((default (srecode-insert-ask-default sti dictionary))
- (compound-value
- (srecode-field-value (oref sti :object-name)
- :firstinserter sti
- :defaultvalue default))
- )
-
-
-
- compound-value))
- (defmethod srecode-dump ((ins srecode-template-inserter-ask) indent)
- "Dump the state of the SRecode template inserter INS."
- (call-next-method)
- (princ " : \"")
- (princ (oref ins prompt))
- (princ "\"")
- )
- (defclass srecode-template-inserter-width (srecode-template-inserter-variable)
- ((key :initform ?|
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- )
- "Inserts the value of a dictionary variable with a specific width.
- The second argument specifies the width, and a pad, separated by a colon.
- Thus a specification of `10:left' will insert the value of A
- to 10 characters, with spaces added to the left. Use `right' for adding
- spaces to the right.")
- (defmethod srecode-insert-variable-secondname-handler
- ((sti srecode-template-inserter-width) dictionary value width)
- "For VALUE handle WIDTH behaviors for this variable inserter.
- Return the result as a string.
- By default, treat as a function name."
- (if width
-
- (let* ((split (split-string width ":"))
- (width (string-to-number (nth 0 split)))
- (second (nth 1 split))
- (pad (cond ((or (null second) (string= "right" second))
- 'right)
- ((string= "left" second)
- 'left)
- (t
- (error "Unknown pad type %s" second)))))
- (if (>= (length value) width)
-
- (substring value 0 width)
-
- (let ((padchars (make-string (- width (length value)) ? )))
- (if (eq pad 'left)
- (concat padchars value)
- (concat value padchars)))))
- (error "Width not specified for variable/width inserter")))
- (defmethod srecode-inserter-prin-example :STATIC ((ins srecode-template-inserter-width)
- escape-start escape-end)
- "Insert an example using inserter INS.
- Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
- (princ " ")
- (princ escape-start)
- (princ "|A:10:right")
- (princ escape-end)
- (terpri)
- )
- (defvar srecode-template-inserter-point-override nil
- "Point-positioning method for the SRecode template inserter.
- When nil, perform normal point-positioning behavior.
- When the value is a cons cell (DEPTH . FUNCTION), call FUNCTION
- instead, unless the template nesting depth, measured
- by (length (oref srecode-template active)), is greater than
- DEPTH.")
- (defclass srecode-template-inserter-point (srecode-template-inserter)
- ((key :initform ?^
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- (point :type (or null marker)
- :allocation :class
- :documentation
- "Record the value of (point) in this class slot.
- It is the responsibility of the inserter algorithm to clear this
- after a successful insertion."))
- "Record the value of (point) when inserted.
- The cursor is placed at the ^ macro after insertion.
- Some inserter macros, such as `srecode-template-inserter-include-wrap'
- will place text at the ^ macro from the included macro.")
- (defmethod srecode-inserter-prin-example :STATIC ((ins srecode-template-inserter-point)
- escape-start escape-end)
- "Insert an example using inserter INS.
- Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
- (princ " ")
- (princ escape-start)
- (princ "^")
- (princ escape-end)
- (terpri)
- )
- (defmethod srecode-insert-method ((sti srecode-template-inserter-point)
- dictionary)
- "Insert the STI inserter.
- Save point in the class allocated 'point' slot.
- If `srecode-template-inserter-point-override' non-nil then this
- generalized marker will do something else. See
- `srecode-template-inserter-include-wrap' as an example."
-
-
-
-
- (if (and srecode-template-inserter-point-override
- (<= (length (oref srecode-template active))
- (car srecode-template-inserter-point-override)))
-
- (let ((over (cdr srecode-template-inserter-point-override))
- (srecode-template-inserter-point-override nil))
- (funcall over dictionary))
- (oset sti point (point-marker))
- ))
- (defclass srecode-template-inserter-subtemplate (srecode-template-inserter)
- ()
- "Wrap a section of a template under the control of a macro."
- :abstract t)
- (defmethod srecode-inserter-prin-example :STATIC ((ins srecode-template-inserter-subtemplate)
- escape-start escape-end)
- "Insert an example using inserter INS.
- Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
- (call-next-method)
- (princ " Template Text to control")
- (terpri)
- (princ " ")
- (princ escape-start)
- (princ "/VARNAME")
- (princ escape-end)
- (terpri)
- )
- (defmethod srecode-insert-subtemplate ((sti srecode-template-inserter-subtemplate)
- dict slot)
- "Insert a subtemplate for the inserter STI with dictionary DICT."
-
- (when (not (srecode-dictionary-child-p dict))
- (error "Only section dictionaries allowed for %s"
- (object-name-string sti)))
-
- (srecode-insert-method (slot-value sti slot) dict)
- )
- (defmethod srecode-insert-method-helper ((sti srecode-template-inserter-subtemplate)
- dictionary slot)
- "Do the work for inserting the STI inserter.
- Loops over the embedded CODE which was saved here during compilation.
- The template to insert is stored in SLOT."
- (let ((dicts (srecode-dictionary-lookup-name
- dictionary (oref sti :object-name))))
- (when (not (listp dicts))
- (error "Cannot insert section %S from non-section variable."
- (oref sti :object-name)))
-
-
- (while dicts
- (when (not (srecode-dictionary-p (car dicts)))
- (error "Cannot insert section %S from non-section variable."
- (oref sti :object-name)))
- (srecode-insert-subtemplate sti (car dicts) slot)
- (setq dicts (cdr dicts)))))
- (defmethod srecode-insert-method ((sti srecode-template-inserter-subtemplate)
- dictionary)
- "Insert the STI inserter.
- Calls back to `srecode-insert-method-helper' for this class."
- (srecode-insert-method-helper sti dictionary 'template))
- (defclass srecode-template-inserter-section-start (srecode-template-inserter-subtemplate)
- ((key :initform ?#
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- (template :initarg :template
- :documentation
- "A template used to frame the codes from this inserter.")
- )
- "Apply values from a sub-dictionary to a template section.
- The dictionary saved at the named dictionary entry will be
- applied to the text between the section start and the
- `srecode-template-inserter-section-end' macro.")
- (defmethod srecode-parse-input ((ins srecode-template-inserter-section-start)
- tag input STATE)
- "For the section inserter INS, parse INPUT.
- Shorten input until the END token is found.
- Return the remains of INPUT."
- (let* ((out (srecode-compile-split-code tag input STATE
- (oref ins :object-name))))
- (oset ins template (srecode-template
- (object-name-string ins)
- :context nil
- :args nil
- :code (cdr out)))
- (car out)))
- (defmethod srecode-dump ((ins srecode-template-inserter-section-start) indent)
- "Dump the state of the SRecode template inserter INS."
- (call-next-method)
- (princ "\n")
- (srecode-dump-code-list (oref (oref ins template) code)
- (concat indent " "))
- )
- (defclass srecode-template-inserter-section-end (srecode-template-inserter)
- ((key :initform ?/
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- )
- "All template segments between the section-start and section-end
- are treated specially.")
- (defmethod srecode-insert-method ((sti srecode-template-inserter-section-end)
- dictionary)
- "Insert the STI inserter."
- )
- (defmethod srecode-match-end ((ins srecode-template-inserter-section-end) name)
- "For the template inserter INS, do I end a section called NAME?"
- (string= name (oref ins :object-name)))
- (defclass srecode-template-inserter-include (srecode-template-inserter-subtemplate)
- ((key :initform ?>
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- (includedtemplate
- :initarg :includedtemplate
- :documentation
- "The template included for this inserter."))
- "Include a different template into this one.
- The included template will have additional dictionary entries from the subdictionary
- stored specified by this macro.")
- (defmethod srecode-inserter-prin-example :STATIC ((ins srecode-template-inserter-include)
- escape-start escape-end)
- "Insert an example using inserter INS.
- Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
- (princ " ")
- (princ escape-start)
- (princ ">DICTNAME:contextname:templatename")
- (princ escape-end)
- (terpri)
- )
- (defmethod srecode-insert-include-lookup ((sti srecode-template-inserter-include)
- dictionary)
- "For the template inserter STI, lookup the template to include.
- Finds the template with this macro function part and stores it in
- this template instance."
- (let* ((templatenamepart (oref sti :secondname))
- )
-
- (if (not templatenamepart)
- (error "Include macro %s needs a template name" (oref sti :object-name)))
-
-
-
-
- (let ((tmpl (srecode-template-get-table (srecode-table)
- templatenamepart))
- (active (oref srecode-template active))
- ctxt)
- (when (not tmpl)
-
-
-
- (while (and (not tmpl) active)
- (setq ctxt (oref (car active) context))
- (setq tmpl (srecode-template-get-table (srecode-table)
- templatenamepart
- ctxt))
- (when (not tmpl)
- (when (slot-boundp (car active) 'table)
- (let ((app (oref (oref (car active) table) application)))
- (when app
- (setq tmpl (srecode-template-get-table
- (srecode-table)
- templatenamepart
- ctxt app)))
- )))
- (setq active (cdr active)))
- (when (not tmpl)
-
-
- (setq tmpl (srecode-template-get-table (srecode-table)
- templatenamepart)))
- )
-
- (oset sti :includedtemplate tmpl))
- (if (not (oref sti includedtemplate))
-
- (error "No template \"%s\" found for include macro `%s'"
- templatenamepart (oref sti :object-name)))
- ))
- (defmethod srecode-insert-method ((sti srecode-template-inserter-include)
- dictionary)
- "Insert the STI inserter.
- Finds the template with this macro function part, and inserts it
- with the dictionaries found in the dictionary."
- (srecode-insert-include-lookup sti dictionary)
-
-
- (if (srecode-dictionary-lookup-name dictionary (oref sti :object-name))
-
- (srecode-insert-method-helper sti dictionary 'includedtemplate)
-
-
- (srecode-insert-subtemplate sti dictionary 'includedtemplate))
- )
- (defclass srecode-template-inserter-include-wrap (srecode-template-inserter-include srecode-template-inserter-section-start)
- ((key :initform ?<
- :allocation :class
- :documentation
- "The character code used to identify inserters of this style.")
- )
- "Include a different template into this one, and add text at the ^ macro.
- The included template will have additional dictionary entries from the subdictionary
- stored specified by this macro. If the included macro includes a ^ macro,
- then the text between this macro and the end macro will be inserted at
- the ^ macro.")
- (defmethod srecode-inserter-prin-example :STATIC ((ins srecode-template-inserter-include-wrap)
- escape-start escape-end)
- "Insert an example using inserter INS.
- Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use."
- (princ " ")
- (princ escape-start)
- (princ "<DICTNAME:contextname:templatename")
- (princ escape-end)
- (terpri)
- (princ " Template Text to insert at ^ macro")
- (terpri)
- (princ " ")
- (princ escape-start)
- (princ "/DICTNAME")
- (princ escape-end)
- (terpri)
- )
- (defmethod srecode-insert-method ((sti srecode-template-inserter-include-wrap)
- dictionary)
- "Insert the template STI.
- This will first insert the include part via inheritance, then
- insert the section it wraps into the location in the included
- template where a ^ inserter occurs."
-
- (srecode-insert-include-lookup sti dictionary)
-
-
-
-
-
-
- (let ((srecode-template-inserter-point-override
- (lexical-let ((inserter1 sti))
- (cons
-
- (+ (length (oref srecode-template active)) 1)
-
- (lambda (dict)
- (let ((srecode-template-inserter-point-override nil))
- (if (srecode-dictionary-lookup-name
- dict (oref inserter1 :object-name))
-
- (srecode-insert-method-helper
- inserter1 dict 'template)
-
- (srecode-insert-subtemplate
- inserter1 dict 'template))))))))
-
-
- (call-next-method)))
- (provide 'srecode/insert)
|