//Эта страница доступна также на следующих языках:// [[guile_scripting|English]] ===== Скрипты Guile ===== В gEDA/gaf для обеспечения возможности написания скриптов на Scheme используется [[http://www.gnu.org/s/guile/|Guile Scheme]], и в распоряжении разработчика оказываются все возможности языка Guile. //Справочное руководство по Guile// [//Guile Reference Manual//] можно найти либо в формате Info (''[[info://guile|info guile]]'' на большинстве систем), либо в формате HTML на [[http://www.gnu.org/software/guile/docs/docs.html|веб-странице Guile]]. Для доступа к объектам и страницам gEDA и для их изменения имеется набор модулей, называемый gEDA Scheme API. Есть и //Справочное руководство по Scheme в gEDA// [//gEDA Scheme Reference Manual//] в формате Info (''[[info://geda-scheme|info geda-scheme]]''). ==== Учебники ==== * [[gnetlist scheme tutorial.ru|Написание скриптов драйверов gnetlist на Scheme]] (//John Doty//) Смотрите также раздел [[geda:gschem_ug:extensions.ru|Расширение функциональности gschem]] //[[geda:gschem_ug.ru|Руководства пользователя gEDA gschem]]// и раздел [[geda:gnetlist_ug.ru#API драйвера в Scheme]] //[[geda:gnetlist_ug.ru|Руководства пользователя gEDA gnetlist]]//. ==== Справочная информация ==== * [[geda>gEDA:gnetlist Scheme primitives|Примитивы Scheme для gnetlist]] * [[gEDA:gschem repl.ru|Использование REPL в gschem]] ==== Примеры скриптов ==== Каждый скрипт можно скачать и загрузить в **gschem**: * нажмите : и введите (load "filename.scm") * затем нажмите Enter === Удаление объектов с заданными свойствами === Например, удалим все объекты, являющиеся окружностями или дугами с нулевым радиусом (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)))) Предположим, нам необходимо удалить компонент с известным атрибутом, тогда нам нужно также отделить и удалить все его атрибуты. Функция, определённая ниже делает именно это. (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))) После загрузки файла, нажмите : и введите, например, (delete-components-by-attrib! (active-page) "refdes" "R1") === Процедуры для ввода/вывода === Следующий скрипт определяет две процедуры, которые могут использоваться в режиме пакетной обработки с помощью скриптов для **gaf shell**: * ''schematic-file->page'' * ''page->schematic-file'' (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))))) === Копирование, перемещение и вращение объектов === ; 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) ; нажмите ; Наслаждайтесь! (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) === Редактирование группы атрибутов === Допустим, вы выделили несколько позиционных обозначений (атрибут refdes) резисторов и хотите переименовать их все сразу, например, если они были скопированы из другого места. (use-modules (gschem selection)) (define (set-selected-attribs-value! value) (for-each (lambda (attrib) (set-attrib-value! attrib value)) (page-selection (active-page)))) Использование процедуры в **gschem**: (set-selected-attribs-value! "R100.?") Теперь, после изменения их номеров с помощью t u, вы копируете их все и хотите переименовать эти скопированные резисторы, добавив суффикс: (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)))) Использование процедуры в **gschem**: (append-selected-attribs-suffix! "-top") Теперь переименуем несколько других атрибутов, добавив префикс: (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)))) Использование процедуры в **gschem**: (append-selected-attribs-prefix! "A1.") Давайте заменим первые буквы выделенных атрибутов префиксом: (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)))) Использование процедуры в **gschem**: (replace-selected-attribs-prefix! "C") Давайте переименуем выделенные атрибуты ''netname='', увеличив их значения на определённое число: (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)))) Использование процедуры в **gschem**: (add-selected-attribs-number! 100) Мы могли бы задать любую функцию вместо "+" для номера соединения в этой процедуре. Например: (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)))) Использование процедуры в **gschem**: (use-another-func! -) (define (multiply-by-2 x) (* 2 x)) (use-another-func! multiply-by-2)