<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4022155443158713503</id><updated>2011-10-25T07:59:55.644+04:00</updated><category term='wand'/><category term='xwem'/><category term='ffi'/><category term='macos'/><category term='bsoy'/><category term='internals'/><category term='rus'/><title type='text'>SXEmacsen</title><subtitle type='html'>Блог о SXEmacs на русском языке</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>21</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-4526822744656780930</id><published>2010-04-22T23:51:00.001+04:00</published><updated>2010-04-22T23:51:42.290+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='xwem'/><title type='text'>Гестуры в xwem</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;


&lt;p class='fl'&gt;Совсем забыл про классную фукнциональность в xwem — гестуры &lt;acronym title='Also Known As'&gt;aka&lt;/acronym&gt; strokes.   Это когда рисуешь что-нибудь на экране, а у тебя выполняется какая-нибудь команда.  В родном (S)XEmacs есть поддержка, но она конечно далека от идела с точки зрения пользовательского интерфейса, зато дало нужную функциональность для реализации гестур в xwem.&lt;/p&gt;&lt;p&gt;Вот список гестур, которыми я пользуюсь:&lt;/p&gt;&lt;div class='figure' align='center'&gt;&lt;img style='width: 603px; height: 231px;' src='http://lgarc.narod.ru/sxemacsen/img/xwem-strokes/global-strokes.png' alt='global strokes'/&gt;
&lt;p class='caption'&gt;Глобальные гестуры&lt;/p&gt;&lt;/div&gt;&lt;div class='figure' align='center'&gt;&lt;img style='width: 616px; height: 40px;' src='http://lgarc.narod.ru/sxemacsen/img/xwem-strokes/xemacs-strokes.png' alt='xemacs strokes'/&gt;
&lt;p class='caption'&gt;Гестуры локальные для xemacs фреймов&lt;/p&gt;&lt;/div&gt;&lt;div class='figure' align='center'&gt;&lt;img style='width: 607px; height: 104px;' src='http://lgarc.narod.ru/sxemacsen/img/xwem-strokes/gv-strokes.png' alt='gv strokes'/&gt;
&lt;p class='caption'&gt;Гестуры локальные для ghostview приложений&lt;/p&gt;&lt;/div&gt;&lt;div class='figure' align='center'&gt;&lt;img style='width: 604px; height: 198px;' src='http://lgarc.narod.ru/sxemacsen/img/xwem-strokes/opera-strokes.png' alt='opera strokes'/&gt;
&lt;p class='caption'&gt;Гестуры локальные для бравзера opera&lt;/p&gt;&lt;/div&gt;&lt;div class='figure' align='center'&gt;&lt;img style='width: 604px; height: 200px;' src='http://lgarc.narod.ru/sxemacsen/img/xwem-strokes/firefox-strokes.png' alt='firefox strokes'/&gt;
&lt;p class='caption'&gt;Гестуры локальные для бравзера firefox&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Скачать эти гестуры можно &lt;a href='http://lgarc.narod.ru/sxemacs/dot.strokes' class='reference external'&gt;тут&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Как видно из скринов, гестуры в xwem достаточно прокаченные: они могут запускать команды, произвольные e-lisp выражения, эмулировать нажатия кнопок, а также вводить в текущее приложение всякие строки (на скринах нет такого варианта гестуры).&lt;/p&gt;

    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-4526822744656780930?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/4526822744656780930/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=4526822744656780930' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/4526822744656780930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/4526822744656780930'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2010/04/xwem.html' title='Гестуры в xwem'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-1005535457145366097</id><published>2010-04-03T03:19:00.001+04:00</published><updated>2010-04-03T03:19:28.579+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wand'/><title type='text'>SXEmacs живёт</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;


&lt;p class='fl'&gt;После некоторого затишья проект SXEmacs продолжил развитие.  Появились merge-requestы и что-то всё таки делается.  Залили мои патчи к &lt;acronym title='Foreign function interface'&gt;FFI&lt;/acronym&gt;, которые реализуют новый тип &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;safe-string&lt;/span&gt;&lt;/tt&gt; в помощь дядьке, который пишет &lt;acronym title='Foreign function interface'&gt;FFI&lt;/acronym&gt; к &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;libdbus&lt;/span&gt;&lt;/tt&gt;.  Так же в &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt; я добавил поддержку модного liquid scale, кто не знает, то это выглядит &lt;a href='http://www.youtube.com/watch?v=tStUYQ-70zQ' class='reference external'&gt;вот так&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Кстати, я наконец-то придумал как можно использовать &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;wand-button&lt;/span&gt;&lt;/tt&gt; в стандартном &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;customize&lt;/span&gt;&lt;/tt&gt;!&lt;/p&gt;

    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-1005535457145366097?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/1005535457145366097/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=1005535457145366097' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/1005535457145366097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/1005535457145366097'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2010/04/sxemacs.html' title='SXEmacs живёт'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-526363359080033106</id><published>2010-02-07T21:12:00.001+03:00</published><updated>2010-02-07T21:12:31.807+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='macos'/><title type='text'>Интеграция SXEmacs с Mac OS</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;


&lt;p class='fl'&gt;Немного сомневаюсь, хочу посоветоваться с пользователями GNU Emacs под Mac &lt;acronym title='Operating System'&gt;OS&lt;/acronym&gt;.  Есть идея и возможность реализовать в SXEmacs &lt;acronym title='Foreign function interface'&gt;FFI&lt;/acronym&gt; к &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;libobjc&lt;/span&gt;&lt;/tt&gt;.  Только не очень представляю как его потом можно полезно использовать.&lt;/p&gt;&lt;p&gt;Вообще я хочу сделать чтобы эпловский multitouch мог работать в SXEmacs (конкретно в &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt;).  Я не представляю как реализован multitouch и что нужно для того, чтобы он работал.  Просветите пожалуйста если кто в курсе.&lt;/p&gt;&lt;p&gt;Ещё хотел бы посоветоваться какая именно интеграция с Mac &lt;acronym title='Operating System'&gt;OS&lt;/acronym&gt; была бы полезна в Emacs?  Мне пока на ум приходит только использование нативных виджетов для &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;M-x&lt;/span&gt; &lt;span class='pre'&gt;customize&lt;/span&gt; &lt;span class='pre'&gt;RET&lt;/span&gt;&lt;/tt&gt;, чтобы выглядело как настройки у других приложений под Mac &lt;acronym title='Operating System'&gt;OS&lt;/acronym&gt;.  Само собой ещё growl и голос.&lt;/p&gt;&lt;p&gt;Ещё хотелось бы, чтобы &lt;a href='http://code.google.com/p/slife/' class='reference external'&gt;Slife.app&lt;/a&gt; каким-нибудь образом брал данные из запущенного Emacs (потому что отчёты &lt;a href='http://code.google.com/p/slife/' class='reference external'&gt;Slife.app&lt;/a&gt; типа "95% времени работает приложение X11.app" меня как-то не возбуждают), но как это сделать вообще без понятия.&lt;/p&gt;&lt;p&gt;Если наработается хоть пусть и небольшая интеграция с Mac &lt;acronym title='Operating System'&gt;OS&lt;/acronym&gt;, то это будет очень большим подспорьем для привлечения нужных людей (возможно даже из проекта GNU Emacs ;))) к реализации нативного &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;redisplay&lt;/span&gt;&lt;/tt&gt; в SXEmacs под Mac &lt;acronym title='Operating System'&gt;OS&lt;/acronym&gt;.&lt;/p&gt;

    &lt;/div&gt;
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-526363359080033106?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/526363359080033106/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=526363359080033106' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/526363359080033106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/526363359080033106'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2010/02/sxemacs-mac-os.html' title='Интеграция SXEmacs с Mac OS'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-8869420671264267255</id><published>2009-12-16T01:39:00.002+03:00</published><updated>2009-12-16T01:42:45.169+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wand'/><title type='text'>Генератор кнопок</title><content type='html'>&lt;!-- Copyright (C) 2009 Zajcev Evgeny --&gt;&lt;!-- $Id$ --&gt;&lt;p class="fl"&gt;В (S)XEmacs есть классный package, называется &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;xpm-button.el&lt;/span&gt;&lt;/tt&gt;.  Он умеет  на лету генерировать картинку с кнопкой.  Всё вроде бы хорошо, но &amp;laquo;красота&amp;raquo; сгенерированных кнопок повергает в уныние.  Решил написать достаточно гибкий генератор красивых кнопок используя &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt;.  По мере написания генератора, добавлял необходимый функционал в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt;.  Вот что в итоге получилось:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;wand-button&lt;/span&gt; &lt;span style="color: #000000"&gt;150&lt;/span&gt; &lt;span style="color: #000000"&gt;32&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Wand Button&amp;quot;&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:bg&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;cornflowerblue&amp;quot;&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:fg&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;white&amp;quot;&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:round&lt;/span&gt; &lt;span style="color: #000000"&gt;8.0&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:depth&lt;/span&gt; &lt;span style="color: #000000"&gt;1&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:yoff&lt;/span&gt; &lt;span style="color: #000000"&gt;8&lt;/span&gt; &lt;span style="color: #00008b; font-style: italic"&gt;; :type &amp;#39;pressed&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:wand-font&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;make-wand-font&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:family&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Zapfino&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;rarr; &lt;img alt="button1" src="http://lgarc.narod.ru/sxemacsen/img/wand-button1.png" style="width: 323px; height: 42px;" /&gt;&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;wand-button&lt;/span&gt; &lt;span style="color: #000000"&gt;100&lt;/span&gt; &lt;span style="color: #000000"&gt;20&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Wand Button&amp;quot;&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:bg&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;gray80&amp;quot;&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:fg&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;black&amp;quot;&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:round&lt;/span&gt; &lt;span style="color: #000000"&gt;10.0&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:contrast&lt;/span&gt; &lt;span style="color: #000000"&gt;0.5&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:depth&lt;/span&gt; &lt;span style="color: #000000"&gt;2&lt;/span&gt; &lt;span style="color: #00008b; font-style: italic"&gt;; :type &amp;#39;pressed&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:wand-font&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;make-wand-font&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:family&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Copperplate&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;rarr; &lt;img alt="button2" src="http://lgarc.narod.ru/sxemacsen/img/wand-button2.png" style="width: 224px; height: 28px;" /&gt;&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;wand-button&lt;/span&gt; &lt;span style="color: #000000"&gt;100&lt;/span&gt; &lt;span style="color: #000000"&gt;40&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;encode-coding-string&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;привет&amp;quot;&lt;/span&gt; &lt;span style="color: #CD0000"&gt;&amp;#39;utf-8&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:bg&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;palegreen&amp;quot;&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:fg&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;green&amp;quot;&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:round&lt;/span&gt; &lt;span style="color: #000000"&gt;0.0&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:depth&lt;/span&gt; &lt;span style="color: #000000"&gt;4&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:yoff&lt;/span&gt; &lt;span style="color: #000000"&gt;-2&lt;/span&gt; &lt;span style="color: #00008b; font-style: italic"&gt;; :type &amp;#39;pressed&lt;/span&gt;
             &lt;span style="color: #CD0000"&gt;:wand-font&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;make-wand-font&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:family&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Arial Black&amp;quot;&lt;/span&gt;
                                        &lt;span style="color: #CD0000"&gt;:size&lt;/span&gt; &lt;span style="color: #000000"&gt;20&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;rarr; &lt;img alt="button2" src="http://lgarc.narod.ru/sxemacsen/img/wand-button3.png" style="width: 225px; height: 50px;" /&gt;&lt;/p&gt;&lt;p&gt;Интересно будет этот функционал внедрить в Emacs widgets, а то кнопки там сделаны через очень большую задницу.&lt;/p&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/wand-button.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-8869420671264267255?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/8869420671264267255/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=8869420671264267255' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/8869420671264267255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/8869420671264267255'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2009/12/blog-post.html' title='Генератор кнопок'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-6848039620432348682</id><published>2009-11-27T01:04:00.004+03:00</published><updated>2009-11-27T01:17:30.775+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ffi'/><category scheme='http://www.blogger.com/atom/ns#' term='wand'/><title type='text'>Wand-mode - новые возможности</title><content type='html'>&lt;!-- Copyright (C) 2009 Zajcev Evgeny --&gt;&lt;!-- $Id: wand-mode-update1.rest,v 1.2 2009/11/26 18:27:59 00000000 Exp $ --&gt;&lt;p class="fl"&gt;Wand-mode развивается, с тех пор как я &lt;a class="reference" href="http://sxemacsen.blogspot.com/2008/12/wand-mode-display1.html"&gt;сделал описание&lt;/a&gt;, было добавлено несколько интересных возможностей.  Их я и опишу.&lt;/p&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id2" name="id2"&gt;Новшества&lt;/a&gt;&lt;/h2&gt;&lt;ul class="simple"&gt;&lt;li&gt;&lt;a class="reference" href="#id5"&gt;Использование имени файла в имени буфера&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#iptc"&gt;Поддержка IPTC профиля&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#id7"&gt;Простой редактор свойств изображения&lt;/a&gt;, можно легко редактировать &lt;acronym title="Exchangeable Image File Format"&gt;EXIF&lt;/acronym&gt; данные&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#fit-to-size"&gt;Новая операция: fit to size&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#modulate"&gt;Новая операция: modulate&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#grayscale"&gt;Новая операция: grayscale&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#id6"&gt;Глобальные операции&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="#pixel-color-picker"&gt;Pixel color picker&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id5" name="id5"&gt;Имя файла в имени буфера&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Откроем какую-нибудь картинку: &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-f&lt;/span&gt; &lt;span class="pre"&gt;lg-tree.jpg&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;, получаем примерно следующее:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="orig image" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/wand-update1/1.png" style="width: 500px; height: 324px;" /&gt;&lt;/div&gt;&lt;p&gt;Замечаем, что в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mode-line&lt;/span&gt;&lt;/tt&gt; отображается имя буфера, которое теперь содержит имя оригинального файла.  Удобно при переключении с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-b&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="modulate" name="modulate"&gt;Новая операция: modulate&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Фотка сама по себе классная, но природа выглядит как-то уныло, немного приукрасим, с помощью команды &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;o&lt;/span&gt; &lt;span class="pre"&gt;modulate&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt; &lt;span class="pre"&gt;saturation&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt; &lt;span class="pre"&gt;60&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;, получим результат:&lt;/p&gt;&lt;div align="center" class="figure"&gt;&lt;img alt="sat inc 60 percents" src="http://lgarc.narod.ru/sxemacsen/img/wand-update1/3.png" style="width: 660px; height: 350px;" /&gt;&lt;p class="caption"&gt;60% increased saturation&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Уже намного лучше.&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="iptc" name="iptc"&gt;Поддержка IPTC профиля&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Хочется добавить информацию о том, что это там на фотке. Воспользуемся редактором &lt;acronym title="International Press Telecommunications Council, metadata attributes applied to image"&gt;IPTC&lt;/acronym&gt; профиля.  Добавим &lt;acronym title="International Press Telecommunications Council, metadata attributes applied to image"&gt;IPTC&lt;/acronym&gt; теги с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;p&lt;/span&gt; &lt;span class="pre"&gt;caption&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt; &lt;span class="pre"&gt;lg&lt;/span&gt; &lt;span class="pre"&gt;climbes&lt;/span&gt; &lt;span class="pre"&gt;trees&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;p&lt;/span&gt; &lt;span class="pre"&gt;keywords&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt; &lt;span class="pre"&gt;js-kit,&lt;/span&gt; &lt;span class="pre"&gt;corporative&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;, получим:&lt;/p&gt;&lt;div align="center" class="figure"&gt;&lt;img alt="caption and keywords added" src="http://lgarc.narod.ru/sxemacsen/img/wand-update1/4.png" style="width: 660px; height: 400px;" /&gt;&lt;p class="caption"&gt;Caption and Keywords added&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="pixel-color-picker" name="pixel-color-picker"&gt;Pixel color picker&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Интересно какого цвета у меня трусы, кликнем на них и увидим:&lt;/p&gt;&lt;div align="center" class="figure"&gt;&lt;img alt="pixel color picker" src="http://lgarc.narod.ru/sxemacsen/img/wand-update1/5.png" style="width: 760px; height: 430px;" /&gt;&lt;p class="caption"&gt;Pixel color picker&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Видим координаты пикселя, по которому мы кликнули, его цвет и разложение по RGB.  Удобно.&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id6" name="id6"&gt;Глобальные операции&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Иногда нужно просмотреть несколько картинок применяя конкретный набор операций, например увеличение.  Для этого теперь есть команда фиксирования операций, по умолчанию висит на &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;O&lt;/span&gt;&lt;/tt&gt;, нажмём её и перейдём к следующей картинке в директории с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SPC&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;div align="center" class="figure"&gt;&lt;img alt="global operations" src="http://lgarc.narod.ru/sxemacsen/img/wand-update1/6.png" style="width: 750px; height: 480px;" /&gt;&lt;p class="caption"&gt;Global operations applied&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Видим список глобальных операций, а также замечаем, что они были автоматически применены к картинке.  Однако для этой картинки увеличение saturation не подходит.  Отменим с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;undo&lt;/span&gt;&lt;/tt&gt; (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-/&lt;/span&gt;&lt;/tt&gt;):&lt;/p&gt;&lt;div align="center" class="figure"&gt;&lt;img alt="operations canceled" src="http://lgarc.narod.ru/sxemacsen/img/wand-update1/7.png" style="width: 740px; height: 450px;" /&gt;&lt;p class="caption"&gt;Operations canceled&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Чтобы сбросить глобальные операции нужно нажать &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-u&lt;/span&gt; &lt;span class="pre"&gt;O&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id7" name="id7"&gt;Редактор свойств изображения&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Иногда нужно подправить &lt;acronym title="Exchangeable Image File Format"&gt;EXIF&lt;/acronym&gt; данные у изображения.  Лично я не пользуюсь этой возможностью (мне хватает &lt;acronym title="International Press Telecommunications Council, metadata attributes applied to image"&gt;IPTC&lt;/acronym&gt; профиля), но есть один знакомый фотограф, который попросил эту функциональность в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt;.  Мне не сложно за пару пива.  Вызвать редактор можно с помощью кнопки &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;e&lt;/span&gt;&lt;/tt&gt;.  Он отфильтрует свойства согласно переменной &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode-properties-pattern&lt;/span&gt;&lt;/tt&gt; (&amp;quot;^exif:&amp;quot; по умолчанию).&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="grayscale" name="grayscale"&gt;Новая операция: grayscale&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Существует множество методик преобразования картинки в чёрно-белую. Один из них, например, полностью удалить saturation с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;o&lt;/span&gt; &lt;span class="pre"&gt;modulate&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt; &lt;span class="pre"&gt;saturation&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt; &lt;span class="pre"&gt;-100&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;, что часто приводит к желаемому результату.  Всё же была добавлена возможность поменять colormap на grayscale &amp;mdash; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;o&lt;/span&gt; &lt;span class="pre"&gt;grayscale&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="fit-to-size" name="fit-to-size"&gt;Новая операция: fit to size&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Иногда нужно изменить размеры изображения, чтобы она влазила в определённый размер.  Теперь это можно сделать с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;o&lt;/span&gt; &lt;span class="pre"&gt;fit&lt;/span&gt; &lt;span class="pre"&gt;to&lt;/span&gt; &lt;span class="pre"&gt;size&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;. Эта операция запросит ширину, высоту и сохраняя соотношение сторон изменит размер.  Есть также пользовательская переменная &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode-scaler&lt;/span&gt;&lt;/tt&gt;, которая отвечает за то, какой преобразователь будет использован.  Вы можете создавать свои собственные преобразователи с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-make-scaler&lt;/span&gt;&lt;/tt&gt;; неплохой настройкой может быть:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;setq&lt;/span&gt; &lt;span style="color: #000000"&gt;Wand-mode-scaler&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;Wand-make-scaler&lt;/span&gt; &lt;span style="color: #CD0000"&gt;:GaussianFilter&lt;/span&gt; &lt;span style="color: #000000"&gt;1&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Документация к &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode-scaler&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-make-scaler&lt;/span&gt;&lt;/tt&gt; содержит исчерпывающую информацию о преобразователях.&lt;/p&gt;&lt;/div&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/wand-mode-update1.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-6848039620432348682?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/6848039620432348682/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=6848039620432348682' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/6848039620432348682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/6848039620432348682'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2009/11/wand-mode.html' title='Wand-mode - новые возможности'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-4253756778654542572</id><published>2009-11-12T17:35:00.002+03:00</published><updated>2009-11-12T17:37:55.893+03:00</updated><title type='text'>Судоку для (S)XEmacs</title><content type='html'>&lt;!-- Copyright (C) 2009 Zajcev Evgeny --&gt;&lt;!-- $Id: sudoku.rest,v 1.1.1.1 2009/10/31 08:24:51 00000000 Exp $ --&gt;&lt;p class="fl"&gt;Не спалось как-то ночью и мягкой подруги не было под рукой.  Решил поиграть во что-нибудь.  Тетрис слишком активный, сокобан уже прошёл весь, World of Goo перегревает комп &amp;mdash; решил погонять в судоку. Зашёл на &lt;a class="reference" href="http://websudoku.com"&gt;websudoku.com&lt;/a&gt; и начал играть, всё бы хорошо, но это не в SXEmacs и недоступно offline.  Решил написать &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sudoku.el&lt;/span&gt;&lt;/tt&gt; для игры в судоку под SXEmacs.  Поискал в инете и нашёл &lt;a class="reference" href="http://www.columbia.edu/~jr2075/sudoku.el"&gt;sudoku.el&lt;/a&gt; для (X)Emacs.  Скачал, запустил и не обрадовался, посмотрел код &amp;mdash; вообще расстроился.  В итоге ночь провёл за переписыванием &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sudoku.el&lt;/span&gt;&lt;/tt&gt;, чтобы удовлетворить свои нужды, а именно:&lt;/p&gt;&lt;ul class="simple"&gt;&lt;li&gt;Удобный, красивый и информативный интерфейс&lt;/li&gt;&lt;li&gt;Возможность скачивания судок с &lt;a class="reference" href="http://websudoku.com"&gt;websudoku.com&lt;/a&gt; и &lt;a class="reference" href="http://menneske.no/sudoku/"&gt;menneske.no&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Возможность печати судок&lt;/li&gt;&lt;li&gt;Возможность редактирования судок&lt;/li&gt;&lt;li&gt;Возможность сохранения/загрузки судок&lt;/li&gt;&lt;li&gt;Наличие карандашей для сложных техник и экспериментов&lt;/li&gt;&lt;li&gt;Возможность решать только реально сложные задачи, т.е. авто-заполнение (полу)очевидных полей&lt;/li&gt;&lt;/ul&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id1" name="id1"&gt;Пример&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Запускаем &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;M-x&lt;/span&gt; &lt;span class="pre"&gt;sudoku&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="sudoku-mode" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sud1.png" style="width: 1080px; height: 710px;" /&gt;&lt;/div&gt;&lt;p&gt;Сразу видим кучу очевидных полей для заполнения, например, R5C5 (где курсор) и понятно дело лениво их все заполнять, поэтому нажимаем &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;a&lt;/span&gt;&lt;/tt&gt;, получаем:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="autoinsert" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sud2.png" style="width: 1080px; height: 710px;" /&gt;&lt;/div&gt;&lt;p&gt;Теперь действительно сложная задача, но сразу видно интересность значения 4, поэтому берём карандаш&lt;a class="footnote-reference" href="#id4" id="id2" name="id2"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; &amp;mdash; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;p&lt;/span&gt;&lt;/tt&gt; (от pencil) и применяем технику &lt;a class="reference" href="http://www.sadmansoftware.com/sudoku/nishio.htm"&gt;Nishio&lt;/a&gt; начиная с R8C9, получаем:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="pencil" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sud3.png" style="width: 1080px; height: 710px;" /&gt;&lt;/div&gt;&lt;ol class="arabic simple"&gt;&lt;li&gt;R8C9 -&amp;gt; 4 (начало &lt;a class="reference" href="http://www.sadmansoftware.com/sudoku/nishio.htm"&gt;Nishio&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;R2C3 -&amp;gt; 4 (единственное место в C3 где может быть 4)&lt;/li&gt;&lt;li&gt;R3C7 -&amp;gt; 4 (единственное место в R1 где может быть 4)&lt;/li&gt;&lt;li&gt;в восьмом квадрате некуда ставить 4&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;то есть в R8C9 не может стоять 4.  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-u&lt;/span&gt; &lt;span class="pre"&gt;p&lt;/span&gt;&lt;/tt&gt; и отменяем карандаш. Теперь мы знаем, что 4 стоит в R2C9:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="won" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sud4.png" style="width: 1080px; height: 710px;" /&gt;&lt;/div&gt;&lt;p&gt;Хорошая судочка, пожалуй сыну подойдёт, распечатаем её нажав &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/tt&gt;, на бумаге это выглядит вот так:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="printed" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sud5.png" style="width: 640px; height: 716px;" /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id3" name="id3"&gt;Скачать&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Скачать можно с &lt;a class="reference" href="http://lgarc.narod.ru/xemacs/sudoku.el"&gt;http://lgarc.narod.ru/xemacs/sudoku.el&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Замечания, баги, фиксы присылайте на &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;lg&lt;/span&gt; &lt;span class="pre"&gt;AT&lt;/span&gt; &lt;span class="pre"&gt;sxemacs.org&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;&lt;hr class="docutils" /&gt;&lt;div class="docutils footnote" id="id4"&gt;&lt;span class="label"&gt;&lt;a class="fn-backref" href="#id2" name="id4"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;В режиме карандаша авто-заполнение отключается&lt;/div&gt;&lt;/div&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/sudoku.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-4253756778654542572?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/4253756778654542572/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=4253756778654542572' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/4253756778654542572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/4253756778654542572'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2009/11/sxemacs.html' title='Судоку для (S)XEmacs'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-3786846225340386947</id><published>2009-09-30T13:53:00.002+04:00</published><updated>2009-09-30T13:59:54.277+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='macos'/><title type='text'>Говорящий SXEmacs</title><content type='html'>&lt;p class="fl"&gt;Баловался тут давеча с разными способами более тесной интеграции SXEmacs с Mac &lt;acronym title="Operating System"&gt;OS&lt;/acronym&gt;.  Сделал (а точнее стащил из GNU Emacs) интересную функцию, с помощью которой можно запускать различные сценарии &lt;a class="reference" href="http://developer.apple.com/applescript/"&gt;AppleScript&lt;/a&gt;:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;defun&lt;/span&gt; &lt;span style="color: #000000"&gt;do-applescript&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;&amp;amp;rest&lt;/span&gt; &lt;span style="color: #000000"&gt;script-lines&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;let&lt;/span&gt; &lt;span style="color: #696969"&gt;((&lt;/span&gt;&lt;span style="color: #000000"&gt;script&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;mapconcat&lt;/span&gt; &lt;span style="color: #CD0000"&gt;&amp;#39;identity&lt;/span&gt; &lt;span style="color: #000000"&gt;script-lines&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
        &lt;span style="color: #000000"&gt;start&lt;/span&gt; &lt;span style="color: #000000"&gt;cmd&lt;/span&gt; &lt;span style="color: #8B4513"&gt;return&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;while&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;string-match&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt; &lt;span style="color: #000000"&gt;script&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
      &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;setq&lt;/span&gt; &lt;span style="color: #000000"&gt;script&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;replace-match&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\r&amp;quot;&lt;/span&gt; &lt;span style="color: #880000"&gt;t&lt;/span&gt; &lt;span style="color: #880000"&gt;t&lt;/span&gt; &lt;span style="color: #000000"&gt;script&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;while&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;string-match&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #000000"&gt;script&lt;/span&gt; &lt;span style="color: #000000"&gt;start&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
      &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;setq&lt;/span&gt; &lt;span style="color: #000000"&gt;start&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;+&lt;/span&gt; &lt;span style="color: #000000"&gt;2&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;match-beginning&lt;/span&gt; &lt;span style="color: #000000"&gt;0&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
            &lt;span style="color: #000000"&gt;script&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;replace-match&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\\\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #880000"&gt;t&lt;/span&gt; &lt;span style="color: #880000"&gt;t&lt;/span&gt; &lt;span style="color: #000000"&gt;script&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;setq&lt;/span&gt; &lt;span style="color: #000000"&gt;cmd&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;concat&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;osascript -e \&amp;quot;\&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #000000"&gt;script&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\&amp;quot;\&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;setq&lt;/span&gt; &lt;span style="color: #8B4513"&gt;return&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;shell-command-to-string&lt;/span&gt; &lt;span style="color: #000000"&gt;cmd&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;concat&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #8B4513"&gt;return&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Применения этой процедуры очевидны.  Например можно заставить &lt;a class="reference" href="http://www.growl.info"&gt;Growl&lt;/a&gt; отображать сообщения SXEmacs:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;defun&lt;/span&gt; &lt;span style="color: #000000"&gt;growl&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;title&lt;/span&gt; &lt;span style="color: #000000"&gt;message&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;do-applescript&lt;/span&gt;
   &lt;span style="color: #008B00"&gt;&amp;quot;tell application \&amp;quot;GrowlHelperApp\&amp;quot;&amp;quot;&lt;/span&gt;
   &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;format&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;notify with name \&amp;quot;SXEmacs Notification\&amp;quot; title %S description %S application name \&amp;quot;SXEmacs\&amp;quot; image from location \&amp;quot;file:///opt/local/share/sxemacs-22.1.10/etc/sxemacs-icon.png\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #000000"&gt;title&lt;/span&gt; &lt;span style="color: #000000"&gt;message&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
   &lt;span style="color: #008B00"&gt;&amp;quot;end tell&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Но, что более интересно, можно научить SXEmacs разговаривать, используя &lt;a class="reference" href="http://www.apple.com/accessibility/voiceover/"&gt;VoiceOver&lt;/a&gt;!&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;defvar&lt;/span&gt; &lt;span style="color: #000000"&gt;lg-say-voices&lt;/span&gt;
  &lt;span style="color: #666666"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color: #696969"&gt;((&lt;/span&gt;&lt;span style="color: #000000"&gt;agnes&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Agnes&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;albert&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Albert&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;alex&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Alex&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;badnews&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;BadNews&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;bahh&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Bahh&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;bells&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Bells&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;boing&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Boing&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;bruce&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Bruce&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;bubbles&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Bubbles&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;cellos&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Cellos&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;deranged&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Deranged&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;fred&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Fred&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;goodnews&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;GoodNews&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;hysterical&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Hysterical&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;junior&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Junior&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;kathy&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Kathy&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;organ&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Organ&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;princess&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Princess&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;ralph&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Ralph&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;trinoids&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Trinoids&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;vicki&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Vicki&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;victoria&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Victoria&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;whisper&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Whisper&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;zarvox&lt;/span&gt; &lt;span style="color: #666666"&gt;.&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Zarvox&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;

&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;defun&lt;/span&gt; &lt;span style="color: #000000"&gt;lg-say-the-text&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;text&lt;/span&gt; &lt;span style="color: #4682B4"&gt;&amp;amp;optional&lt;/span&gt; &lt;span style="color: #000000"&gt;voice&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;let*&lt;/span&gt; &lt;span style="color: #696969"&gt;((&lt;/span&gt;&lt;span style="color: #000000"&gt;sv&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;cdr&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;assq&lt;/span&gt; &lt;span style="color: #000000"&gt;voice&lt;/span&gt; &lt;span style="color: #000000"&gt;lg-say-voices&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;
         &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;svoice&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;if&lt;/span&gt; &lt;span style="color: #000000"&gt;sv&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;format&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot; using %S&amp;quot;&lt;/span&gt; &lt;span style="color: #000000"&gt;sv&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
         &lt;span style="color: #00008b; font-style: italic"&gt;;; &amp;quot; -&amp;gt; &amp;#39; in order to avoid osascript confusion&lt;/span&gt;
         &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;nt&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;replace-in-string&lt;/span&gt; &lt;span style="color: #000000"&gt;text&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;&amp;#39;&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;do-applescript&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;format&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;say %S%s&amp;quot;&lt;/span&gt; &lt;span style="color: #000000"&gt;nt&lt;/span&gt; &lt;span style="color: #000000"&gt;svoice&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;growl&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Text via VoiceOver&amp;quot;&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Done!&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;

&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;defun&lt;/span&gt; &lt;span style="color: #000000"&gt;lg-say-region-or-buffer&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;arg&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
  &lt;span style="color: #008B00"&gt;&amp;quot;Say contents of the buffer or region.&lt;/span&gt;
&lt;span style="color: #008B00"&gt;If prefix ARG is specified then use custom voice.&amp;quot;&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;interactive&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;let&lt;/span&gt; &lt;span style="color: #696969"&gt;((&lt;/span&gt;&lt;span style="color: #000000"&gt;voice&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;and&lt;/span&gt; &lt;span style="color: #000000"&gt;current-prefix-arg&lt;/span&gt;
                    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;intern&lt;/span&gt;
                     &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;completing-read&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;Voice: &amp;quot;&lt;/span&gt;
                      &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;mapcar&lt;/span&gt; &lt;span style="color: #8B4513"&gt;#&amp;#39;&lt;/span&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;lambda&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;v&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
                                  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;list&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;symbol-name&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;car&lt;/span&gt; &lt;span style="color: #000000"&gt;v&lt;/span&gt;&lt;span style="color: #696969"&gt;))))&lt;/span&gt;
                              &lt;span style="color: #000000"&gt;lg-say-voices&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
                      &lt;span style="color: #880000"&gt;nil&lt;/span&gt; &lt;span style="color: #880000"&gt;t&lt;/span&gt;&lt;span style="color: #696969"&gt;))))&lt;/span&gt;
        &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;text&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;if&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;region-active-p&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
                  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;buffer-substring&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;region-beginning&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;region-end&lt;/span&gt;&lt;span style="color: #696969"&gt;))&lt;/span&gt;
                &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;buffer-substring&lt;/span&gt;&lt;span style="color: #696969"&gt;))))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;lg-say-the-text&lt;/span&gt; &lt;span style="color: #000000"&gt;text&lt;/span&gt; &lt;span style="color: #000000"&gt;voice&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;

&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;define-key&lt;/span&gt; &lt;span style="color: #000000"&gt;global-map&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;kbd&lt;/span&gt; &lt;span style="color: #008B00"&gt;&amp;quot;C-c s&amp;quot;&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #CD0000"&gt;&amp;#39;lg-say-region-or-buffer&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Далее, можно например реализовать процедуру, которая будет читать тело письма в gnus:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #8B4513"&gt;defun&lt;/span&gt; &lt;span style="color: #000000"&gt;lg-gnus-say-article-body&lt;/span&gt; &lt;span style="color: #696969"&gt;()&lt;/span&gt;
  &lt;span style="color: #008B00"&gt;&amp;quot;Say body of the current gnus article.&amp;quot;&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;interactive&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #4682B4"&gt;let&lt;/span&gt; &lt;span style="color: #696969"&gt;((&lt;/span&gt;&lt;span style="color: #000000"&gt;atxt&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;with-current-buffer&lt;/span&gt; &lt;span style="color: #000000"&gt;gnus-article-buffer&lt;/span&gt;
                &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;save-restriction&lt;/span&gt;
                  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;article-goto-body&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt;
                  &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;buffer-substring&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;point&lt;/span&gt;&lt;span style="color: #696969"&gt;)&lt;/span&gt; &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;point-max&lt;/span&gt;&lt;span style="color: #696969"&gt;))))))&lt;/span&gt;
    &lt;span style="color: #696969"&gt;(&lt;/span&gt;&lt;span style="color: #000000"&gt;lg-say-the-text&lt;/span&gt; &lt;span style="color: #000000"&gt;atxt&lt;/span&gt;&lt;span style="color: #696969"&gt;)))&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Единственная проблема с данной реализацией это то, что SXEmacs блокирует во время выполнения сценария &lt;a class="reference" href="http://developer.apple.com/applescript/"&gt;AppleScript&lt;/a&gt;.  Нужно расширить процедуру &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;do-applescript&lt;/span&gt;&lt;/tt&gt;, чтобы она поддерживала параметр &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;IN-BACKGROUND&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/speaking-sxemacs.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-3786846225340386947?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/3786846225340386947/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=3786846225340386947' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/3786846225340386947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/3786846225340386947'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2009/09/sxemacs.html' title='Говорящий SXEmacs'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-7735097670273282544</id><published>2009-08-08T01:29:00.004+04:00</published><updated>2009-08-08T01:41:53.212+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='macos'/><title type='text'>MacOS clipboarding</title><content type='html'>&lt;!-- Copyright (C) 2009 Zajcev Evgeny --&gt;&lt;p class="fl"&gt;В Mac &lt;acronym title="Operating System"&gt;OS&lt;/acronym&gt; есть отличное приложение &amp;mdash; X11.app.  Реальный и работающий X сервер.  Оно позволило при переходе с FreeBSD на MacOS практически не менять среду разработки и использовать привычные, старые добрые X приложения, такие как &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;xterm&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Inkscape&lt;/span&gt;&lt;/tt&gt; или &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SXEmacs&lt;/span&gt;&lt;/tt&gt;. Единственный минус это отсутствие внятного межклипбордного взаимодействия между Cocoa приложениями и X приложениями, особенно бесило, что я не могу выделить что-то в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SXEmacs&lt;/span&gt;&lt;/tt&gt; и вставить в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Firefox&lt;/span&gt;&lt;/tt&gt;.  Давеча нашёл способ как это можно сделать:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;system-type&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;darwin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;;; Make C-w, M-y interact with Mac OS X clipboard&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;lg-paste-from-osx&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell-command-to-string&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;pbpaste&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;lg-paste-to-osx&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;text&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nb"&gt;push&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;process-connection-type&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;start-process&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;pbcopy&amp;quot;&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;pbcopy&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;process-send-string&lt;/span&gt; &lt;span class="nv"&gt;proc&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;process-send-eof&lt;/span&gt; &lt;span class="nv"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;interprogram-paste-function&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;lg-paste-from-osx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;interprogram-cut-function&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;lg-paste-to-osx&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Теперь, после &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-w&lt;/span&gt;&lt;/tt&gt; или &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;M-w&lt;/span&gt;&lt;/tt&gt; в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SXEmacs&lt;/span&gt;&lt;/tt&gt;, я могу делать &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-v&lt;/span&gt;&lt;/tt&gt; в Cocoa приложениях, а выделив что-то в Cocoa приложениях и скопировав, я могу вставлять в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;SXEmacs&lt;/span&gt;&lt;/tt&gt; с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-y&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/macos-clipboard.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-7735097670273282544?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/7735097670273282544/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=7735097670273282544' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/7735097670273282544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/7735097670273282544'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2009/08/macos-clipboarding.html' title='MacOS clipboarding'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-841839359412934897</id><published>2008-12-29T20:50:00.001+03:00</published><updated>2008-12-29T20:55:38.038+03:00</updated><title type='text'>SXEmacs - behind the scene</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: sxemacs-behind-the-scene.rest,v 1.1 2008/12/29 17:48:45 lg Exp $ --&gt; &lt;p class="fl"&gt;Как и обещал приоткрою немного занавес SXEmacs и расскажу, а точнее покажу, как устроена модель разработки SXEmacs.  Но сначала про разработчиков:&lt;/p&gt;&lt;dl class="docutils"&gt;&lt;dt&gt;hroptatyr (aka Sebastian Freundt)&lt;/dt&gt; &lt;dd&gt;Немец, живёт в Берлине, математик, занимается разработкой систем компьютерной алгебры, зарабатывает на жизнь игрой на бирже, любит мощные компьютеры и большие мониторы, носит очки&lt;/dd&gt; &lt;dt&gt;lg (aka Zajcev Evgeny)&lt;/dt&gt; &lt;dd&gt;Гимнаст, работал охранником 6 лет, хорошо владеет рукопашным боем, неплохо обращается с холодным оружием и отлично стреляет.  Живёт в лесистой части г. Ульяновск, любит работать в туалете, выпивать, читать книжки и детей&lt;/dd&gt; &lt;dt&gt;njsf (aka Nelson Ferreira)&lt;/dt&gt; &lt;dd&gt;Живёт в Америке, любит фотографировать и путешествовать, есть красивая подружка, имеет хорошее чувство юмора.&lt;/dd&gt; &lt;dt&gt;PeanutHorst&lt;/dt&gt; &lt;dd&gt;Не совсем разработчик, а скорее противовес в команде SXEmacs, пессимистичен, работает в OpenBox под FreeBSD, часто несёт глупости, тестирует SXEmacs на различных платформах.&lt;/dd&gt; &lt;dt&gt;JackaLX (aka Steve Youngs)&lt;/dt&gt; &lt;dd&gt;Создал SXEmacs, домохозяин, имеет кучку детей, держит магазин, торгующий шмотками и вещами с символикой SXEmacs, ждёт когда кто-нибудь переведёт первый доллар в качестве денежного пожертвования на развитие SXEmacs, есть красавица жена Мишель с большой грудью, которая зарабатывает на жизнь семье&lt;/dd&gt; &lt;/dl&gt; &lt;p&gt;Это список активных разработчиков на текущий момент, так что он не совсем полный, но для понимания поднаготщины &amp;mdash; хватит.&lt;/p&gt;&lt;p&gt;Итак, скачайте эту &lt;a class="reference" href="http://lgarc.narod.ru/sxemacsen/img/se1.png"&gt;картинку&lt;/a&gt; и откройте её в просмоторщике в полном формате, т.е. без использования &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;fill-to-width&lt;/span&gt;&lt;/tt&gt; или схожих функций.&lt;/p&gt;&lt;p&gt;Те кому интересны все детали можете скачать &lt;a class="reference" href="http://lgarc.narod.ru/sxemacsen/img/se.svg"&gt;SVG исходник&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/sxemacs-behind-the-scene.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-841839359412934897?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/841839359412934897/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=841839359412934897' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/841839359412934897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/841839359412934897'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/sxemacs-behind-scene_29.html' title='SXEmacs - behind the scene'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-2690046786991217652</id><published>2008-12-23T15:37:00.001+03:00</published><updated>2008-12-23T17:35:45.071+03:00</updated><title type='text'>Условия гонки в ASYNEQ</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: race-condition-in-asyneq.rest,v 1.4 2008/12/23 12:36:26 lg Exp $ --&gt; &lt;p class="fl"&gt;Давайте для начала я покажу вам скриншот моего SXEmacs:&lt;/p&gt;&lt;div align="center" class="align-center"&gt;&lt;img alt="Скриншот" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sxemacs-lg-asyneq.png" style="width: 950px; height: 600px;" /&gt;&lt;/div&gt; &lt;p&gt;Ничего необычного не замечаете?  У меня почти невидимые клеточки. Цвет &lt;span style="color: #C4C4C4"&gt;#C4C4C4&lt;/span&gt; на фоне &lt;span style="color: #CCCCCC"&gt;#CCCCCC&lt;/span&gt; да ещё с моим дальтонизмом &amp;mdash; я их действительно &lt;span style="background: #CCCCCC; color: #C4C4C4"&gt;еле вижу&lt;/span&gt;, главное что я знаю, что они там есть и если приглядеться, то я их отчётливо вижу.  Особо внимательные заметят, что в каждую клеточку помещается 4 символа по горизонтали и 2 по вертикали.&lt;/p&gt;&lt;p&gt;Теперь немного утомительной истории.  Путём наблюдений и экспериментов я пришёл к выводу, что у меня есть некая особенность &amp;mdash; проблемы лучше решаются, если во время размышлений вести записи на листочке в клеточку.  Первый раз я это заметил решая просто гигантское количество задач по планиметрии в 8 классе.  В дальнейшем доходило даже до маразма; для того, чтобы решить одну задачу на вступительных экзаменах в МГУ мне пришлось разлиновать в клеточку выданный листочек.  Я всё не мог понять с чем это связано, и вот, когда начал использовать XEmacs в году '97-98, то понял.  Как сейчас помню, сидел набирал текст какой-то программы и возникло острое ощущение, что буквы, которые я так старательно набираю, сейчас разбегутся, а вместе с этими буквами разбегутся и вкладываемые мысли.  Тогда то я и понял, что хорошие мысли порождаются &lt;em&gt;свободным&lt;/em&gt; разумом, но истинно свободный разум также легко теряет мысли как и порождает их, для разума-рабочей лошадки, нужна &amp;laquo;клетка&amp;raquo;.  Вот такая вот психология.&lt;/p&gt;&lt;p&gt;Со временем, поэкспериментировав с цветом и размером клеток в окнах (S)XEmacs я нашёл оптимальный (дающий наибольшую продуктивность) для себя вариант &amp;mdash; тот, что на картинке.&lt;/p&gt;&lt;p&gt;И вот представьте, сижу я как обычно печатаю текст, пытаясь вложить в него хоть немного смысла, как вдруг, буквы, в прямом смысле этого слова, начинают убегать и смешиваться друг с другом.  Всё думаю, доигрался, колёсики уехали.  Как ни странно, но первая мысль была именно, что проблемы у меня, а не у SXEmacs.  Немного успокоившись задался вопросом почему так произошло, ведь раньше такого не было. Нашёл особенность &amp;mdash; использовался &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flyspell&lt;/span&gt;&lt;/tt&gt; режим, который обычно выключен.  Покопавшись в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flyspell&lt;/span&gt;&lt;/tt&gt; нашёл особенность, что &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;self-insert&lt;/span&gt;&lt;/tt&gt; команда может породить вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;accept-process-output&lt;/span&gt;&lt;/tt&gt;.  Дальнейшее разбирательство привело к ASYNEQ.  А текст так и не написал :(&lt;/p&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/race-condition-in-asyneq.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;p class="fl"&gt;&lt;strong&gt;UPD:&lt;/strong&gt; Код для сетки&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;defface&lt;/span&gt; &lt;span class="nv"&gt;lg-grido-face&lt;/span&gt;
  &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;((((&lt;/span&gt;&lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;background&lt;/span&gt; &lt;span class="nv"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:foreground&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;gray10&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="nv"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;background&lt;/span&gt; &lt;span class="nv"&gt;light&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:foreground&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;gray77&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:foreground&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;gray77&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="s"&gt;&amp;quot;Face for grid.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;push&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;grido&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;face-foreground&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;lg-grido-face&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nv"&gt;xpm-color-symbols&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;defconst&lt;/span&gt; &lt;span class="nv"&gt;lg-square-64x64-xpm&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;concat&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;/* XPM */\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;static char *mini_square_xpm[] = {\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;/* columns rows colors chars-per-pixel */\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;64 64 2 1\&amp;quot;,\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;       c None s background\&amp;quot;,\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;.      c gray77 s grido\&amp;quot;,\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;/* pixels */&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;................................................................\&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n,&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;\&amp;quot;    .                                                           \&amp;quot;\n&amp;quot;&lt;/span&gt;
   &lt;span class="s"&gt;&amp;quot;};&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;set-face-background-pixmap&lt;/span&gt;
 &lt;span class="ss"&gt;&amp;#39;default&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-image-specifier&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;vector&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;xpm&lt;/span&gt; &lt;span class="ss"&gt;:data&lt;/span&gt; &lt;span class="nv"&gt;lg-square-64x64-xpm&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-2690046786991217652?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/2690046786991217652/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=2690046786991217652' title='Комментарии: 9'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/2690046786991217652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/2690046786991217652'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/asyneq.html' title='Условия гонки в ASYNEQ'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-5875738651943684642</id><published>2008-12-22T14:54:00.002+03:00</published><updated>2008-12-22T16:09:17.814+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internals'/><category scheme='http://www.blogger.com/atom/ns#' term='bsoy'/><title type='text'>SXEmacs - лучший программный продукт года</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: sxemacs-best-software.rest,v 1.6 2008/12/22 11:53:12 lg Exp $ --&gt; &lt;p class="fl"&gt;Решил немного помечтать и вообразить, что нужно SXEmacs, чтобы выиграть приз &amp;laquo;Лучший программный продукт года&amp;raquo;.  Было ли вообще такое, чтобы GNU Emacs выигрывал этот приз?  Что же необходимо изменить и сделать в SXEmacs, чтобы это событие произошло?&lt;/p&gt;&lt;ul class="simple"&gt;&lt;li&gt;Кардинально улучшить подсистему обработки событий (event loop).&lt;/li&gt; &lt;li&gt;Реализовать подсистему отображения (redisplay) используя современные средства, например &lt;a class="reference" href="http://www.cairographics.org"&gt;Cairo&lt;/a&gt;.  Использовать современные библиотеки виджетов, например GTK+.&lt;/li&gt; &lt;li&gt;Реализовать &lt;em&gt;нормальную&lt;/em&gt; мультиязыковую поддержку.&lt;/li&gt; &lt;li&gt;Поймать все утечки памяти при использовании &lt;a class="reference" href="http://www.hpl.hp.com/personal/Hans_Boehm/gc/"&gt;BDWGC&lt;/a&gt; и сделать его сборщиком мусора по умолчанию.&lt;/li&gt; &lt;li&gt;Реализовать чистую интеграцию различных &lt;acronym title="Язык Программирования"&gt;ЯП&lt;/acronym&gt;, таких как &lt;a class="reference" href="http://python.org"&gt;Python&lt;/a&gt;, &lt;a class="reference" href="http://ruby-lang.org"&gt;Ruby&lt;/a&gt; и др.&lt;/li&gt; &lt;li&gt;Улучшить документацию как для разработчиков так и для пользователей.&lt;/li&gt; &lt;li&gt;Создать более продвинутый и быстрый сопоставитель текста с образцом на замену регулярных выражений.  На базе него сделать, чтобы &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;font-lock&lt;/span&gt;&lt;/tt&gt; работал корректно и быстро.&lt;/li&gt; &lt;li&gt;Создать систему совместной разработки на базе SXEmacs.&lt;/li&gt; &lt;/ul&gt;&lt;div class="admonition-info right width50 admonition"&gt;&lt;p class="first admonition-title"&gt;info&lt;/p&gt; &lt;p class="last"&gt;Призываю читателей к дискуссии.  Опишите свой взгляд, расскажите каким вы хотели бы видеть ([S]X)Emacs.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Подробное изложение каждой части этого плана я буду публиковать отдельными постами (не обязательно в правильном порядке).  Потом их можно будет склеить в одну статейку и оформить как некий путь развития SXEmacs.  Сегодня будет небольшой обзор &lt;a class="reference" href="#id2"&gt;подсистемы событий&lt;/a&gt;.&lt;/p&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id2" name="id2"&gt;Подсистема событий&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Самое удивительное, что сейчас вообще нет этой подсистемы ;).  Есть определённые части, выполняющие необходимые действия, но отсутствует целостность, расширяемость и сила.  В существующей &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt; есть только высокий уровень доступа, нет разделения &lt;acronym title="Application Programming Interface"&gt;API&lt;/acronym&gt; на низкий/высокий уровни, поэтому если требуется что-то добавить, то необходимо делать много низкоуровневой мишуры, с помощью &lt;a class="reference" href="http://en.wikipedia.org/wiki/Copy_and_paste_programming"&gt;копи&amp;amp;паст программирования&lt;/a&gt; &amp;mdash; утомительно.&lt;/p&gt;&lt;p&gt;В SXEmacs было решено использовать &lt;a class="reference" href="http://software.schmorp.de/pkg/libev.html"&gt;libev&lt;/a&gt; как низкоуровневую базу для &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt;.  Выбор стоял между &lt;a class="reference" href="http://liboop.ofb.net"&gt;liboop&lt;/a&gt;, &lt;a class="reference" href="http://monkey.org/~provos/libevent/"&gt;libevent&lt;/a&gt;, &lt;a class="reference" href="http://software.schmorp.de/pkg/libev.html"&gt;libev&lt;/a&gt; и одной проприетарной библиотекой, которую планировалось перелицензировать (уже было получено согласие правообладателя).  &lt;a class="reference" href="http://liboop.ofb.net"&gt;liboop&lt;/a&gt; отпала первой &amp;mdash; библиотека практически мертва.  &lt;a class="reference" href="http://monkey.org/~provos/libevent/"&gt;libevent&lt;/a&gt; является почти de-facto стандартом для создания софта с &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt;, но у нескольких разработчиков SXEmacs был негативный (как и позитивный тоже) опыт использования &lt;a class="reference" href="http://monkey.org/~provos/libevent/"&gt;libevent&lt;/a&gt; и как раз ограничения, которые существуют в ней плюс просто &lt;a class="reference" href="http://libev.schmorp.de/bench.html"&gt;ошеломляющие результаты тестирования скорости&lt;/a&gt; libev в сравнении с libevent не позволили выбрать libevent.  Проприетарная библиотека отпала так как она зависела от дополнительной большой библиотеки, а так же в ней не очень удобный &lt;acronym title="Application Programming Interface"&gt;API&lt;/acronym&gt; (хотя, видимо, очень мощный) и отсутствовала документация.&lt;/p&gt;&lt;p&gt;Так зачем вообще всё это нужно?  А для того, чтобы &lt;strong&gt;полностью&lt;/strong&gt; избавиться от внутренних блокировок в SXEmacs.  Блокировки бывают двух типов:&lt;/p&gt;&lt;ol class="arabic simple"&gt;&lt;li&gt;Выполнение elisp кода приостанавливается в ожидании какого-то события.&lt;/li&gt; &lt;li&gt;Блокирует сам вызов библиотечной функции.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;К пункту 2 относятся вызовы для разрешения DNS имён, такие как &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gethostbyname(3)&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;getaddrinfo(3)&lt;/span&gt;&lt;/tt&gt;, вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;connect(2)&lt;/span&gt;&lt;/tt&gt;, а также, как это не удивительно, вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write(2)&lt;/span&gt;&lt;/tt&gt;.  В GNU Emacs реализован неблокирующий вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;connect&lt;/span&gt;&lt;/tt&gt; если передано ключевое слово &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;:nowait&lt;/span&gt;&lt;/tt&gt;&lt;a class="footnote-reference" href="#id10" id="id3" name="id3"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; в процедуру &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;make-network-process&lt;/span&gt;&lt;/tt&gt;, при этом вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;make-network-process&lt;/span&gt;&lt;/tt&gt; всё же может заблокировать, если заблокировало разыменование имени хоста.  В SXEmacs вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;connect&lt;/span&gt;&lt;/tt&gt; всегда блокирует, поэтому &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open-network-stream&lt;/span&gt;&lt;/tt&gt; всегда блокирует. Что касается &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write(2)&lt;/span&gt;&lt;/tt&gt;, то по настоящему всё же &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write&lt;/span&gt;&lt;/tt&gt; не блокирует, ибо дескриптор был переведён в неблокирующий режим для неблокирующего чтения, но все Емаксы, получая &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;EWOULDBLOCK&lt;/span&gt;&lt;/tt&gt; от &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write(2)&lt;/span&gt;&lt;/tt&gt;, делают &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;select&lt;/span&gt;&lt;/tt&gt; в ожидании, когда разрешат записать.&lt;/p&gt;&lt;p&gt;К пункту 1 относятся любые вызовы &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;accept-process-output&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;call-process&lt;/span&gt;&lt;/tt&gt;.  Что произойдёт если &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;accept-process-output&lt;/span&gt;&lt;/tt&gt; ожидает данных и в этот момент приходит какое-нибудь событие?  Если событие &lt;em&gt;системное&lt;/em&gt;, то оно обрабатывается немедленно, если событие &lt;em&gt;специальное&lt;/em&gt; или &lt;em&gt;командное&lt;/em&gt;&lt;a class="footnote-reference" href="#id11" id="id4" name="id4"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;, то оно будет отложено и записано в очередь событий, которые будут обработаны позже.&lt;/p&gt;&lt;div class="section"&gt;&lt;h3&gt;&lt;a id="id5" name="id5"&gt;Асинхронный обработчик событий&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;В SXEmacs есть такая вещь называется ASYNEQ &amp;mdash; это возможность асинхронной обработки событий.  Не всякое событие может быть обработано асинхронно.  В общем случае асинхронная обработка командных событий ведёт к условиям гонки (race condition)&lt;a class="footnote-reference" href="#id12" id="id6" name="id6"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;.  Специальные же события без проблем можно обрабатывать асинхронно.  Именно по этой причине &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;xlib&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;xwem&lt;/span&gt;&lt;/tt&gt; работают более предсказуемо под SXEmacs, ибо они порождают просто тонны специальных событий, которые в XEmacs обрабатываются синхронно как и командные.&lt;/p&gt;&lt;p&gt;Часто командные события всё же можно обрабатывать асинхронно.  Условия гонки были обнаружены токмо спустя год после того как в SXEmacs появился ASYNEQ.  Это говорит о том, что условия гонки крайне редки и сильно зависят от специфики elisp кода, то есть автоматически невозможно определить возникнет ли в конкретном случае race condition или нет.  Возможно, необходимо определить переменную &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;asyneq-ignore-command-events&lt;/span&gt;&lt;/tt&gt;, которую можно связать со значением &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;t&lt;/span&gt;&lt;/tt&gt; в особых случаях, когда необходимо запретить асинхронную обработку командных событий.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id7" name="id7"&gt;Как организовать новую ПС&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Что мы хотим от новой &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt;:&lt;/p&gt;&lt;ul class="simple"&gt;&lt;li&gt;Целостность &amp;mdash; одно место обработки событий, отсутствие костылей на вроде как при потенциальном блокировании &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write&lt;/span&gt;&lt;/tt&gt; в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;process-send-string&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt; &lt;li&gt;Простой и мощный &lt;acronym title="Application Programming Interface"&gt;API&lt;/acronym&gt; как с низкоуровневыми, так и с высокоуровневыми конструкциями&lt;/li&gt; &lt;li&gt;Возможность интеграции других подсистем событий в &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt; SXEmacs.  Для начала X11 и Glib&lt;/li&gt; &lt;/ul&gt;&lt;div align="center" class="right figure"&gt;&lt;img alt="Схема ПС" src="http://lgarc.narod.ru/sxemacsen/img/sxemacs-event-loop.png" style="width: 400px; height: 276px;" /&gt; &lt;p class="caption"&gt;&lt;strong&gt;Сх. 1.&lt;/strong&gt; пример работы ПС SXEmacs (&lt;a class="reference" href="http://lgarc.narod.ru/sxemacsen/img/sxemacs-event-loop.svg"&gt;event-loop.svg&lt;/a&gt;)&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Использовать новую &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt; будут:&lt;/p&gt;&lt;ul class="simple"&gt;&lt;li&gt;На низком уровне&lt;ul&gt;&lt;li&gt;Асинхронное разыменование DNS&lt;/li&gt; &lt;li&gt;Остальные потенциально блокирующие вызовы&lt;/li&gt; &lt;li&gt;Клей для других &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt;&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;li&gt;На высоком уровне&lt;ul&gt;&lt;li&gt;Event &lt;acronym title="Application Programming Interface"&gt;API&lt;/acronym&gt; на elisp уровне&lt;/li&gt; &lt;li&gt;Таймеры&lt;/li&gt; &lt;li&gt;Прогнозируемые предикаты&lt;/li&gt; &lt;li&gt;И т.д.&lt;/li&gt; &lt;/ul&gt;&lt;/li&gt; &lt;/ul&gt;&lt;p&gt;Попробую изобразить в виде схемы, что будет происходить при возникновении командного события, которое порождает вызов &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open-network-stream&lt;/span&gt;&lt;/tt&gt;.  Как видим, событие помещается в очередь событий и когда до него дойдёт очередь, оно будет обработано, что породит вызов процедуры &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open-network-stream&lt;/span&gt;&lt;/tt&gt;, которой, в свою очередь, необходимо разыменовать имя хоста и подсоединиться к нему, т.е. произвести две потенциально блокирующих операции.  За время выполнения &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;open-network-stream&lt;/span&gt;&lt;/tt&gt; мы два раза посетим обработчик событий и в случае, если нам действительно нужно будет ждать, мы сможем обработать ещё кучу событий из очереди.&lt;/p&gt;&lt;p&gt;Именно так я и вижу работу новой &lt;acronym title="Подсистема Событий"&gt;ПС&lt;/acronym&gt; в SXEmacs.&lt;/p&gt;&lt;hr class="docutils" /&gt;&lt;div class="docutils footnote" id="id10"&gt;&lt;span class="label"&gt;&lt;a class="fn-backref" href="#id3" name="id10"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;Вроде &lt;acronym title="Richard M. Stallman"&gt;RMS&lt;/acronym&gt; был ярым противником ключевых слов&lt;/div&gt;&lt;div class="docutils footnote" id="id11"&gt;&lt;span class="label"&gt;&lt;a class="fn-backref" href="#id4" name="id11"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;Командные события порождаются действиями пользователя (нажал кнопку, мышкой побаловался и т.д.)&lt;/div&gt;&lt;div class="docutils footnote" id="id12"&gt;&lt;span class="label"&gt;&lt;a class="fn-backref" href="#id6" name="id12"&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;Не буду описывать подробности, но, поверьте мне, я думал что помешался когда наблюдал эти условия гонки при работе с &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;flyspell&lt;/span&gt;&lt;/tt&gt;.  Впрочем, психологическую составляющую этого опыта можно вынести отдельным постом, будет интересно&lt;/div&gt;&lt;/div&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/sxemacs-best-software.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-5875738651943684642?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/5875738651943684642/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=5875738651943684642' title='Комментарии: 4'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5875738651943684642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5875738651943684642'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/sxemacs_22.html' title='SXEmacs - лучший программный продукт года'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-2610521458011245978</id><published>2008-12-22T13:55:00.000+03:00</published><updated>2008-12-22T14:01:22.625+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='internals'/><title type='text'>Расширение REPL</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: user-readers.rest,v 1.4 2008/12/18 01:04:10 lg Exp $ --&gt; &lt;p class="fl"&gt;Возникла тут идея реализовать возможность расширения возможностей &lt;acronym title="Read-Eval-Print Loop"&gt;REPL&lt;/acronym&gt; в SXEmacs, а особенно его Read части.  Но сначала про Print часть.&lt;/p&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id1" name="id1"&gt;Пользовательская печать&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;В XEmacs уже давно были предпосылки к созданию пользовательской печати elisp-объектов.  Так, например, при задании структуры с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;defstruct&lt;/span&gt;&lt;/tt&gt; можно было указать &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;:print-function&lt;/span&gt;&lt;/tt&gt; &amp;mdash; процедуру, которая осуществляет печать объекта данной структуры.  Уже давно существовала магическая переменная &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;custom-print-functions&lt;/span&gt;&lt;/tt&gt; со следующим напутствием:&lt;/p&gt;&lt;blockquote class="citation"&gt;&lt;p&gt;This variable is not used at present, but it is defined in hopes that a future Emacs interpreter will be able to use it.&lt;a class="footnote-reference" href="#id4" id="id2" name="id2"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class="attribution"&gt;&amp;mdash;custom-print-functions (cl.el)&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;В SXEmacs это напутствие было выполнено и появилась возможность пользовательской печати.  Это моментально решило проблему печати сложно-рекурсивных структур, которая до этого решалась с помощью изменения переменных &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;print-level&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;print-length&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;Уже существуют пакеты, которые используют возможность пользовательской печати.  Использовать эту возможность крайне легко:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defstruct&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;test-prs&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:print-function&lt;/span&gt;
             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tp&lt;/span&gt; &lt;span class="nv"&gt;s&lt;/span&gt; &lt;span class="nv"&gt;pl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;princ&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;#&amp;lt;test-prs %s&amp;gt;&amp;quot;&lt;/span&gt;
                              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;test-prs-name&lt;/span&gt; &lt;span class="nv"&gt;tp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
  &lt;span class="k"&gt;type&lt;/span&gt;              &lt;span class="c1"&gt;; type of struct: `frs&amp;#39;, `snd&amp;#39;, ..&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;; name of object&lt;/span&gt;
  &lt;span class="nv"&gt;state&lt;/span&gt;             &lt;span class="c1"&gt;; state of object&lt;/span&gt;
  &lt;span class="nv"&gt;plist&lt;/span&gt;             &lt;span class="c1"&gt;; user defined properties list&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-test-prs&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Done&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;test-prs&lt;/span&gt; &lt;span class="nv"&gt;Done&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id3" name="id3"&gt;Пользовательское чтение&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Раз у нас есть пользовательская печать, то почему бы нам не иметь пользовательского чтения.  В SXEmacs была реализована возможность пользовательского чтения под кодовым названием &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ureaders&lt;/span&gt;&lt;/tt&gt; (от user readers).  В новой встроенной (built-in) переменной &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ureaders&lt;/span&gt;&lt;/tt&gt; хранится список пользовательских читалок.  Пользовательская читалка это пара, состоящая из имени и функции-читалки от одного аргумента, которая возвращает elisp-объект или порождает ошибку.  Приведу пример. Допустим, мы хотим чтобы следующая конструкция работала:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;mm&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;test&lt;/span&gt; &lt;span class="nv"&gt;ao&lt;/span&gt; &lt;span class="nv"&gt;--&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                 &lt;span class="nv"&gt;test&lt;/span&gt; &lt;span class="nv"&gt;--&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
                 &lt;span class="nv"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;--&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="nb"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;val&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ao&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;реализуем:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;my-test-reader&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;flet&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;string-trim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;replace-in-string&lt;/span&gt; &lt;span class="nv"&gt;s&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;\\(^[ \t]+\\|[ \t]+$\\)&amp;quot;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;ss&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;mapcar&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;string-trim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;split-string&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;rv&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;dolist&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt; &lt;span class="nv"&gt;ss&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;rw&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;mapcar&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;string-trim&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;split-string&lt;/span&gt; &lt;span class="nv"&gt;s&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;--&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;push&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;intern&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car&lt;/span&gt; &lt;span class="nv"&gt;rw&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cadr&lt;/span&gt; &lt;span class="nv"&gt;rw&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                &lt;span class="nv"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="nv"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;push&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;my-test-reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;ureaders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;На первый взгляд эта возможность кажется не совсем нужной, ведь у нас и так есть мощнейшее средство &amp;mdash; макросы.  Это так, конечно, но в связке с пользовательской печатью почти прямой доступ к кишкам чтения выглядит интересно.  Позже я продемонстрирую захватывающие вещи, которые можно реализовать с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ureaders&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;hr class="docutils" /&gt;&lt;div class="docutils footnote" id="id4"&gt;&lt;span class="label"&gt;&lt;a class="fn-backref" href="#id2" name="id4"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;Эта переменная пока не используется и была создана в надежде, что в будущем интерпретатор Emacs сможет её использовать.&lt;/div&gt;&lt;/div&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/user-readers.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-2610521458011245978?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/2610521458011245978/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=2610521458011245978' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/2610521458011245978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/2610521458011245978'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/repl.html' title='Расширение REPL'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-8215738685442226921</id><published>2008-12-19T03:46:00.002+03:00</published><updated>2008-12-19T06:26:50.619+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wand'/><title type='text'>Просмотр страничных файлов в Wand-mode</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: wand-mode-pages-navigation.rest,v 1.2 2008/12/08 12:07:18 lg Exp $ --&gt; &lt;p class="fl"&gt;Недавно в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt; была добавлена возможность просмотра страничных файлов, таких как &lt;acronym title="Portable Document Format"&gt;PDF&lt;/acronym&gt;, EPS, MPEG и т.д., у которых есть несколько &lt;em&gt;страниц&lt;/em&gt;.  Навигация по страницам до ужаса проста:&lt;/p&gt;&lt;ul class="simple"&gt;&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PgDown&lt;/span&gt;&lt;/tt&gt; - Следующая страница&lt;/li&gt; &lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PgUp&lt;/span&gt;&lt;/tt&gt; - Предыдущая страница&lt;/li&gt; &lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Home&lt;/span&gt;&lt;/tt&gt; - Первая страница&lt;/li&gt; &lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;End&lt;/span&gt;&lt;/tt&gt; - Последняя страница&lt;/li&gt; &lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;g&lt;/span&gt;&lt;/tt&gt; или &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;M-g&lt;/span&gt;&lt;/tt&gt; - Переход на выбранную страницу.  Передать номер страницы можно посредством универсального аргумента или ввести интерактивно.&lt;/li&gt; &lt;/ul&gt;&lt;p&gt;Конечно, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt; это вам не &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;xpdf&lt;/span&gt;&lt;/tt&gt; или &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gv&lt;/span&gt;&lt;/tt&gt;, но для быстренького ознакомления с документом или быстренького выковыривания нужной картинки из книжки или видео вполне сгодится.&lt;/p&gt;&lt;p&gt;Текущая &lt;em&gt;страница&lt;/em&gt; и общее количество &lt;em&gt;страниц&lt;/em&gt; будет отображено на экране если у вас non-&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;nil&lt;/span&gt;&lt;/tt&gt; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode-show-fileinfo&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;Заметим, что операции над картинкой будут осуществляться только для текущей &lt;em&gt;страницы&lt;/em&gt;, а не для всех &lt;em&gt;страниц&lt;/em&gt; файла.&lt;/p&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/wand-mode-pages-navigation.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-8215738685442226921?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/8215738685442226921/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=8215738685442226921' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/8215738685442226921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/8215738685442226921'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/wand-mode_19.html' title='Просмотр страничных файлов в Wand-mode'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-4326917912918014499</id><published>2008-12-19T00:41:00.002+03:00</published><updated>2008-12-19T06:26:13.537+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wand'/><title type='text'>Wand-mode - алгоритм устранения красных глаз</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: wand-redeye-algorithm.rest,v 1.6 2008/12/18 21:39:58 lg Exp $ --&gt; &lt;div class="right width50 margintop1 attention"&gt;&lt;p class="first admonition-title"&gt;Внимание!&lt;/p&gt; &lt;p class="last"&gt;Для корректного отображения этой страницы вашему браузеру необходима поддержка формата &lt;a class="reference" href="http://www.w3.org/Math/"&gt;MathML&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;p class="fl"&gt;Как и обещал напишу про то, как улучшить алгоритм устранения красных глаз у &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt; и как его тестировать.  Возможно, что найдутся желающие его поковырять и улучшить ибо я не эстет да ещё и дальтоник к тому же, так что доволен тем, что есть и сейчас.&lt;/p&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id1" name="id1"&gt;Описание алгоритма&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Вкратце, проходим по всем пикселям выделенной области и смотрим на их красноту.  Если пиксел &lt;em&gt;достаточно красный&lt;/em&gt;, то заменяем его на тёмный.  Затем немного размываем пикселы лежащие внутри эллипса, вписанного в выделенную область.  Определение красности пиксела и его замена на более тёмный происходит в функции &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-fix-red-pixels&lt;/span&gt;&lt;/tt&gt;. Аргумент &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;PIXELS&lt;/span&gt;&lt;/tt&gt;, который она принимает &amp;mdash; это список троек, где каждая тройка имеет вид &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(RED&lt;/span&gt; &lt;span class="pre"&gt;GREEN&lt;/span&gt; &lt;span class="pre"&gt;BLUE)&lt;/span&gt;&lt;/tt&gt;.  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;RED&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;GREEN&lt;/span&gt;&lt;/tt&gt; и &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;BLUE&lt;/span&gt;&lt;/tt&gt; принимают значения от 0 до 255.&lt;/p&gt;&lt;p&gt;После того как пикселы подправлены краснота уйдёт, но кое-где могут остаться резкие перепады цвета.  Для того чтобы их сгладить мы накладываем эллиптическую маску (ибо зрак, в основном, круглой формы ;)) и применяем размытие по Гауссу с радиусом, который нам выдаст функция &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode-redeye-blur-radius&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id2" name="id2"&gt;С чего начать&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Неплохим началом в ковырянии алгоритма может стать функция &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode-redeye-blur-radius&lt;/span&gt;&lt;/tt&gt;.  Это должна быть такая хитрая функция, которая даёт небольшие значения для маленьких входных и очень медленно растёт.  Сейчас это убогая &lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"&gt;&lt;mroot&gt;&lt;mrow&gt;&lt;mi&gt;W&lt;/mi&gt;&lt;mi&gt;H&lt;/mi&gt;&lt;/mrow&gt;&lt;mn&gt;16 &lt;/mn&gt;&lt;/mroot&gt;&lt;/math&gt;, где &lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"&gt;&lt;mi&gt;W&lt;/mi&gt;&lt;/math&gt; &amp;mdash; ширина выделенной области, а &lt;math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"&gt;&lt;mi&gt;H&lt;/mi&gt;&lt;/math&gt; &amp;mdash; высота.&lt;/p&gt;&lt;/div&gt;&lt;div class="section"&gt;&lt;h2&gt;&lt;a id="id3" name="id3"&gt;Тестирование улучшенного алгоритма&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Для начала скачайте &lt;a class="reference" href="http://lgarc.narod.ru/sxemacsen/img/redeye-samples.jpg"&gt;вот эту картинку&lt;/a&gt; с примерами красных глаз. Затем для тестирования вам понадобится следующая команда:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;Wand-test-redeye&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;&amp;quot;Apply redeye reduction algorithm to ARG&amp;#39;s region.&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;pp&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="mi"&gt;41&lt;/span&gt; &lt;span class="mi"&gt;349&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt; &lt;span class="mi"&gt;34&lt;/span&gt; &lt;span class="mi"&gt;86&lt;/span&gt; &lt;span class="mi"&gt;307&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="mi"&gt;354&lt;/span&gt; &lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;47&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="mi"&gt;94&lt;/span&gt; &lt;span class="mi"&gt;151&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;      &lt;span class="c1"&gt;; first region&lt;/span&gt;
              &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt; &lt;span class="mi"&gt;315&lt;/span&gt; &lt;span class="mi"&gt;676&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt; &lt;span class="mi"&gt;108&lt;/span&gt; &lt;span class="mi"&gt;660&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;86&lt;/span&gt; &lt;span class="mi"&gt;79&lt;/span&gt; &lt;span class="mi"&gt;168&lt;/span&gt; &lt;span class="mi"&gt;468&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;                    &lt;span class="c1"&gt;; second region&lt;/span&gt;
              &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="mi"&gt;335&lt;/span&gt; &lt;span class="mi"&gt;885&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;147&lt;/span&gt; &lt;span class="mi"&gt;930&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="mi"&gt;267&lt;/span&gt; &lt;span class="mi"&gt;774&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="mi"&gt;129&lt;/span&gt; &lt;span class="mi"&gt;792&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;    &lt;span class="c1"&gt;; third region&lt;/span&gt;
              &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="mi"&gt;343&lt;/span&gt; &lt;span class="mi"&gt;1219&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="mi"&gt;87&lt;/span&gt; &lt;span class="mi"&gt;1161&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="mi"&gt;294&lt;/span&gt; &lt;span class="mi"&gt;1044&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="mi"&gt;127&lt;/span&gt; &lt;span class="mi"&gt;1036&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;; fourth region&lt;/span&gt;
              &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;431&lt;/span&gt; &lt;span class="mi"&gt;1468&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="mi"&gt;376&lt;/span&gt; &lt;span class="mi"&gt;1463&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="mi"&gt;310&lt;/span&gt; &lt;span class="mi"&gt;1468&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="mi"&gt;232&lt;/span&gt; &lt;span class="mi"&gt;1477&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;116&lt;/span&gt; &lt;span class="mi"&gt;1458&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;1466&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;253&lt;/span&gt; &lt;span class="mi"&gt;1336&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;132&lt;/span&gt; &lt;span class="mi"&gt;1378&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;; fifth region&lt;/span&gt;
              &lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;mapc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;reg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Wand-operation-apply&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;redeye-remove&lt;/span&gt; &lt;span class="nv"&gt;image-wand&lt;/span&gt; &lt;span class="nv"&gt;reg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;1-&lt;/span&gt; &lt;span class="nv"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;pp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Wand-redisplay&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Откройте картинку &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;redeye-samples.jpg&lt;/span&gt;&lt;/tt&gt; с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;M-x&lt;/span&gt; &lt;span class="pre"&gt;Wand-display&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;.  Тестировать алгоритм устранения красных глаз можно с помощью команды &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-u&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;NUM&amp;gt;&lt;/span&gt; &lt;span class="pre"&gt;M-x&lt;/span&gt; &lt;span class="pre"&gt;Wand-test-redeye&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;, где &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;NUM&amp;gt;&lt;/span&gt;&lt;/tt&gt; это номер области над которой нужно произвести тестирование.  Как видно из кода всего есть 5 областей.  После выполнения команды проверьте результаты с помощью программы для увеличения, я предпочитаю &lt;a class="reference" href="http://www.oersted.co.jp/~yav/soft/#lupe"&gt;Lupe&lt;/a&gt; &amp;mdash; быстро работает и вообще отличный софт.  Если для всех областей результаты схожи с тем что справа, то у вас неплохо получилось.&lt;/p&gt;&lt;p&gt;Присылайте результаты в список рассылки &lt;a class="reference" href="http://sxemacs.org/mailman/listinfo/sxemacs-devel/"&gt;sxemacs-devel&amp;#64;&lt;/a&gt;, для лучшего варианта предусмотрен приз ;)&lt;/p&gt;&lt;/div&gt;&lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/wand-redeye-algorithm.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-4326917912918014499?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/4326917912918014499/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=4326917912918014499' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/4326917912918014499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/4326917912918014499'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/wand-mode.html' title='Wand-mode - алгоритм устранения красных глаз'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-5825046532019655924</id><published>2008-12-10T00:18:00.000+03:00</published><updated>2008-12-10T00:19:24.024+03:00</updated><title type='text'>Логотип SXEmacs</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt; &lt;!-- $Id: sxemacs-logo.rest,v 1.1 2008/12/09 21:15:51 lg Exp $ --&gt; &lt;p class="fl"&gt;Удивительно, но у SXEmacs нет логотипа в формате векторной графики, а тот, что есть в растре, по части качества просто отвратительный.&lt;/p&gt; &lt;p&gt;Я попробовал тут свои силы в создании лого в &lt;a class="reference" href="http://www.inkscape.org/"&gt;Inkscape&lt;/a&gt;.  Вот, что из этого вышло:&lt;/p&gt; &lt;div align="center" class="align-center"&gt;&lt;img alt="Лого" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sxemacs-400.png" style="width: 400px; height: 164px;" /&gt;&lt;/div&gt; &lt;p&gt;и логотип для бета версии&lt;/p&gt; &lt;div align="center" class="align-center"&gt;&lt;img alt="Бета Лого" class="align-center" src="http://lgarc.narod.ru/sxemacsen/img/sxemacs-beta-400.png" style="width: 400px; height: 164px;" /&gt;&lt;/div&gt; &lt;p&gt;Вы можете также скачать исходный &lt;a class="reference" href="http://lgarc.narod.ru/sxemacsen/img/sxemacs.svg"&gt;sxemacs.svg&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Надеюсь Стиву понравится и оный станет официальным логотипом SXEmacs.&lt;/p&gt; &lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/sxemacs-logo.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-5825046532019655924?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/5825046532019655924/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=5825046532019655924' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5825046532019655924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5825046532019655924'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/sxemacs_10.html' title='Логотип SXEmacs'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-2189324820533456718</id><published>2008-12-09T21:18:00.001+03:00</published><updated>2008-12-09T21:39:02.781+03:00</updated><title type='text'>SXEmacs - Unix-way</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt;&lt;!-- $Id: sxemacs-unix-way.rest,v 1.5 2008/12/08 04:32:12 lg Exp $ --&gt; &lt;img alt="Bloated software" class="right margintop1" src="http://lgarc.narod.ru/sxemacsen/img/bs-360.png" style="width: 360px; height: 116px;" /&gt; &lt;p class="fl"&gt;Часто приходится слышать, что Емакс это не &lt;a class="reference" href="http://www.insight-it.ru/programming/unix-way/"&gt;Unix-way&lt;/a&gt;, но так как он огромен, то в Емакс можно &lt;em&gt;всё&lt;/em&gt;, иногда даже говорят, что Емакс это целая операционная система.&lt;/p&gt; &lt;p&gt;Да, GNU Emacs огромен, ибо подход выбран доставлять до пользователя максимально укомплектованный дистрибутив.  В SXEmacs выбран другой подход &amp;mdash; предоставить пользователю небольшой дистрибутив и лёгкий способ установки пакетов.  Напомню, что в SXEmacs (в отличии от XEmacs), при поддержке &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ffi-curl&lt;/span&gt;&lt;/tt&gt;, можно начать устанавливать пакеты
без наличия каких-либо предустановленных пакетов.  Так каким образом в
дистрибутиве размером 9Mb может быть &lt;em&gt;всё&lt;/em&gt;?  Его там нет.  Зато в Unix-like системе есть &lt;em&gt;всё&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Вернёмся к изначальному вопросу.  Емакс это и есть Unix-way в чистом виде и в Емакс можно &lt;em&gt;всё&lt;/em&gt; потому и только потому, что в Unix-like системе можно &lt;em&gt;всё&lt;/em&gt;, то есть Емакс это добротный унифицированный пользовательский интерфейс к Unix-like системе.&lt;/p&gt; &lt;p&gt;Давеча, экспериментируя с отображением видео, я добился таки показа видео в обычном glyph посредством &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;xlib-ffi&lt;/span&gt;&lt;/tt&gt;, но далеко не был удовлетворён.  Я нутром чувствовал неправильность, хотя результаты были просто потрясающими.  А смущало меня наличие &lt;a class="reference" href="http://www.mplayerhq.hu/"&gt;mplayer&lt;/a&gt; &amp;mdash; отличного средства для проигрывания видео.  Памятуя совет из &lt;a class="reference" href="http://mitpress.mit.edu/sicp/"&gt;SICP&lt;/a&gt; &amp;mdash; &lt;em&gt;мысли отталкиваясь от желаемого&lt;/em&gt; (wishful thinking)&lt;a class="footnote-reference" href="#id3" id="id1" name="id1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;, я всё мечтал, чтобы видео в glyphе отображал &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mplayer&lt;/span&gt;&lt;/tt&gt;, а не сам SXEmacs. И в итоге додумал как это можно сделать!  Этот способ работает как в SXEmacs так и в XEmacs, хотя в XEmacs есть небольшие ограничения. Итак, код:&lt;/p&gt; &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;lg-video-glyph&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;optional&lt;/span&gt; &lt;span class="nv"&gt;w&lt;/span&gt; &lt;span class="nv"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;&amp;quot;Create video glyph to play FILE.&lt;/span&gt;
&lt;span class="s"&gt;Optionally you can specify width and height by passing W and H args.&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;gg&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-glyph&lt;/span&gt; &lt;span class="nv"&gt;[subwindow]&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;prc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;start-process&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;mplayer&amp;quot;&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;mplayer&amp;quot;&lt;/span&gt;
                             &lt;span class="s"&gt;&amp;quot;-wid&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;int-to-string&lt;/span&gt;
                                     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;subwindow-xid&lt;/span&gt;
                                      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;glyph-image-instance&lt;/span&gt; &lt;span class="nv"&gt;gg&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
                             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;expand-file-name&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;resize-subwindow&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;glyph-image-instance&lt;/span&gt; &lt;span class="nv"&gt;gg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;w&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;h&lt;/span&gt; &lt;span class="mi"&gt;140&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;put&lt;/span&gt; &lt;span class="nv"&gt;gg&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;mplayer-proc&lt;/span&gt; &lt;span class="nv"&gt;prc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;gg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;gg&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lg-video-glyph&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;~/video/kids/kung-fu-panda.mp4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;set-extent-end-glyph&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-extent&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
 &lt;span class="nv"&gt;gg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;конечно, укажите не &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/video/kids/kung-fu-panda.mp4&lt;/span&gt;&lt;/tt&gt;, а реальный какой-нибудь файл с видео, который у вас есть.  Появившийся, после выполнения &lt;acronym title="S expression"&gt;s-exp&lt;/acronym&gt; с &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;set-extent-end-glyph&lt;/span&gt;&lt;/tt&gt;, glyph можно изменять в размерах при помощи:&lt;/p&gt; &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;resize-subwindow&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;glyph-image-instance&lt;/span&gt; &lt;span class="nv"&gt;gg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;WIDTH&lt;/span&gt; &lt;span class="nv"&gt;HEIGHT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Заметим также, что если навести мышкой на этот glyph, то можно управлять программой &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mplayer&lt;/span&gt;&lt;/tt&gt; как обычно, т.е. делать перемотку, паузить, менять громкость и т.д.  Должен работать и &lt;acronym title="On Screen Display"&gt;OSD&lt;/acronym&gt;.&lt;/p&gt; &lt;p&gt;В XEmacs вы можете обнаружить, что glyph становится микроскопическим (20x20) если изменить размер фрейма XEmacs.  Эта неприятность была исправлена в SXEmacs.&lt;/p&gt; &lt;p&gt;Есть и ещё проблема.  Как нам определить размер видео фрейма, чтобы выставить размеры glyphа, соблюдающие пропорцию?  Можно, конечно, разобрать вывод программы &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mplayer&lt;/span&gt;&lt;/tt&gt;, но что если формат вывода будет изменён&lt;a class="footnote-reference" href="#id4" id="id2" name="id2"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;? Нет, нужно что-то более подходящее.  В SXEmacs есть такая вещь как &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;media-stream&lt;/span&gt;&lt;/tt&gt;, воспользуемся этой возможностью:&lt;/p&gt; &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;make-media-stream&lt;/span&gt; &lt;span class="ss"&gt;:file&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;~/crypt/video/kung-fu-panda.mp4&amp;quot;&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;media-stream&lt;/span&gt; &lt;span class="ss"&gt;:kind&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;file&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/home/lg/crypt/video/kung-fu-panda.mp4&amp;quot;&lt;/span&gt;&lt;span class="nb"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;media-substream&lt;/span&gt; &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;video&lt;/span&gt; &lt;span class="nv"&gt;mov,mp4,m4a,3gp,3g2,mj2&lt;/span&gt;
                            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;h264&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;720x304&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;2.37/1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;media-substream&lt;/span&gt; &lt;span class="ss"&gt;:type&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;audio&lt;/span&gt; &lt;span class="nv"&gt;mov,mp4,m4a,3gp,3g2,mj2&lt;/span&gt;
                            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;mpeg4aac&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;stereo,&lt;/span&gt; &lt;span class="mi"&gt;48000&lt;/span&gt; &lt;span class="nv"&gt;Hz,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="nv"&gt;Bit&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nv"&gt;driven&lt;/span&gt; &lt;span class="nv"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;ffmpeg&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;как видим, информация о размере фрейма у нас имеется, в моём случае это 720x304.&lt;/p&gt; &lt;p&gt;У многих может возникнуть резонный вопрос &amp;laquo;зачем в SXEmacs отображать видео?&amp;raquo;, некоторые даже могут подумать, что это идиотизм.  Но представим, что есть &amp;laquo;сумасшедший&amp;raquo;, который решил написать клиента для обмена &lt;em&gt;сообщениями&lt;/em&gt;, работающего под SXEmacs.  Причём сообщением может быть не только коротенький текст, но и голос или видео+голос или даже объект векторной графики.  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;mplayer&lt;/span&gt;&lt;/tt&gt; умеет принимать данные из &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;stdin&lt;/span&gt;&lt;/tt&gt;, поэтому вырисовывается неплохая схема медиа потоков.&lt;/p&gt; &lt;div align="center" class="right figure"&gt; &lt;img alt="SXEmacs media streams" src="http://lgarc.narod.ru/sxemacsen/img/sxemacs-media.png" style="width: 600px; height: 258px;" /&gt; &lt;p class="caption"&gt;Схема медиа потоков в SXEmacs&lt;/p&gt; &lt;/div&gt; &lt;p&gt;Опять же может возникнуть вопрос зачем такой клиент в SXEmacs, ведь есть &lt;acronym title="Вставьте здесь что пожелаете"&gt;XXX&lt;/acronym&gt;.  Да, как отдельный компонент, возможно, задающие вопрос правы, но если этот клиент будет частью системы для совместной разработки (collaborative development), то уже не так очевидно. Понятно, что в системе совместной разработки должны присутствовать компоненты:&lt;/p&gt; &lt;ul class="simple"&gt; &lt;li&gt;Мощный текстовый редактор ;)&lt;/li&gt; &lt;li&gt;Средство для совместного редактирования файлов&lt;/li&gt; &lt;li&gt;Средство для обмена сообщениями: текстовыми, голосовыми, видео&lt;/li&gt; &lt;li&gt;Средства для мозгового штурма &amp;mdash; совместная доска для рисования, писания, черкания и т.д.&lt;/li&gt; &lt;li&gt;Система контроля версий&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;про простоту использования, свободные технологии в основе и унифицированность пользовательского интерфейса я уже и не говорю. Так, что-то я отвлёкся в сторону.  О системе совместной разработки я напишу позже.&lt;/p&gt; &lt;p&gt;Основной же вывод из примера с видео-glyph я хочу сделать, что SXEmacs &amp;mdash; это и есть Unix-way как он задумывался изначально.&lt;/p&gt; &lt;hr class="docutils" /&gt; &lt;div class="docutils footnote" id="id3"&gt; &lt;span class="label"&gt;&lt;a class="fn-backref" href="#id1" name="id3"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;В русском переводе SICP &amp;laquo;wishful thinking&amp;raquo; переведено как &amp;laquo;мечтать не вредно&amp;raquo;.&lt;/div&gt; &lt;div class="docutils footnote" id="id4"&gt; &lt;span class="label"&gt;&lt;a class="fn-backref" href="#id2" name="id4"&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/span&gt;Стандартизированный ввод и вывод программ это тоже один из аспектов Unix-way.&lt;/div&gt; &lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/sxemacs-unix-way.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-2189324820533456718?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/2189324820533456718/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=2189324820533456718' title='Комментарии: 3'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/2189324820533456718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/2189324820533456718'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/sxemacs-unix-way.html' title='SXEmacs - Unix-way'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-8648882131817165489</id><published>2008-12-05T13:35:00.003+03:00</published><updated>2008-12-09T20:39:37.454+03:00</updated><title type='text'>Магические файлы</title><content type='html'>&lt;!-- Copyright (C) 2008 Zajcev Evgeny --&gt;&lt;!-- $Id: find-file-magick-file-alist.rest,v 1.3 2008/12/08 04:32:12 lg Exp $ --&gt;&lt;p class="fl"&gt;Расскажу про одну особенность в SXEmacs &amp;mdash; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Всегда есть &lt;em&gt;специальные&lt;/em&gt; файлы, которые не нужно открывать как текстовые, а нужно его специальным образом обработать и отобразить какую-нибудь информацию.  К таким файлам относятся, например, директории.  Я сомневаюсь, что вы хотели бы при выполнении команды &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-f&lt;/span&gt; &lt;span class="pre"&gt;/tmp&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt; увидеть бинарное содержимое файла &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/tmp&lt;/span&gt;&lt;/tt&gt; (напомню, что директории это такие же файлы как и все остальные).  Вы наверняка хотели бы, чтобы запустился &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dired&lt;/span&gt;&lt;/tt&gt; над этой директорией и вы увидели бы её содержимое.  В GNU Emacs и XEmacs это сделано явно, то есть при открытие файла (вызове &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-noselect&lt;/span&gt;&lt;/tt&gt;, а остальное семейство find-file-функций использует эту) происходит проверка, является ли файл директорией и если да, то запускается &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dired&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Этот подход очень ограниченный, так как не только директории могут быть магическими файлами.  Поэтому в SXEmacs была введена новая переменная &amp;mdash; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt;.  Это обычный &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;alist&lt;/span&gt;&lt;/tt&gt; (список пар), в котором голова пары это предикат получающий имя файла и возвращающий non-&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;nil&lt;/span&gt;&lt;/tt&gt; в случае если файл магический, а хвост пары это одноарная функция, получающая имя файла (про который уже известно, что он магический) и обязательно возвращающая какой-нибудь буфер, в котором содержится интерпретация этого магического файла.&lt;/p&gt; &lt;p&gt;По умолчанию в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt; всего одна пара &amp;mdash; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(file-directory-p&lt;/span&gt; &lt;span class="pre"&gt;.&lt;/span&gt; &lt;span class="pre"&gt;find-file-try-dired-noselect)&lt;/span&gt;&lt;/tt&gt;.  Как вы догадались это для работы &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dired&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Мы уже знаем про мощный инструмент работы с изображениями &amp;mdash; &lt;a class="reference" href="http://sxemacsen.blogspot.com/2008/12/wand-mode-display1.html"&gt;Wand-mode&lt;/a&gt;.  Хотелось бы сделать так, что если какой-нибудь файл может быть открыт с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-display&lt;/span&gt;&lt;/tt&gt;, то и использовать его для таких файлов.  Скажем, что файлы с изображениями &amp;mdash; магические и воспользуемся переменной &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;push&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Wand-file-supported-for-read-p&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;Wand-display-noselect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nv"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;или и того проще:&lt;/p&gt; &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Wand-find-file-enable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;теперь если мы откроем файл с картинкой с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-f&lt;/span&gt;&lt;/tt&gt; (или любой другой командой find-file-семейства), то у нас запуститься &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Заметим, что предикаты в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt; должны быть очень точными.  Если вдруг какой-нибудь предикат вернёт non-&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;nil&lt;/span&gt;&lt;/tt&gt; для немагического файла - это приведёт к проблемам.  На счастье в SXEmacs есть команда-функция &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;magic:file-type&lt;/span&gt;&lt;/tt&gt;, которая воспользуется прелестями &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;libmagic&lt;/span&gt;&lt;/tt&gt; и вернёт вероятный тип файла. Наверняка вы знаете программу &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;file(1)&lt;/span&gt;&lt;/tt&gt;, которая использует &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;libmagic&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Ещё один пример магический файлов.  Это файлы с базами &lt;a class="reference" href="http://sqlite.org"&gt;SQLite&lt;/a&gt;.  Я уж точно не хочу открыв, с помощью &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-f&lt;/span&gt;&lt;/tt&gt;, файл с базой увидеть её бинарное содержимое.  Заместо хотелось бы, что бы запустилась программа &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sqlite&lt;/span&gt;&lt;/tt&gt;, натравленная на этот файл, и я бы мог давать всякие команды, SQLные ли запросы или всякие &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.tables&lt;/span&gt;&lt;/tt&gt; и т.д. Напишем пару функций - предикат и открывалку:&lt;/p&gt; &lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;lg-sqlite-file-p&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;&amp;quot;Return non-nil if FILENAME is actually SQLite format 3 file.&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with-temp-buffer&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;insert-file-contents-literally&lt;/span&gt; &lt;span class="nv"&gt;filename&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;string=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;buffer-substring&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;SQLite format 3&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;lg-sqlite-find-file&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;sql-database&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;funcall&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-product-feature&lt;/span&gt; &lt;span class="ss"&gt;:sqli-connect&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;sqlite&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;sql-interactive-product&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;sqlite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;sql-buffer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;current-buffer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sql-interactive-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;rename-buffer&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;*SQL:%s*&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-name-nondirectory&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;current-buffer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Если у вас есть рабочий &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ffi-sqlite&lt;/span&gt;&lt;/tt&gt;, то можете воспользоваться уже готовым предикатом - &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sqlite-file-p&lt;/span&gt;&lt;/tt&gt;.  Теперь добавим элемент в &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;push&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;lg-sqlite-file-p&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;lg-sqlite-find-file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nv"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Всё, теперь можно открывать файлы с базами &lt;a class="reference" href="http://sqlite.org"&gt;SQLite&lt;/a&gt; &amp;mdash; &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-f&lt;/span&gt; &lt;span class="pre"&gt;~/test.db&lt;/span&gt; &lt;span class="pre"&gt;RET&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt; &lt;p&gt;Аналогичным образом можно сделать, например, чтобы запускался &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gdb-with-core&lt;/span&gt;&lt;/tt&gt; с правильными аргументами при открытии &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;core&lt;/span&gt;&lt;/tt&gt; файлов.&lt;/p&gt; &lt;p&gt;Вообще, Емаксу необходим более продвинутый механизм автоматического определения, что делать с файлом на замену давно устаревшего &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;auto-mode-alist&lt;/span&gt;&lt;/tt&gt;.  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;find-file-magic-files-alist&lt;/span&gt;&lt;/tt&gt; может стать неплохим началом в создании такого механизма.&lt;/p&gt; &lt;p style="text-align: right"&gt;&lt;a href="http://lgarc.narod.ru/sxemacsen/find-file-magick-file-alist.rest"&gt;&lt;img alt="ReST source" class="icon16" src="http://lgarc.narod.ru/sxemacsen/img/file_src.png" /&gt; Скачать оригинал&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-8648882131817165489?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/8648882131817165489/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=8648882131817165489' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/8648882131817165489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/8648882131817165489'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/blog-post.html' title='Магические файлы'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-6741732202729848022</id><published>2008-12-02T14:16:00.019+03:00</published><updated>2008-12-04T15:24:07.833+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ffi'/><category scheme='http://www.blogger.com/atom/ns#' term='wand'/><title type='text'>Wand-mode -- забудьте о display(1)</title><content type='html'>&lt;span class="pre"&gt;Wand-mode&lt;/span&gt; это режим просмотра и редактирования изображений для SXEmacs.  &lt;span class="pre"&gt;Wand-mode&lt;/span&gt; базируется на &lt;acronym title="Application Programming Interface"&gt;API&lt;/acronym&gt; &lt;a class="reference" href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt; и поэтому в &lt;span class="pre"&gt;Wand-mode&lt;/span&gt; возможны многие операции программ &lt;span class="pre"&gt;convert(1)&lt;/span&gt;, &lt;span class="pre"&gt;display(1)&lt;/span&gt; и т.д.  &lt;span class="pre"&gt;Wand-mode&lt;/span&gt; поддерживает все форматы поддерживаемые &lt;acronym title="ImageMagick"&gt;IM&lt;/acronym&gt;, а их более 100, в том числе PDF, EPS, etc.
&lt;h3&gt;Знакомство с &lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/h3&gt;&lt;span class="pre"&gt;M-x Wand-display RET /path/to/image.jpg RET&lt;/span&gt; получаем результат примерно следующий:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display sample" class="align-center" src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZZGEbxeQI/AAAAAAAAA24/3hyqz0ENQq4/wd-500.jpg" style="width: 500px; height: 260px;" /&gt;
&lt;/div&gt;Смотрим информацию о файле - кнопка &lt;span class="pre"&gt;i&lt;/span&gt;:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display identify" class="align-center" src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZaEdl8ZRI/AAAAAAAAA3A/lhbq7HvaRig/wdi-500.jpg" style="width: 500px; height: 260px;" /&gt;
&lt;/div&gt;Теперь подредактируем: наложим операцию очищения от мусора (Despeckle) и немного уменьшим контрастность.  Используем кнопки &lt;span class="pre"&gt;o&lt;/span&gt; &lt;span class="pre"&gt;despeckle RET&lt;/span&gt; далее &lt;span class="pre"&gt;o contrast RET decrease RET&lt;/span&gt;.  Везде будет работать completition так что не переживайте.  Получаем результат:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display edit" class="align-center" src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZkS11na9I/AAAAAAAAA4A/OLW3sqbXW58/wd-edit-500.jpg" style="width: 500px; height: 260px;" /&gt;
&lt;/div&gt;
&lt;h3&gt;Просмотр директорий с изображениями&lt;/h3&gt;У &lt;span class="pre"&gt;Wand-mode&lt;/span&gt; простые, но неплохие навигационные возможности для просмотра.  Откройте любой файл с помощью &lt;span class="pre"&gt;Wand-display&lt;/span&gt;, если в его директории есть ещё файлы, поддерживаемые &lt;acronym title="ImageMagick"&gt;IM&lt;/acronym&gt;, то вы можете использовать кнопки:
&lt;ul class="simple"&gt;&lt;li&gt;&lt;span class="pre"&gt;Space&lt;/span&gt; - следующая картинка &lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;BackSpace&lt;/span&gt; - предыдущая&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;M-&amp;lt;&lt;/span&gt; - Самая первая картинка в директории&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;M-&amp;gt;&lt;/span&gt; - Самая последняя картинка в директории&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Меню &lt;span class="pre"&gt;Wand-mode&lt;/span&gt;
&lt;/h3&gt;&lt;p&gt;У &lt;span class="pre"&gt;Wand-mode&lt;/span&gt; есть отличное меню (чем-то схожее с меню &lt;span class="pre"&gt;display(1)&lt;/span&gt;) для работы изображением.
&lt;/p&gt;&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display menu" class="align-center" src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZn4REx3RI/AAAAAAAAA7w/6bvdZeA_n94/wd-menu-500.jpg" style="width: 500px; height: 260px;" /&gt;
&lt;/div&gt;Меню доступно либо из &lt;span class="pre"&gt;menubar&lt;/span&gt; если он у вас включён, либо же по правой кнопке мыши.  Все команды, которые можно выполнить клавиатурой можно выполнить и через меню.  Верно и обратное - все команды, которые можно выполнить через меню можно выполнить и через клавиатуру.

&lt;h3&gt;Настройка &lt;span class="pre"&gt;Wand-mode&lt;/span&gt;&lt;/h3&gt;У &lt;span class="pre"&gt;Wand-mode&lt;/span&gt; не так много параметров, поэтому настройка дело простое.  Как обычно вы можете всё сделать через &lt;span class="pre"&gt;M-x customize-group RET Wand-mode RET&lt;/span&gt;, я лишь приведу небольшое описание параметров, которые вы скорее всего захотите изменить:
&lt;ul&gt;&lt;li&gt;&lt;span class="pre"&gt;Wand-mode-zoom-factor&lt;/span&gt; - Number (default: &lt;span class="pre"&gt;2&lt;/span&gt;)
&lt;p&gt;Как из названия ясно это коэффициент для команд &lt;span class="pre"&gt;+&lt;/span&gt;(zoom-in) и &lt;span class="pre"&gt;-&lt;/span&gt; (zoom-out)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;Wand-mode-show-fileinfo&lt;/span&gt; - Boolean (default: &lt;span class="pre"&gt;t&lt;/span&gt;)
&lt;p&gt;Если non-&lt;span class="pre"&gt;nil&lt;/span&gt;, то будет выводится минимальная информация о просматриваемом файле.  Для более подробной информации, как уже отмечалось, есть команда &lt;span class="pre"&gt;i&lt;/span&gt;.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;Wand-mode-show-operations&lt;/span&gt; - Boolean (default: &lt;span class="pre"&gt;t&lt;/span&gt;)
&lt;p&gt;Если non-&lt;span class="pre"&gt;nil&lt;/span&gt;, то при выполнении операций будет выводится список операций над изображением. Выполнять команды undo/redo вы сможете в любом случае.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;Wand-mode-auto-fit&lt;/span&gt; - Boolean (default: &lt;span class="pre"&gt;t&lt;/span&gt;)
&lt;p&gt;Если non-&lt;span class="pre"&gt;nil&lt;/span&gt;, то при выводе изображения в окне SXEmacs оно(изображение) будет уменьшено если не умещается.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;Wand-mode-auto-rotate&lt;/span&gt; - Boolean (default: &lt;span class="pre"&gt;t&lt;/span&gt;)
&lt;p&gt;Если non-&lt;span class="pre"&gt;nil&lt;/span&gt;, то в случае наличия у изображения информации о его ориентации (современные фотоаппараты умеют правильно определять ориентацию в зависимости от положения фотоаппарата в пространстве), то выводимое изображение будет автоматически повёрнуто.  При этом поворот будет входить в список совершённых операций над изображением.  Достаточно удобно.
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Внесение изменений и сохранение результатов&lt;/h3&gt;Для операций над изображением по умолчанию доступны следующие кнопки:
&lt;ul class="simple"&gt;&lt;li&gt;&lt;span class="pre"&gt;l&lt;/span&gt; - Поворот на 90° против часовой стрелки (как бы влево)
&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;r&lt;/span&gt; - Поворот на 90° по часовой стрелке (как бы вправо)
&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;+&lt;/span&gt; - Увеличение изображения в соответствии с &lt;span class="pre"&gt;Wand-mode-zoom-factor&lt;/span&gt;
&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;-&lt;/span&gt; - Уменьшение изображения в соответствии с &lt;span class="pre"&gt;Wand-mode-zoom-factor&lt;/span&gt;
&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;o&lt;/span&gt; - Главная кнопка операций. Спрашивает у пользователя какую операцию и с какими параметрами применить.  Поддерживает completition.
&lt;/li&gt;&lt;/ul&gt;Операции можно применять одна за другой, как мы уже делали. Все операции над картинкой записываются и в любой момент можно сделать undo или redo операций с помощью стандартных клавиш &lt;span class="pre"&gt;C-/&lt;/span&gt; (или &lt;span class="pre"&gt;C-_&lt;/span&gt;) и &lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;C-/&lt;/span&gt;, также можно повторно применить последнюю операцию при помощи кнопки &lt;span class="pre"&gt;C-.&lt;/span&gt; или &lt;span class="pre"&gt;C-x&lt;/span&gt; &lt;span class="pre"&gt;M-:&lt;/span&gt; (в обычном режиме эта комбинация выполняет команду &lt;span class="pre"&gt;`repeat-complex-command'&lt;/span&gt;).  Чтобы отменить все операции просто перезагрузите изображение при помощи команды &lt;span class="pre"&gt;C-r&lt;/span&gt;.
&lt;p&gt;Теперь когда новое изображение готово, его нужно сохранить на диск. Для этого есть две команды:&lt;/p&gt;&lt;ul class="simple"&gt;&lt;li&gt;&lt;span class="pre"&gt;C-x C-w&lt;/span&gt; - Вам предложат выбрать один из форматов для записи и имя нового файла. &lt;strong&gt;ВНИМАНИЕ&lt;/strong&gt;: запись в &lt;em&gt;неграфические&lt;/em&gt; форматы типа &lt;span class="pre"&gt;HTML&lt;/span&gt;, &lt;span class="pre"&gt;TXT&lt;/span&gt; и т.д. может привести к &lt;span class="pre"&gt;core dump&lt;/span&gt;. По всей видимости это связано с ошибкой в &lt;acronym title="ImageMagick"&gt;IM&lt;/acronym&gt;, но, к сожалению, разработчики &lt;acronym title="ImageMagick"&gt;IM&lt;/acronym&gt; не шибко контактные ребята, поэтому бог знает когда это будет исправлено.
&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;C-x C-s&lt;/span&gt; - Простой вариант записи. Вам предложат выбрать имя файла, а формат изображения будет определён из расширения имени.
&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Операции над областью изображения&lt;/h3&gt;С помощью левой кнопки мыши можно выделить некоторую область изображения, например руку Сары:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display region" class="align-center" src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZn4m4Qh9I/AAAAAAAAA74/hgDM2PjfrfQ/wd-region-500.jpg" style="width: 500px; height: 260px;" /&gt;
&lt;div style="text-align: left;"&gt;Если параметр &lt;span class="pre"&gt;Wand-mode-show-fileinfo&lt;/span&gt; проставлен в non-&lt;span class="pre"&gt;nil&lt;/span&gt;, то вы увидите координаты области, иногда это полезно.  Когда область активна, то некоторые операции (которые можно применить для области, например изменение контраста, уменьшение шума, размытие и т.д.)  будут изменять изображение только в области. Есть также команды, которые можно выполнить &lt;em&gt;только&lt;/em&gt; для области, такие как:
&lt;/div&gt;&lt;/div&gt;&lt;ul class="simple"&gt;&lt;li&gt;&lt;span class="pre"&gt;c&lt;/span&gt;    - crop, оставить только область и отрезать всё что вне её
&lt;/li&gt;&lt;li&gt;&lt;span class="pre"&gt;o chop RET&lt;/span&gt; - chop, вырезать область и сомкнуть края
&lt;/li&gt;&lt;li&gt;&lt;a class="reference" href="http://www.blogger.com/post-edit.g?blogID=4022155443158713503&amp;amp;postID=6741732202729848022#id7"&gt;Устранение красных глаз&lt;/a&gt;
&lt;/li&gt;&lt;/ul&gt;Выполнив операцию над областью, выделение исчезает.  Чтобы заново выделить последнюю область используйте команду &lt;span class="pre"&gt;C-M-z&lt;/span&gt; (в обычном режиме эта комбинация клавиш выполняет &lt;span class="pre"&gt;activate-region&lt;/span&gt;).
&lt;h3&gt;&lt;a id="id7" name="id7"&gt;Устранение красных глаз&lt;/a&gt;&lt;/h3&gt;Самое главное в устранении красных глаз это грамотно выделить область с краснотою.  Выделять лучше всего таким образом, чтобы краснота была в центре и оставалось немного пространства от красноты до краёв выделенной области.  Вот пример удачного выделения:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display red eye good region" class="align-center" src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZn44D_vGI/AAAAAAAAA8A/diO8oZgUCJs/ra-good-500.jpg" style="width: 500px; height: 291px;" /&gt;
&lt;/div&gt;А вот не совсем удачного, хотя алгоритм устранения красных глаз сработает и в данном случае, но при более тяжёлых будут заметны артефакты:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display red eye bad region" class="align-center" src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZn5MoxvdI/AAAAAAAAA8I/FTDdTk2pXws/ra-bad-500.jpg" style="width: 500px; height: 291px;" /&gt;
&lt;/div&gt;После того как вы выделили нужную область просто нажмите &lt;span class="pre"&gt;.&lt;/span&gt; или выберите пункт в Меню &lt;strong&gt;Wand →Region→Remove red eye&lt;/strong&gt;.

Алгоритм устранения красных глаз достаточно прямолинеен и не дотягивает до реализованных в профессиональных утилитах.  С другой стороны результаты демонстрирует неплохие и пригодные для сельской местности.  Я провёл сравнение и вот результаты:
&lt;div class="align-center" align="center"&gt;&lt;img alt="Wand-display red eyes sxemacs vs prof" class="align-center" src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZn5aFIxAI/AAAAAAAAA8Q/uyySx3IG4_8/s576/redeyes-sxemacs-vs-prof.jpg" /&gt;
&lt;/div&gt;Про то как улучшить алгоритм устранения красных глаз и как его тестировать я напишу в следующий раз.
&lt;h3&gt;Сводная таблица операций&lt;/h3&gt;Ну и напоследок я сделал небольшой обзор операций над изображениями. Заметим, что операции, которые не изменяют размер изображения могут без проблем применяться к области:
&lt;table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="transform"&gt;&lt;td colspan="4" align="center"&gt;&lt;span style="font-weight: bold; text-decoration: underline;font-size:110;"&gt;Transform&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align: top;"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Sample&lt;/span&gt;
Width: 400
Height: 200&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkkheR7-I/AAAAAAAAA4o/5X5dByEEz-s/sample.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align: top;"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Rotate&lt;/span&gt;
Degrees: 120°&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkUPDH1zI/AAAAAAAAA4g/ojSRd9ZnQR8/rotate-120.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align: top;"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Flip&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTZASKxI/AAAAAAAAA4Q/ps92PCc34jM/flip.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align: top;"&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Flop&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZkTxDqGuI/AAAAAAAAA4Y/wTgBqOsdVwA/flop.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr id="effects"&gt;&lt;td colspan="3" align="center"&gt;&lt;span style="font-weight: bold; text-decoration: underline;font-size:110;" &gt;Effect&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Add Noise&lt;/span&gt;
Noise type: Poisson&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh3.ggpht.com/_eA5oAfIbdq0/STZmOjQ-KMI/AAAAAAAAA5g/fV5C4tWcO_Y/add-noise-poisson.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Despeckle&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZmOzgc88I/AAAAAAAAA5o/IvBoy4CahmM/despeckle.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Edge detect&lt;/span&gt;
Radius: 1.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZmPKz-JXI/AAAAAAAAA5w/e5D6EHecuH0/edge-detect-1.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Emboss&lt;/span&gt;
Radius: 1.0
Sigma: 2.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZmgldH6rI/AAAAAAAAA6A/0dV3lxPs6z8/emboss-1-2.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Gaussian Blur&lt;/span&gt;
Radius: 1.0
Sigma: 2.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZmgHqCdVI/AAAAAAAAA54/UxZ6YOvDK1A/gaussian-blur-1-2.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Radial Blur&lt;/span&gt;
Radius: 3.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZmg3UrDnI/AAAAAAAAA6I/t1Ppw-Sr6Wk/radial-blur-3.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Reduce Noise&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZmhUPcoGI/AAAAAAAAA6Q/CsEP31V312A/reduce-noise.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Sharpen&lt;/span&gt;
Radius: 1.0
Sigma: 2.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh3.ggpht.com/_eA5oAfIbdq0/STZmhQ7TKZI/AAAAAAAAA6Y/WYMf4leOr44/sharpen-1-2.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Spread&lt;/span&gt;
Radius: 1.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZnAmqtKPI/AAAAAAAAA6g/R81CWK2XzQI/spread-1.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr id="enhance"&gt;&lt;td colspan="3" align="center"&gt;&lt;span style="font-weight: bold; text-decoration: underline;font-size:110;" &gt;Enhance&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Contrast&lt;/span&gt;
Type: increase&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZkkwPq0ZI/AAAAAAAAA44/0qAu1Wuykbc/contrast-increase.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Contrast&lt;/span&gt;
Type: decrease&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZkki44-5I/AAAAAAAAA4w/uH_eCFzBwjE/contrast-decrease.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Enhance&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh4.ggpht.com/_eA5oAfIbdq0/STZklLQdDwI/AAAAAAAAA5A/WmdSJpcQ8p4/enhance.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Equalize&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZklX8K5DI/AAAAAAAAA5I/95Lp2AtK8zI/equalize.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Negate&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZmOQ9aubI/AAAAAAAAA5Q/jTbXOQxhqY8/negate.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Normalize&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZmOhMAszI/AAAAAAAAA5Y/XAsqwlzJvj0/normalize.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr id="fx"&gt;&lt;td colspan="3" align="center"&gt;&lt;span style="font-weight: bold; text-decoration: underline;font-size:110;" &gt;F/X&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Charcoal&lt;/span&gt;
Radius: 1.0
Sigma: 2.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZnAvHQ1CI/AAAAAAAAA6o/M_fZ9BOZu6I/charcoal-1-2.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Implode&lt;/span&gt;
Radius: 0.4&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZnBfgWL4I/AAAAAAAAA64/q5pv49pbkb0/implode-0.4.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Implode&lt;/span&gt;
Radius: -0.4&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZnBDnm46I/AAAAAAAAA6w/f6UTAfl6xAo/implode--0.4.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Oil Paint&lt;/span&gt;
Radius: 2.0&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZnBjot7BI/AAAAAAAAA7A/xMh2ehZkiik/oil-paint-2.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Sepia Tone&lt;/span&gt;
Threshold: 85%&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZnmgZdiPI/AAAAAAAAA7I/4iHMF3O7qsc/sepia-tone-85.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Solarize&lt;/span&gt;
Threshold: 50%&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh3.ggpht.com/_eA5oAfIbdq0/STZnm1CldTI/AAAAAAAAA7Q/naDzSWEtOKs/solarize-50.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Swirl&lt;/span&gt;
Angle: 90°&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh3.ggpht.com/_eA5oAfIbdq0/STZnm7j9anI/AAAAAAAAA7Y/h5mCF6JOJ5o/swirl-90.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Vignette&lt;/span&gt;
Black/White: 10&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh3.ggpht.com/_eA5oAfIbdq0/STZnnJtIc3I/AAAAAAAAA7g/7AS7QWj5EII/vignette-10.jpg" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img src="http://lh6.ggpht.com/_eA5oAfIbdq0/STZkTSpO3xI/AAAAAAAAA4I/w4CsbXLFMlk/input.jpg" /&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight: bold;"&gt;Wave&lt;/span&gt;
Amplitude: 2
Wave length: 10&lt;/td&gt;&lt;td&gt;&lt;img src="http://lh5.ggpht.com/_eA5oAfIbdq0/STZnnbgxNkI/AAAAAAAAA7o/Wqj19S9M2Vo/wave-2-10.jpg"/&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-6741732202729848022?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/6741732202729848022/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=6741732202729848022' title='Комментарии: 5'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/6741732202729848022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/6741732202729848022'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/wand-mode-display1.html' title='Wand-mode -- забудьте о display(1)'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_eA5oAfIbdq0/STZZGEbxeQI/AAAAAAAAA24/3hyqz0ENQq4/s72-c/wd-500.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-5367728216023231465</id><published>2008-12-02T14:03:00.001+03:00</published><updated>2008-12-02T14:07:45.942+03:00</updated><title type='text'>Ascii-art лого для SXEmacs</title><content type='html'>&lt;pre style="font-weight: bold; line-height: 100%"&gt;
   ____________  _____________
  /   ____/\   \/  /\_   ____/ _____ _____   ____  ______
  \____  \  \     /  |   __|_ /     \\__  \ / ___\/  ___/
  /       \ /     \  |       \  Y Y  \/ __ Y  \___\___ \ 
 /________//___/\__\/________/__|_|__|_____/\____/_____/

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-5367728216023231465?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/5367728216023231465/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=5367728216023231465' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5367728216023231465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5367728216023231465'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/ascii-art-sxemacs.html' title='Ascii-art лого для SXEmacs'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-7017845480857217557</id><published>2008-12-01T15:24:00.006+03:00</published><updated>2008-12-02T15:41:48.032+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rus'/><title type='text'>Быстрый ёфикатор для SXEmacs</title><content type='html'>Сегодня, в день рождения &lt;a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%B0%D1%80%D0%B0%D0%BC%D0%B7%D0%B8%D0%BD"&gt;Карамзина&lt;/a&gt;, я покажу как в SXEmacs можно сделать быстрый полу-автоматический &lt;a href="http://ru.wikipedia.org/wiki/%D0%81%D1%84%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80"&gt;ёфикатор&lt;/a&gt; текста.

Для начала демонстрация:
&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-d1beb26e140a609d" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;
&lt;param name="bgcolor" value="#FFFFFF"&gt;
&lt;param name="allowfullscreen" value="true"&gt;
&lt;param name="flashvars" value="flvurl=http://v1.nonxt1.googlevideo.com/videoplayback?id%3Dd1beb26e140a609d%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331343849%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D25E46F83F6346C6F286E3133ACFD21F3342D81B4.1BA4850A233C4E2D3821741951F3E6DAB6B7B137%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dd1beb26e140a609d%26offsetms%3D5000%26itag%3Dw160%26sigh%3DYRRAQQgf_1vyxJuLwSqyQrdbPy8&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;
&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"
width="320" height="266" bgcolor="#FFFFFF"
flashvars="flvurl=http://v1.nonxt1.googlevideo.com/videoplayback?id%3Dd1beb26e140a609d%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331343849%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D25E46F83F6346C6F286E3133ACFD21F3342D81B4.1BA4850A233C4E2D3821741951F3E6DAB6B7B137%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Dd1beb26e140a609d%26offsetms%3D5000%26itag%3Dw160%26sigh%3DYRRAQQgf_1vyxJuLwSqyQrdbPy8&amp;autoplay=0&amp;ps=blogger"
allowFullScreen="true" /&gt;&lt;/object&gt;


Для выполнения такой задачи уже существовал &lt;a href="http://python.anabar.ru/yo.htm"&gt;скрипт и база слов&lt;/a&gt; Евгения Миньковского для XEmacs, но у этого решения есть несколько недостатков:
&lt;ul&gt;&lt;li&gt;Время загрузки базы слов в hash-таблицу (serialization) крайне огромное и этому есть объяснения.&lt;/li&gt;&lt;li&gt;В скрипте содержатся не-ascii символы, это скорее эстетический недостаток, а не реальный.&lt;/li&gt;&lt;/ul&gt;Я поэкспериментировал немного, посоветовался с разработчиками XEmacs и SXEmacs и пришёл к выводу, что сделать более быструю (чем O(n)) сереализацию базы слов в hash-таблицу пока не представляется возможным.

С другой стороны, я был наслышан, что третья реализация FTS(Full Text Search) в SQLite3 достаточно быстра, к тому же, у SQLite3 хороший и простой API.  Поэтому было решено написать ffi-sqlite.el -- FFI(Foreign Function Interface) к библиотеке sqlite3, что и было сделано в течение пары часов.  (На данный момент ffi-sqlite.el уже находится в main репозитарии SXEmacs)

После того как в моих руках оказалась связка SXEmacs+SQLite из базы слов Евгения Миньковского была создана &lt;a href="http://lgarc.narod.ru/sxemacs/yo.db"&gt;sqlite база&lt;/a&gt; с двумя FTS таблицами:
&lt;ol&gt;&lt;li&gt;Для слов, в которых написание ё точно определено&lt;/li&gt;&lt;li&gt;Для слов, в которых возможно написание ё&lt;/li&gt;&lt;/ol&gt;Далее дело техники.  Немного адаптируем код Евгения и получаем:
&lt;pre style="line-height: 100%;"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defcustom&lt;/span&gt; &lt;span style="color: rgb(139, 0, 139);"&gt;yo-db-file&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;expand-file-name "&lt;span style="color: rgb(0, 139, 0);"&gt;yo.db&lt;/span&gt;" user-init-directory&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
"&lt;span style="color: rgb(0, 139, 0);"&gt;File with yo database.&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defcustom&lt;/span&gt; &lt;span style="color: rgb(139, 0, 139);"&gt;yo-cutting-strings&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;list "&lt;span style="color: rgb(0, 139, 0);"&gt;\\-&lt;/span&gt;" "&lt;span style="color: rgb(0, 139, 0);"&gt;\"=&lt;/span&gt;" "&lt;span style="color: rgb(0, 139, 0);"&gt;\"~&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
"&lt;span style="color: rgb(0, 139, 0);"&gt;Words in the text may be splitting by some strings:
for example: hy\\-phe\\-na\\-ti\\-on in TeX&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defconst&lt;/span&gt; &lt;span style="color: rgb(139, 0, 139);"&gt;yo-cutting-regexp&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;concat "&lt;span style="color: rgb(0, 139, 0);"&gt;\\(?:&lt;/span&gt;"
        &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;mapconcat 'regexp-quote
                   yo-cutting-strings "&lt;span style="color: rgb(0, 139, 0);"&gt;\\|&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
        "&lt;span style="color: rgb(0, 139, 0);"&gt;\\)&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;

&lt;span style="color: rgb(0, 0, 139);"&gt;;; Under Mule: 1493 - little e, 1461 - big E
&lt;/span&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defconst&lt;/span&gt; &lt;span style="color: rgb(139, 0, 139);"&gt;yo-e-word-regexp&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;concat "&lt;span style="color: rgb(0, 139, 0);"&gt;\\(?:\\w\\(?:\\w\\|&lt;/span&gt;" yo-cutting-regexp "&lt;span style="color: rgb(0, 139, 0);"&gt;\\)*\\)?&lt;/span&gt;"
        "&lt;span style="color: rgb(0, 139, 0);"&gt;\\(?:&lt;/span&gt;" &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;char-to-string &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;int-to-char 1493&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt; "&lt;span style="color: rgb(0, 139, 0);"&gt;\\|&lt;/span&gt;"
        &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;char-to-string &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;int-to-char 1461&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt; "&lt;span style="color: rgb(0, 139, 0);"&gt;\\)&lt;/span&gt;"
        "&lt;span style="color: rgb(0, 139, 0);"&gt;\\(?:\\w\\(?:\\w\\|&lt;/span&gt;" yo-cutting-regexp "&lt;span style="color: rgb(0, 139, 0);"&gt;\\)*\\)?&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defvar&lt;/span&gt; &lt;span style="color: rgb(139, 0, 139);"&gt;yo-db&lt;/span&gt; nil&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defun&lt;/span&gt; &lt;span style="color: rgb(139, 35, 35);"&gt;yo-word&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;word &lt;span style="color: rgb(70, 130, 180);"&gt;&amp;amp;optional&lt;/span&gt; table&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
"&lt;span style="color: rgb(0, 139, 0);"&gt;Return yo variant of the WORD.
Return value:
nil     - no yo variant
string  - unambiguous yo variant
(maybe . string) - ambiguous yo variant&lt;/span&gt;"
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;unless&lt;/span&gt; yo-db
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;setq yo-db &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;sqlite-open yo-db-file&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;let*&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;((&lt;/span&gt;sql &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;format "&lt;span style="color: rgb(0, 139, 0);"&gt;select val from %S where key match ?&lt;/span&gt;"
                    &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;or table 'onlyyo&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; word&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
       &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;eword &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;encode-coding-string word 'utf-8&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
       &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;result &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;car &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;car &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;sqlite-rows yo-db sql &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;list eword&lt;span style="color: rgb(105, 105, 105);"&gt;))))))&lt;/span&gt;
  &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;if&lt;/span&gt; result
      &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;decode-coding-string result 'utf-8&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
  &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;when&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;or &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;null table&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;eq table 'onlyyo&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
    &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;let&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;((&lt;/span&gt;mres &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;yo-word word 'maybeyo&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;
      &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;when&lt;/span&gt; mres &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;cons 'maybe mres&lt;span style="color: rgb(105, 105, 105);"&gt;)))))))&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defun&lt;/span&gt; &lt;span style="color: rgb(139, 35, 35);"&gt;yofy-region&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;begin end&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
"&lt;span style="color: rgb(0, 139, 0);"&gt;Yofy the region.&lt;/span&gt;"
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;interactive "&lt;span style="color: rgb(0, 139, 0);"&gt;r&lt;/span&gt;"&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;save-restriction&lt;/span&gt;
  &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;save-excursion&lt;/span&gt;
    &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;narrow-to-region begin end&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
  &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;beginning-of-buffer&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
  &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;let&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;current-e-word current-yo-word&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
      &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;while&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;re-search-forward yo-e-word-regexp nil t&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
        &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;save-match-data&lt;/span&gt;
          &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;setq current-e-word
                &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;downcase
                 &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;replace-in-string
                  &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;match-string 0&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; yo-cutting-regexp ""&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;
          &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;setq current-yo-word &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;yo-word current-e-word&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;

      &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;cond&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;((&lt;/span&gt;stringp current-yo-word&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
               &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;replace-match current-yo-word nil&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
              &lt;span style="color: rgb(105, 105, 105);"&gt;((&lt;/span&gt;and &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;consp current-yo-word&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
                    &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;eq &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;car current-yo-word&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; 'maybe&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
               &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;setq current-yo-word &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;cdr current-yo-word&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
             &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;if&lt;/span&gt; search-highlight
                   &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;isearch-highlight &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;match-beginning 0&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;match-end 0&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;
               &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;when&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;y-or-n-p &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;format "&lt;span style="color: rgb(0, 139, 0);"&gt;\"%s\" --&amp;gt; \"%s\"? &lt;/span&gt;"
                                       current-e-word current-yo-word&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
               &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;undo-boundary&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
               &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;replace-match current-yo-word nil&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
             &lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;isearch-dehighlight&lt;span style="color: rgb(105, 105, 105);"&gt;))))&lt;/span&gt;
      &lt;span style="color: rgb(105, 105, 105);"&gt;))))&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defun&lt;/span&gt; &lt;span style="color: rgb(139, 35, 35);"&gt;yofy-buffer&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;()&lt;/span&gt;
"&lt;span style="color: rgb(0, 139, 0);"&gt;Yofy whole buffer.&lt;/span&gt;"
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;interactive&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;yofy-region &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;point-min&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;point-max&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;

&lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;defun&lt;/span&gt; &lt;span style="color: rgb(139, 35, 35);"&gt;yofy&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;()&lt;/span&gt;
"&lt;span style="color: rgb(0, 139, 0);"&gt;Yofy region or buffer.&lt;/span&gt;"
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;interactive&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;&lt;span style="color: rgb(139, 0, 0);"&gt;if&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;region-active-p&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt;
    &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;yofy-region &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;region-beginning&lt;span style="color: rgb(105, 105, 105);"&gt;)&lt;/span&gt; &lt;span style="color: rgb(105, 105, 105);"&gt;(&lt;/span&gt;region-end&lt;span style="color: rgb(105, 105, 105);"&gt;))&lt;/span&gt;
&lt;span style="color: rgb(105, 105, 105);"&gt;  (&lt;/span&gt;yofy-buffer&lt;span style="color: rgb(105, 105, 105);"&gt;)))&lt;/span&gt;
&lt;/pre&gt;  Кладём &lt;a href="http://lgarc.narod.ru/sxemacs/yo.db"&gt;базу слов (5.3M)&lt;/a&gt; в &lt;span class="pre"&gt;~/.sxemacs/&lt;/span&gt;, вставляем код в &lt;span class="pre"&gt;init.el&lt;/span&gt; и всё.  Теперь у нас появилась мощная команда - &lt;span class="pre"&gt;M-x yofy RET&lt;/span&gt;, которую вы можете забиндить на какую-нибудь кнопку. В моём случае она висит на &lt;span class="pre"&gt;C-m e y&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-7017845480857217557?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=d1beb26e140a609d&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/7017845480857217557/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=7017845480857217557' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/7017845480857217557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/7017845480857217557'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/sxemacs_01.html' title='Быстрый ёфикатор для SXEmacs'/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4022155443158713503.post-5932825693299806674</id><published>2008-12-01T15:07:00.000+03:00</published><updated>2008-12-01T15:22:32.868+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rus'/><title type='text'></title><content type='html'>Открыт блог о &lt;a href="http://sxemacs.org"&gt;SXEmacs&lt;/a&gt; на русском языке.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4022155443158713503-5932825693299806674?l=sxemacsen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sxemacsen.blogspot.com/feeds/5932825693299806674/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4022155443158713503&amp;postID=5932825693299806674' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5932825693299806674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4022155443158713503/posts/default/5932825693299806674'/><link rel='alternate' type='text/html' href='http://sxemacsen.blogspot.com/2008/12/sxemacs.html' title=''/><author><name>lg</name><uri>http://www.blogger.com/profile/08003803875490377611</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
