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
geda:guile_scripting.ru [2012/03/10 16:27]
vzh Updated
geda:guile_scripting.ru [2016/02/09 08:10] (current)
vzh Added a link to a new document
Line 1: Line 1:
 +//Эта страница доступна также на следующих языках://​
 +[[guile_scripting|English]]
 +
 ===== Скрипты Guile ===== ===== Скрипты Guile =====
  
- +В gEDA/gaf для обеспечения возможности написания скриптов на Scheme 
-В gEDA/gaf +используется [[http://​www.gnu.org/​s/​guile/​|Guile Scheme]], и в распоряжении 
-для обеспечения возможности написания скриптов на Scheme используется +разработчика оказываются все возможности языка Guile. //​Справочное 
-[[http://​www.gnu.org/​s/​guile/​|Guile Scheme]], и в распоряжении разработчика +руководство по Guile// [//Guile Reference Manual//] можно найти либо в 
-оказываются все возможности языка Guile. //​Справочное руководство по Guile// +формате Info (''​[[info://​guile|info guile]]''​ на большинстве систем),​ либо в 
-[//Guile Reference Manual//] можно найти либо в формате Info +формате HTML на 
-(''​[[info://​guile|info guile]]''​ на большинстве систем),​ либо в формате HTML +[[http://​www.gnu.org/​software/​guile/​docs/​docs.html|веб-странице Guile]].
-на [[http://​www.gnu.org/​software/​guile/​docs/​docs.html|веб-странице Guile]].+
  
 Для доступа к объектам и страницам gEDA и для их изменения имеется набор Для доступа к объектам и страницам gEDA и для их изменения имеется набор
Line 15: Line 17:
 (''​[[info://​geda-scheme|info geda-scheme]]''​). (''​[[info://​geda-scheme|info geda-scheme]]''​).
  
 +==== Учебники ====
  
-==== Руководства ==== 
   * [[gnetlist scheme tutorial.ru|Написание скриптов драйверов gnetlist на Scheme]] (//John Doty//)   * [[gnetlist scheme tutorial.ru|Написание скриптов драйверов gnetlist на Scheme]] (//John Doty//)
  
-Смотрите также раздел [[geda:​gschem_ug:​extensions.ru|Расширение функциональности gschem]] +Смотрите также раздел [[geda:​gschem_ug:​extensions.ru|Расширение 
-//​[[geda:​gschem_ug.ru|Руководства пользователя gEDA gschem]]// и раздел +функциональности gschem]] //​[[geda:​gschem_ug.ru|Руководства пользователя 
-[[geda:​gnetlist_ug.ru#​API драйвера в Scheme]] +gEDA gschem]]// и раздел [[geda:​gnetlist_ug.ru#​API драйвера в Scheme]] 
-//[[geda:gschem_ug.ru|Руководства пользователя gEDA gnetlist]]//​.+//[[geda:gnetlist_ug.ru|Руководства пользователя gEDA gnetlist]]//​. 
 + 
 +==== Справочная информация ==== 
 +  * [[geda>​gEDA:​gnetlist Scheme primitives|Примитивы Scheme для gnetlist]] 
 +  * [[gEDA:​gschem repl.ru|Использование REPL в gschem]] 
 + 
 +==== Примеры скриптов ==== 
 +Каждый скрипт можно скачать и загрузить в **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.1331414841.txt.gz · Last modified: 2012/03/10 16:27 by vzh