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/02/20 15:14]
127.0.0.1 external edit
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
 +используется [[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//)   * [[gnetlist scheme tutorial.ru|Написание скриптов драйверов gnetlist на Scheme]] (//John Doty//)
-  * Смотрите также раздел [[geda:​gnetlist_ug.ru#​API драйвера в Scheme]] Руководства пользователя **gEDA gnetlist** 
  
 +Смотрите также раздел [[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**:
 +  * нажмите <​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>​
  
-==== Справка ​по C-библиотеке libgeda ==== +Теперь, после изменения их номеров с помощью <​key>​t</​key>​ <​key>​u</​key>, ​вы 
-**libgeda** определяет набор низкоуровневых функций на **C**, ​таких как +копируете их все ​и хотите ​переименовать эти скопированные резисторы, добавив 
-функции библиотеки компонентов и библиотеки подсхем, для ​конфигурирования +суффикс: <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> 
-  ​attribute +(append-selected-attribs-suffix! "​-top"​) ​ </​code>​
-  ​object +
-  ​* page+
  
 +Теперь переименуем несколько других атрибутов,​ добавив префикс:​ <file lisp
 +append-selected-attribs-prefix.scm>​
 +(use-modules (gschem selection))
  
-=== Переменные === +(define (append-selected-attribs-prefix! prefix
-Основная конфигурация ​(определённая в **libgeda**,​ только для чтения+  ​(for-each 
-  ​* path-sep +    ​(lambda (object) 
-  * geda-rc-path +      (and (attribute? object) 
-  * geda-data-path+           (set-attrib-value! 
 +             object 
 +             ​(string-append prefix (attrib-value object))))) 
 +    (page-selection (active-page)))) 
 +</​file>​
  
-Идентификаторы типов ​объектов (определённые в **libgeda**, только для чтения) +Использование процедуры в **gschem**: <code lisp> 
-  * OBJ_LINE +(append-selected-attribs-prefix! "​A1."​)  ​</​code>​
-  * OBJ_BOX +
-  * OBJ_PICTURE +
-  * OBJ_CIRCLE +
-  * OBJ_NET +
-  * OBJ_BUS +
-  * OBJ_COMPLEX +
-  * OBJ_TEXT +
-  * OBJ_PIN +
-  * OBJ_ARC +
-  * OBJ_ROUTE +
-  * OBJ_THRU_HOLE +
-  * OBJ_PLACEHOLDER+
  
 +Давайте заменим первые буквы выделенных атрибутов префиксом:​ <file lisp
 +append-selected-attribs-prefix.scm>​
 +(use-modules (gschem selection))
  
-=== Функции === +(define (replace-selected-attribs-prefix! prefix) 
-Библиотека компонентов:​ +  ​(for-each 
-  ​* component-library +    ​(lambda (object) 
-  * component-library-command +      (and (attribute? object) 
-  * component-library-funcs +           (set-attrib-value! 
-  * component-library-search +             object 
-  * reset-component-library+             ​(string-append 
 +               prefix 
 +               ​(string-copy (attrib-value object) 1))))) 
 +    (page-selection (active-page)))) 
 +</​file>​
  
-Библиотека подсхем+Использование процедуры в **gschem**<code lisp> 
-  * source-library +(replace-selected-attribs-prefix! "​C"​) ​ </​code>​
-  * source-library-search +
-  * reset-source-library+
  
-Конфигурация поведения ​**libgeda** (только для записи): +Давайте переименуем выделенные ​атрибуты ''​netname='',​ увеличив их значения 
-  * always-promote-attributes +на определённое число<file lisp add-selected-attribs-number.scm>​ 
-  * attribute-promotion +(use-modules (gschem selection))
-  * bitmap-directory +
-  * bus-ripper-symname +
-  * font-directory +
-  * keep-invisible +
-  * map-font-character-to-file +
-  * postscript-prolog +
-  * promote-invisible +
-  * scheme-directory +
-  * untitled-name +
-  * world-size+
  
-Манипуляторы типа ''​smob'':​ +(define (add-selected-attribs-number! number) 
-  * get-attribute-name-value +  ​(for-each 
-  ​* get-attribute-bounds +    ​(lambda (object) 
-  * get-attribute-angle +      (and (attribute? object) 
-  * calcule-new-attrib-bounds +           (set-attrib-value! 
-  * get-object-attributes +             ​object 
-  * get-attrib-value-by-attrib-name +             ​(number->string 
-  * get-object-type +               (+ (string->number (attrib-value object)) number))))) 
-  * get-line-width +    (page-selection (active-page)))) 
-  * get-page-filename+</​file>​
  
 +Использование процедуры в **gschem**: <code lisp>
 +(add-selected-attribs-number! 100)  </​code>​
  
-==== libgeda geda.scm ==== +Мы могли бы задать ​любую функцию ​вместо "​+" ​для номера соединения ​в этой 
-Файл //''​geda.scm''//, ​установленный ​с **libgeda**,​ предоставляет несколько +процедуре.  Например: <file lisp use-another-func.scm> 
-полезных функций как для простой ​обработки путей доступа и файлов,​ так и для +(use-modules (gschem selection))
-загрузки rc-файлов из каталогов //''​gafrc.d''//​.+
  
 +(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**:​ 
-  ​build-path +<code lisp> 
-  * regular-file? +(use-another-func! ​-) 
-  * directory? +(define (multiply-by-2 x) 
-  * has-suffix? +  ​(2 x)) 
-  * load-scheme-dir+(use-another-func! multiply-by-2) 
 +</​code>​
  
geda/guile_scripting.ru.1329768896.txt.gz · Last modified: 2012/03/10 16:27 (external edit)