<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Language" content="en" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Last-Modified" content="Sun, 26 Dec 2010 16:30:19 GMT" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta name="author" content="Office Blackboard" />
<meta name="generator" content="Tokyo Promenade 0.9.18" />
<meta name="robots" content="index,follow" />
<link rel="start" href="/2010/promenade.cgi" type="text/html; charset=UTF-8" title="the top page" />
<link rel="help" href="/2010/promenade.cgi?name=tp-help-en&amp;adjust=front" title="the help page" />
<link rel="alternate" href="/recent.atom" type="application/atom+xml" title="Atom feed of recet articles" />
<!--
<link rel="alternate" href="/2010/promenade.cgi?format=atom&amp;act=timeline&amp;order=mdate" type="application/atom+xml" title="Atom feed by modification date" />
<link rel="alternate" href="/2010/promenade.cgi?format=atom&amp;act=timeline&amp;order=xdate" type="application/atom+xml" title="Atom feed by comment date" />
-->
<link rel="alternate" href="/2010/promenade.cgi?format=atom&amp;id=8" type="application/atom+xml" title="(Atom feed of this article)" />
<link rel="stylesheet" href="/2010/promenade.css" type="text/css" />
<title>blog.8-p.info: sgml-match-mode.el</title>
</head>
<body class="ua_generic env_generic">
<div id="frame" class="frame_normal">
<div id="main" class="view_single">

<div class="article" id="article8">
<h1 class="attr ah0"><a href="http://blog.8-p.info/2010/8-sgml-match-mode-el" class="name">sgml-match-mode.el</a> <img src='https://chart.googleapis.com/chart?chs=40x40&amp;chd=t:0.575959,5.707227&amp;cht=p&amp;chp=4.084070' alt='23:54' /></h1>

<div class="attr">
  Posted at 2010/01/15 23:54,
  Modified at 2010/01/16 00:03
  </div>

<div class="text">
<p>いりくんだ XML や HTML で、とくに div が多かったりすると、どれがどれと対応しているかよくわからなくなるので show-paren-mode 風の minor-mode を書きました。</p>
<pre>(require 'easy-mmode)
(easy-mmode-define-minor-mode
 sgml-match-mode &quot;&quot; nil &quot; &gt;&lt;/&quot; nil)

(defvar sgml-match-show-timer
  (run-with-idle-timer 0.2 t 'sgml-match-show-on-idle))

(defvar sgml-match-overlay (make-overlay 0 0))

(defun sgml-match-show-on-idle ()
  (if sgml-match-mode
      (sgml-match-show-element)))

(defun sgml-match-overlay-move ()
  (let* ((context (car (sgml-get-context)))
         (s (sgml-tag-start context))
         (e (sgml-tag-end context)))
    (cond
     ((and
       (pos-visible-in-window-p s)
       (pos-visible-in-window-p e))
      (move-overlay sgml-match-overlay s e (current-buffer))
      (overlay-put sgml-match-overlay 'face 'highlight))
     (t
      (message &quot;%s&quot; (buffer-substring s e))))))

(defun sgml-match-overlay-hide ()
  (overlay-put sgml-match-overlay 'face nil))

(defun sgml-match-show-element ()
  (save-excursion
    (if (eq (car (sgml-lexical-context)) 'tag)
        (let* ((context (car (save-excursion (sgml-get-context))))
               (type (sgml-tag-type context)))
          (cond ((eq type 'open)
                 (sgml-skip-tag-forward 1)
                 (backward-char 1)
                 (sgml-match-overlay-move))
                ((eq type 'close)
                 (sgml-skip-tag-backward 1)
                 (forward-char 1)
                 (sgml-match-overlay-move))
                (t
                 (sgml-match-overlay-hide))) )
      (sgml-match-overlay-hide))))

(provide 'sgml-match-mode)
</pre>
<p>&lt;foo&gt; にカーソルをおくと対応する &lt;/foo&gt; が、逆に &lt;/foo&gt; なら &lt;foo&gt; がハイライトされます。今日書いたばかりなのでまだわからないですが、多分便利。</p>
</div>
<div class="comments" id="article8_comments">
<div class="meta">0 comments</div>
<form method="post" action="/2010/promenade.cgi" class="riddleform">
<dl class="riddleformlist">
<dt>riddle for guest comment authorization:</dt>
<dd>
<span class="question">Where is the capital city of Japan?</span> ...
<input type="text" name="umridans" value="" size="12" />
<input type="submit" value="answer" />
<input type="hidden" name="id" value="8" />
</dd>
</dl>
</form>
</div>
</div>
</div>
<div id="about">
  <p>
    <a href="/">blog.8-p.info</a> は
    <a href="http://8-p.info/me/">加藤和良</a> の個人的なブログで、プログラミングのはなしが多めです。
  </p>
</div>
</div>
</body>
</html>
