User Tools

Site Tools


geda:guile_scripting.ru

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
geda:guile_scripting.ru [2014/04/23 08:23]
vzh Updated using po4a
geda:guile_scripting.ru [2015/09/23 13:08]
vzh Updated translation
Line 25: Line 25:
 gEDA gschem]]// и раздел [[geda:​gnetlist_ug.ru#​API драйвера в Scheme]] gEDA gschem]]// и раздел [[geda:​gnetlist_ug.ru#​API драйвера в Scheme]]
 //​[[geda:​gnetlist_ug.ru|Руководства пользователя gEDA gnetlist]]//​. //​[[geda:​gnetlist_ug.ru|Руководства пользователя gEDA gnetlist]]//​.
 +
 +==== Справочная информация ====
 +  * [[geda>​gEDA:​gnetlist Scheme primitives|Примитивы Scheme для gnetlist]]
 +
 +==== Примеры скриптов ====
 +Каждый скрипт можно скачать и загрузить в **gschem**:
 +  * нажмите <​key>:</​key>​ и введите <code lisp>​(load "​filename.scm"​)</​code>​
 +  * затем нажмите <​key>​Enter</​key>​
 +
 +=== Удаление объектов с заданными свойствами ===
 +Например,​ удалим все объекты,​ являющиеся окружностями или дугами с нулевым
 +радиусом
 +
 +<file lisp remove-objects.scm>​
 +(use-modules (geda page))
 +
 +; Проверяет,​ является ли объект OBJECT окружностью (circle)
 +; или дугой (arc) с нулевым радиусом
 +(define (zero-radius-object?​ object)
 +  (or
 +    (and (circle? object) (= (circle-radius object) 0))
 +    (and (arc?    object) (= (arc-radius ​   object) 0))))
 +
 +(apply page-remove! (active-page)
 +       ​(filter
 +         ​zero-radius-object?​
 +         ​(page-contents (active-page))))
 +</​file>​
 +
 +Предположим,​ нам необходимо удалить компонент с известным атрибутом,​ тогда
 +нам нужно также отделить и удалить все его атрибуты. ​ Функция,​ определённая
 +ниже делает именно это. ​ <file lisp remove-components-with-attribs.scm>​
 +(use-modules (geda page))
 +(use-modules (geda object))
 +(use-modules (geda attrib))
 +
 +; Удаляет все компоненты,​ имеющие атрибут NAME=VALUE, со страницы PAGE
 +(define (delete-components-by-attrib! page name value)
 +  (for-each
 +    (lambda (obj)
 +      (if (component? obj)
 +        (for-each
 +          (lambda (attr)
 +            (and
 +              (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)))
 +</​file>​
 +
 +После загрузки файла, нажмите <​key>:</​key>​ и введите,​ например,​ <code lisp>
 +(delete-components-by-attrib! (active-page) "​refdes"​ "​R1"​) ​ </​code>​
 +
 +=== Процедуры для ввода/​вывода ===
 +Следующий скрипт определяет две процедуры,​ которые могут использоваться
 +в режиме пакетной обработки с помощью скриптов для **gaf shell**:
 +  * ''​schematic-file->​page''​
 +  * ''​page->​schematic-file''​
 +
 +<file lisp geda-io.scm>​
 +(use-modules (ice-9 lineio))
 +(use-modules (geda page))
 +
 +; Процедуры ввода/​вывода
 +; Читает файл FILE и выводит строку
 +(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) ; тест
 +       ​(close-port port)  ; выражение(я) для вычисления в конце
 +       ​s) ​                ; возвращаемое значение
 +      ; empty body
 +      )))
 +
 +; читает файл схемы FILE и возвращает объект страницы PAGE
 +(define (schematic-file->​page file)
 +    (string->​page file (file->​string file)))
 +
 +; сохраняет страницу схемы PAGE в файл FILE
 +(define (page->​schematic-file page file)
 +  (with-output-to-file file
 +    (lambda () (display (page->​string page)))))
 +</​file>​
 +
 +
 +=== Копирование,​ перемещение и вращение объектов ===
 +<file lisp move-and-rotate.scm>​ ; Scripting example by vzh per request of
 +; Kai-Martin Knaak :-)
 +; Use at your own risk.
 +
 +; Основная процедура здесь
 +; multiple-copy-move-and-rotate-selection,​ что можно сократить до
 +; mcmars.
 +; Использование:​
 +;   ​запустите gschem, чтобы там можно было использовать этот скрипт,​ например
 +;     ​gschem -s move-and-rotate.scm
 +;   ​выделите объекты в gschem, нажмите ':'​ (двоеточие) и наберите
 +;     ​(mcmars '(1000 . 500) 90 10)
 +;   ​нажмите <​Enter>​
 +; Наслаждайтесь!
 +
 +
 +(use-modules (gschem selection))
 +
 +; округление координат по ALIGN
 +(define (ceiling-coords vector align)
 +  (cons
 +    (* (ceiling-quotient (car vector) align) align)
 +    (* (ceiling-quotient (cdr vector) align) align)
 +    ))
 +
 +; Получение минимума X и минимума Y двух пар координат
 +(define (min-coords coord1 coord2)
 +  (let ((x (min (car coord1) (car coord2)))
 +        (y (min (cdr coord1) (cdr coord2))))
 +    ; возвращаемое значение
 +    (cons x y)))
 +
 +; Копирование,​ перемещение и вращение текущего выделения. Выделенные объекты
 +; сначала копируются,​ затем перемещаются на вектор VECTOR и, наконец,​ вращаются
 +; на угол ANGLE вокруг центра,​ который рассчитывается как округлённая до
 +; множителей 100 левая нижняя координата всех объектов в выделении.
 +; Если никакие объекты не выделены,​ открывает диалоговое окно сообщений gschem
 +; с предупреждением.
 +; Возвращает скопированные объекты.
 +(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)
 +        rotated-objects)
 +      )))
 +
 +; Умножает VECTOR, который должен быть парой, на число NUMBER
 +(define (multiply-vector-by vector number)
 +  (cons (* number (car vector)) (* number (cdr vector))))
 +
 +; Копирование,​ перемещение и вращение текущего выделения количество
 +; раз, указанное аргументом NUMBER. Применяет процедуру
 +; copy-move-and-rotate-selection несколько раз, каждый раз увеличивая
 +; вектор и угол на заданные значения VECTOR и ANGLE.
 +; Если никакие объекты не выделены,​ открывает gschem message dialog with
 +; warning.
 +; Если никакие объекты не выделены,​ открывает диалоговое окно сообщений gschem
 +; с предупреждением.
 +; Возвращаемое значение не определено.
 +(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))
 +      (copy-move-and-rotate-selection
 +        (multiply-vector-by vector i) (* angle i)))
 +    ))
 +
 +; Сокращение для имени процедуры multiple-copy-move-and-rotate-selection
 +(define mcmars multiple-copy-move-and-rotate-selection) ​ </​file>​
 +
 +
 +=== Редактирование группы атрибутов ===
 +Допустим,​ вы выделили несколько позиционных обозначений (атрибут refdes)
 +резисторов и хотите переименовать их все сразу, например,​ если они были
 +скопированы из другого места. ​ <file lisp set-selected-attribs-value>​
 +(use-modules (gschem selection))
 +
 +(define (set-selected-attribs-value! value)
 +  (for-each
 +    (lambda (attrib)
 +      (set-attrib-value! attrib value))
 +    (page-selection (active-page))))
 +</​file>​
 +
 +Использование процедуры в **gschem**: <code lisp>
 +(set-selected-attribs-value! "​R100.?"​) ​ </​code>​
 +
 +Теперь,​ после изменения их номеров с помощью <​key>​t</​key>​ <​key>​u</​key>,​ вы
 +копируете их все и хотите переименовать эти скопированные резисторы,​ добавив
 +суффикс:​ <file lisp append-selected-attribs-suffix.scm>​
 +(use-modules (gschem selection))
 +
 +(define (append-selected-attribs-suffix! suffix)
 +  (for-each
 +    (lambda (attrib)
 +      (set-attrib-value!
 +        attrib
 +        (string-append (attrib-value attrib) suffix)))
 +    (page-selection (active-page))))
 +</​file>​
 +
 +Использование процедуры в **gschem**: <code lisp>
 +(append-selected-attribs-suffix! "​-top"​) ​ </​code>​
 +
 +Теперь переименуем несколько других атрибутов,​ добавив префикс:​ <file lisp
 +append-selected-attribs-prefix.scm>​
 +(use-modules (gschem selection))
 +
 +(define (append-selected-attribs-prefix! prefix)
 +  (for-each
 +    (lambda (object)
 +      (and (attribute? object)
 +           ​(set-attrib-value!
 +             ​object
 +             ​(string-append prefix (attrib-value object)))))
 +    (page-selection (active-page))))
 +</​file>​
 +
 +Использование процедуры в **gschem**: <code lisp>
 +(append-selected-attribs-prefix! "​A1."​) ​ </​code>​
 +
 +Давайте заменим первые буквы выделенных атрибутов префиксом:​ <file lisp
 +append-selected-attribs-prefix.scm>​
 +(use-modules (gschem selection))
 +
 +(define (replace-selected-attribs-prefix! prefix)
 +  (for-each
 +    (lambda (object)
 +      (and (attribute? object)
 +           ​(set-attrib-value!
 +             ​object
 +             ​(string-append
 +               ​prefix
 +               ​(string-copy (attrib-value object) 1)))))
 +    (page-selection (active-page))))
 +</​file>​
 +
 +Использование процедуры в **gschem**: <code lisp>
 +(replace-selected-attribs-prefix! "​C"​) ​ </​code>​
 +
 +Давайте переименуем выделенные атрибуты ''​netname='',​ увеличив их значения
 +на определённое число: <file lisp add-selected-attribs-number.scm>​
 +(use-modules (gschem selection))
 +
 +(define (add-selected-attribs-number! number)
 +  (for-each
 +    (lambda (object)
 +      (and (attribute? object)
 +           ​(set-attrib-value!
 +             ​object
 +             ​(number->​string
 +               (+ (string->​number (attrib-value object)) number)))))
 +    (page-selection (active-page))))
 +</​file>​
 +
 +Использование процедуры в **gschem**: <code lisp>
 +(add-selected-attribs-number! 100)  </​code>​
 +
 +Мы могли бы задать любую функцию вместо "​+"​ для номера соединения в этой
 +процедуре. ​ Например:​ <file lisp use-another-func.scm>​
 +(use-modules (gschem selection))
 +
 +(define (use-another-func! func)
 +  (for-each
 +    (lambda (object)
 +      (and (attribute? object)
 +           ​(set-attrib-value!
 +             ​object
 +             ​(number->​string
 +               (func (string->​number (attrib-value object)))))))
 +    (page-selection (active-page))))
 +</​file>​
 +
 +Использование процедуры в **gschem**:
 +<code lisp>
 +(use-another-func! -)
 +(define (multiply-by-2 x)
 +  (* 2 x))
 +(use-another-func! multiply-by-2)
 +</​code>​
  
geda/guile_scripting.ru.txt · Last modified: 2016/02/09 08:10 by vzh