Translations of this page are also available in the following languages: Русский.

Guile scripting

gEDA/gaf uses Guile Scheme to provide Scheme scripting capabilities, and all of the features of Guile are available to use. The Guile Reference Manual is available as an Info manual (info guile on most systems), or on the Guile website.

A collection of modules is provided for accessing and modifying gEDA objects and pages, called the gEDA Scheme API. The gEDA Scheme Reference Manual is also available as an Info manual (info geda-scheme).


Reference documents

Scripting examples

You can download each script example and load it in gschem:

  • just hit : and enter
    (load "filename.scm")
  • then hit Enter

Removing objects with specific properties

For instance, let's remove all objects which are circles or arcs with zero radius:

(use-modules (geda page))
; Checks if the OBJECT is a circle or an arc with zero radius
(define (zero-radius-object? object)
    (and (circle? object) (= (circle-radius object) 0))
    (and (arc?    object) (= (arc-radius    object) 0))))
(apply page-remove! (active-page)
         (page-contents (active-page))))

Let's suppose we have a component with a known attribute to remove, then we have to detach and remove all its attributes, too. The function below does exactly this.

(use-modules (geda page))
(use-modules (geda object))
(use-modules (geda attrib))
; Removes all components having the attrib NAME=VALUE from PAGE
(define (delete-components-by-attrib! page name value)
    (lambda (obj)
      (if (component? obj)
          (lambda (attr)
              (string=? (attrib-name attr) name)
              (string=? (attrib-value attr) value)
              (let ((attached-attribs (object-attribs obj)))
                (apply detach-attribs! obj attached-attribs)
                (apply page-remove! page obj attached-attribs))))
          (object-attribs obj))))
    (page-contents page)))

After loading the file, hit : and enter, for example,

(delete-components-by-attrib! (active-page) "refdes" "R1")

Procedures for input-output

The following script defines two procedures that can be used in gaf shell batch scripts:

  • schematic-file→page
  • page→schematic-file
(use-modules (ice-9 lineio))
(use-modules (geda page))
; Input/output procedures
; reads FILE and outputs string
(define (file->string file)
  (let* ((port (make-line-buffering-input-port (open-file file "r"))))
    (do ((line "" (read-string port))
         (s "" (string-append s line)))
      ((eof-object? line) ; test
       (close-port port)  ; expression(s) to evaluate in the end
       s)                 ; return value
      ; empty body
; reads schematic FILE and outputs PAGE object
(define (schematic-file->page file)
    (string->page file (file->string file)))
; saves schematic PAGE to FILE
(define (page->schematic-file page file)
  (with-output-to-file file
    (lambda () (display (page->string page)))))

Copy, move, and rotate objects

; Scripting example by vzh per request of Kai-Martin Knaak :-)
; Use at your own risk.
; The main procedure here is
; multiple-copy-move-and-rotate-selection which can be abbreviated
; as mcmars.
; Usage:
;   launch gschem so it can use this script, e.g.
;     gschem -s move-and-rotate.scm
;   select objects in gschem, then hit ':' (semicolon) and type
;     (mcmars '(1000 . 500) 90 10)
;   hit <Enter>
; Enjoy!
(use-modules (gschem selection))
; align coords by ALIGN
(define (ceiling-coords vector align)
    (* (ceiling-quotient (car vector) align) align)
    (* (ceiling-quotient (cdr vector) align) align)
; Get minimum X and minimum Y of two pairs of coords
(define (min-coords coord1 coord2)
  (let ((x (min (car coord1) (car coord2)))
        (y (min (cdr coord1) (cdr coord2))))
    ; return value
    (cons x y)))
; Copy, move and rotate current selection. The selected objects
; are first copied, then translated by VECTOR and finally rotated
; by ANGLE about center which is calculated as rounded by 100
; lower left coordinate of all objects in selection.
; If no objects are selected, opens gschem message dialog with
; warning.
; Returns the copied objects.
(define (copy-move-and-rotate-selection vector angle)
  (let ((objects (page-selection (active-page))))
    (if (null? objects)
      (gschem-msg "Select something first!")
      ; else
      (let* ((copied-objects (map copy-object objects))
             (translated-objects (apply translate-objects! vector copied-objects))
             (bounds (apply object-bounds translated-objects))
             (rotation-center (ceiling-coords (min-coords (car bounds) (cdr bounds)) 100))
             (rotated-objects (apply rotate-objects! rotation-center angle translated-objects)))
        (apply page-append! (active-page) rotated-objects)
; Multiply VECTOR which must be a pair by NUMBER
(define (multiply-vector-by vector number)
  (cons (* number (car vector)) (* number (cdr vector))))
; Copy, move and rotate current selection NUMBER times. Applies
; the copy-move-and-rotate-selection procedure multiple times
; increasing every time vector and angle by given values of VECTOR
; and ANGLE.
; If no objects are selected, opens gschem message dialog with
; warning.
; Return value is unspecified.
(define (multiple-copy-move-and-rotate-selection vector angle num)
  (if (null? (page-selection (active-page)))
    (gschem-msg "Select something first!")
    ; else
    (do ((i num (1- i)))
      ((= i 0))
        (multiply-vector-by vector i) (* angle i)))
; Abbreviated name for the multiple-copy-move-and-rotate-selection
; procedure
(define mcmars multiple-copy-move-and-rotate-selection)

Group attribute editing

Let's suppose you have selected several resistors' refdeses and want to rename them at once, e.g., if they were copy from another place.

(use-modules (gschem selection))
(define (set-selected-attribs-value! value)
    (lambda (attrib)
      (set-attrib-value! attrib value))
    (page-selection (active-page))))

Usage of the procedure in gschem:

(set-selected-attribs-value! "R100.?")

Now, after renumbering them using T U, you copy them all and want to rename those copied resistors appending a suffix:

(use-modules (gschem selection))
(define (append-selected-attribs-suffix! suffix)
    (lambda (attrib)
        (string-append (attrib-value attrib) suffix)))
    (page-selection (active-page))))

Usage of the procedure in gschem:

(append-selected-attribs-suffix! "-top")

Now, let's rename some other attributes by adding a prefix:

(use-modules (gschem selection))
(define (append-selected-attribs-prefix! prefix)
    (lambda (object)
      (and (attribute? object)
             (string-append prefix (attrib-value object)))))
    (page-selection (active-page))))

Usage of the procedure in gschem:

(append-selected-attribs-prefix! "A1.")

Let's replace first letters of selected attribs with prefix:

(use-modules (gschem selection))
(define (replace-selected-attribs-prefix! prefix)
    (lambda (object)
      (and (attribute? object)
               (string-copy (attrib-value object) 1)))))
    (page-selection (active-page))))

Usage of the procedure in gschem:

(replace-selected-attribs-prefix! "C")

Let's rename selected netname= attributes increasing them by a fixed number:

(use-modules (gschem selection))
(define (add-selected-attribs-number! number)
    (lambda (object)
      (and (attribute? object)
               (+ (string->number (attrib-value object)) number)))))
    (page-selection (active-page))))

Usage of the procedure in gschem:

(add-selected-attribs-number! 100)

We could set any function instead of ”+” on the net number in this procedure. For instance:

(use-modules (gschem selection))
(define (use-another-func! func)
    (lambda (object)
      (and (attribute? object)
               (func (string->number (attrib-value object)))))))
    (page-selection (active-page))))

Usage of the procedure in gschem:

(use-another-func! -)
(define (multiply-by-2 x)
  (* 2 x))
(use-another-func! multiply-by-2)
geda/guile_scripting.txt · Last modified: 2015/09/23 12:41 by vzh
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki