Tag Sync Script (NomiScript)
Introduction
NomiScript version of the tag synchronization script. When a transaction is created with exactly two splits, this script copies tags bidirectionally:
- Transaction has tags, splits don't -> copy to both splits
- Split has tags, transaction doesn't -> copy to transaction
This demonstrates the NomiScript entity API: context queries, entity iteration, tag accessors, and output functions. Compare with the Rust SDK version.
Trigger function
Only run when the primary entity is a transaction:
(defun should-apply ()
(= (primary-entity-type) +entity-transaction+))
Helper: collect entity indices by type and parent
Build a cons list of entity indices matching a given type and parent:
(defun entities-for (parent-idx entity-type-val)
(let ((result nil))
(do ((i 0 (+ i 1)))
((>= i (entity-count)) result)
(when (and (= (entity-type i) entity-type-val)
(= (entity-parent-idx i) parent-idx))
(setf result (cons i result))))))
Helper: count list length
(defun list-length (lst)
(let ((count 0))
(dolist (e lst)
(setf count (+ count 1)))
count))
Helper: check if a tag is a user tag
The "note" tag is a system tag set by the transaction form and should not count as a user tag for synchronization purposes:
(defun user-tag? (idx)
(not (string= (tag-name idx) "note")))
Helper: copy user tags from one entity to another
(defun copy-tags (source-idx target-idx)
(dolist (tag (entities-for source-idx +entity-tag+))
(when (user-tag? tag)
(create-tag target-idx (tag-name tag) (tag-value tag)))))
Helper: collect user tag indices for an entity
(defun user-tags-for (parent-idx)
(let ((result nil))
(dolist (tag (entities-for parent-idx +entity-tag+))
(when (user-tag? tag)
(setf result (cons tag result))))
result))
Main logic
(let* ((tx-idx (primary-entity-idx))
(splits (entities-for tx-idx +entity-split+))
(tx-tags (user-tags-for tx-idx)))
(when (= (list-length splits) 2)
(let* ((s0 (car splits))
(s1 (car (cdr splits)))
(s0-tags (entities-for s0 +entity-tag+))
(s1-tags (entities-for s1 +entity-tag+)))
(cond
;; Transaction has tags, splits don't -> copy to splits
((and (not (null? tx-tags)) (null? s0-tags) (null? s1-tags))
(dolist (tag tx-tags)
(create-tag s0 (tag-name tag) (tag-value tag))
(create-tag s1 (tag-name tag) (tag-value tag))))
;; Split has tags, transaction doesn't -> copy to transaction
((and (null? tx-tags) (not (null? s0-tags)))
(copy-tags s0 tx-idx))
((and (null? tx-tags) (not (null? s1-tags)))
(copy-tags s1 tx-idx))))))