お待たさせ致しました!

ウニ

洋野町(旧種市町)と言ったら「ウニ」しかも、今が「」。
そして、漁協にお願いして、大漁に入荷!
でも、これって早い話、「お中元」なんだよね〜。
1パック1kgで計11kg!(黒豆の価値なぞ問題外!!)
なんつったって三陸のウニ、東京に持っていったら、数十万で売れる代物か?!

同じ町のウニでも、えさの昆布、流れ込む川や、ミネラルの含み具合で味も大きく変わる。
今なら電話で直送してくれるかな?小子内浜漁協!
(ちょっとだけ、認知度に貢献。俺には仕事をくれない町内だけど。町の貢献のために)


これを、親戚やらそこいら辺に配る。
そして、なんとこれを先日のお詫びもこめて、宮城県の白石まで配る。
晩御飯に間に合わせるため、時速?km/hでがんばる。
なんと往復700キロとなる、とんぼ返り。
きっと豪華な夕食になったことだろう〜。


そしてこれが、我が家の分。


そしてこれが、俺の朝食!(超豪華!)
その辺のお店で頼むと、表面だけ綺麗な盛り付けでですが、そこはガッツり敷き詰め(?)

(糖尿の人には最悪だってさぁ!?)

日ごろお世話になっている皆様に、食べさせることができないのが、とても
「残念!」(意味も無くウニ色で・・・)
その意もこめ、感謝して頂きました。


そうそう帰る途中で立ち寄った、菅生サービスエリアで、オフ会で集まった(?)フェアレディーZの集団をパチリ。

そしてたまにはコードも書く。
formの要素から変数の値を抜き出してオブジェクトにする

// form の要素の値をオブジェクトにして返す。
var getFormValues = (function ( get ) {
  return function ( form ) {
    var es = form.elements;
    var result = [ ];
    var i, e, v;
    
    for (i = 0; e = es[i++]; )
      if ('undefined' === typeof result[e.name]) {
        if ('undefined' !== typeof (v = get (e)))
          result[e.name] = [v];
      }
      
      else {
        if ('undefined' !== typeof (v = get (e)))
          result[e.name].push (v);
      }

    for (i in result)
      if (result.hasOwnProperty (i))
        if (3 == result[i].length && /datet|day/i.test(i))
          result[i] = (v = result[i].join ('-'), '--' == v ? null: v);

        else if (3 == result[i].length && /time/i.test(i))
          result[i] = (v = result[i].join (':'), '::' == v ? null: v);

    return result;
  };
})(function (n) {
    var i = 0, ops, op, r = [ ];
    
    switch (n.type) {
      case 'text' : case 'hidden': case 'textarea': 
        return n.value || '';
      
      case 'radio': case 'checkbox':
        return n.checked ? n.value: undefined;
      
      case 'select-one':
        ops = n.options;
        while (op = ops[i++])
          if (op.selected)
            return op.value;
        return undefined;
      
      case 'select-multiple':
        ops = n.options;
        while (op = ops[i++])
          if (op.selected)
            r.push (op.value);
        return r.length ? r: undefined;
      
      default:
    }
  });
    • 日付の要素の扱い
<input type="text" size="4" name="theDay">年
<input type="text" size="4" name="theDay">月
<input type="text" size="4" name="theDay">日

のように、同じ名前の要素が3個あり、name の一部に "day"|"date" が含まれていると"年-月-日" の文字列で、1つにして返す

    • 時間の要素の扱い

同じ名前の要素が3個あり、name の一部に "time" が含まれていると"時:分:秒" の文字列で、1つにして返す

フォームから抜き出した値のオブジェクトを、SQL用に文字列にする
(スクリプトSQL文を送りつけるのは、好ましくないよ)

// オブジェクト変数を展開して、SQL用の文字列にする
var toStringForSQL = (function ( toSeries ) {
  return function (obj/*Object*/, excluded/*regexp*/, delimiter/*char*/) {
    var key, sql = [ ];
    
    if ('undefined' === typeof delimiter)
      delimiter = ',';
    
    for (key in obj)
      if (obj.hasOwnProperty (key))
        if ('undefined' === typeof excluded || !excluded.test(key))
          if (null == obj[key] || 'undefined' == typeof obj[key])
            sql.push (key + '=NULL');
          else
            sql.push (key + '="'+ toSeries (obj[key]).join (delimiter).replace (/(['"])/g,'\\$1')+'"');

    return sql.join(',');
  };
})(function (obj) {
     var result = [ ];
     
     (function (o) {
       var i, p;
       switch (typeof o) {
         case 'string': case 'number':
           return result.push (o + '');

         default:
           if (1 < o.length)
             for (i = 0; p = o[i++];)
               arguments.callee(p);
           else
             return result.push (o.toString ());
       }
     })(obj);

     return result;
   });
    • 使用例
var hoge = getFormValues (document.forms[0]); //フォームを指定
var sql = "UPDATE database.table SET "+ toStringForSQL (hoge, /^ID$/) + " WHERE ID=" + hoge.id;
var sql = "INSERT database.table SET "+ toStringForSQL (hoge, /^ID$/);
//除外したい要素の名前を正規表現で列挙

これは、章節抽出器の書きかけです

<!DOCTYPE html>
<title>章節抽出器T</title>
<style type="text/css">
body { background-color:#888; }
textarea { background-color:#999; }
</style>
<h1>TEST</h1>
<p><textarea rows="30" cols="100" id="outlines"></textarea></p>
<!--======================================================================-->

<hgroup>
  <h1 id="sg1">1. HTML 4.01 仕様書</h1>
  <h2>subtitle</h2>
</hgroup>

<h2 id="s1-1"><span>1.1.</span> <img alt="SGML と HTML の関係" src="dummy"></h2>
<h3 id="s1-1-1"><span>1.1.1.</span> SGML の概説</h3>
<h3 id="s1-2-2"><span>1.1.2.</span> HTML で用いられる SGML 構成素</h3>

<blockquote>
  <h1>in-blockquote section</h1>
  <h6>in-blockquote subsubsection6</h6>
  <h2>in-blockquote subsection</h2>
  <h3>in-blockquote subsubsection</h3>
  <h6>in-blockquote subsubsection6</h6>
</blockquote>

<h4><a name="name-s1-1-2-1"><span>1.1.2.1.</span> 要素</a></h4>
<h4><span>1.1.2.2.</span> 属性</h4>
<h4><span>1.1.2.3.</span> 文字参照</h4>
<h4><span>1.1.2.4.</span> コメント</h4>

<h3 id="s1-1-3"><span>1.1.3.</span> HTML DTD の読み方</h3>
<h4><span>1.1.3.1.</span> DTD コメント</h4>
<h4><span>1.1.3.2.</span> パラメータ実体定義</h4>
<h4><span>1.1.3.3.</span> 要素宣言</h4>

<h5><span>1.1.3.3.1.</span> 内容モデル定義</h5>
<h6><span>1.1.3.3.1.1.</span> シンタクス</h6>
<h4><span>1.1.3.4.</span> 属性定義</h4>
<h5><span>1.1.3.4.1.</span> 属性定義中の <strong>DTD 実体</strong></h5>

<h5><span>1.1.3.4.2.</span> 論理型属性</h5>
<h2 id="s1-1"><span>1.1.</span> <img alt="SGML と HTML の関係" src="dummy"></h2>
<h3 id="s1-1-1"><span>1.1.1.</span> SGML の概説</h3>
<h3 id="s1-2-2"><span>1.1.2.</span> HTML で用いられる SGML 構成素</h3>

<section>
  <nav>
    <h3>レベル 3 見出し</h3>
    <p><a href="/">Home</a></p>
  </nav>
  <p>Hello world.</p>
  <aside>
    <p>My cat is cute.</p>
  </aside>
  <h1>レベル 1 見出し</h1>
</section>



<script>

(function() {
  var
    outLine, section, stack,
    hash = {
      H1         : { type: 'heading', value: 1 },
      H2         : { type: 'heading', value: 2 },
      H3         : { type: 'heading', value: 3 },
      H4         : { type: 'heading', value: 4 },
      H5         : { type: 'heading', value: 5 },
      H6         : { type: 'heading', value: 6 },
      HGROUP     : { type: 'heading', value: 99 },
      
      ARTICLE    : { type: 'content' },
      ASIDE      : { type: 'content' },
      NAV        : { type: 'content' },
      SECTION    : { type: 'content' },
      
      BLOCKQUOTE : { type: 'root' },
      BODY       : { type: 'root' },
      FIGURE     : { type: 'root' },
      TD         : { type: 'root' }
    },
  //______________

    OutLiner = function ( root ) {
      this.root    = root;
      this.outline = extract( root );
    },
  
    Section  = function ( heading, parent ) {
      this.heading    = heading;
      this.children   = [ ];
      this.associated = [ ];
      this.parent     = parent;
    },
    
    OutLine = function ( node ) {
      this.element = node;
      this.children = [ ];
    },
  //______________

    // 要素を渡り歩く
    extract = function ( root ) {
      var tmp;
      var node = root;

      outLine = null;
      section = null;
      stack = [ ];

      while( true ) {
        node.tagName && enter(node); // 入口
        
        if ( node.hasChildNodes() )
          node = node.firstChild;
        
        else
          while (node) {
            node.tagName && exit(node); // 出口

            if (tmp = node.nextSibling) {
              node = tmp;
              break;
            }

            node = node.parentNode;

            if ( node == root )
              return outLine;
          }
      }
    },

 
    // 入口
    enter = function ( node ) {
      var top = stack[ stack.length - 1 ],
          np = hash[ node.tagName ] || { },
          tp = top ? hash[ top.tagName ] || { }: { },
          pvhd, // 1つ前
          tghd,
          tmp;
      
      if ( np.type === 'content' || np.type === 'root' ) { // 章節構造のタグならば
        if ( outLine ) {
          stack.push( outLine ); // outLine があれば、一時保存する

          if ( section.heading === null ) // ヌルということは、定義したばっかりなので未定義にする
            section.heading = undefined;
        }
        
        // 新規に outLine と section を関連付けて設定する
        outLine = new OutLine ( node );
        section = new Section ( null, outLine );
        outLine.children.push ( section );
      }
      
      else if (outLine === null); // 何も無いなら何もしない

      else if ('heading' == np.type && tp.value != 99) { // 見出し要素<h1>~<h6>なら
        pvhd = outLine.children[outLine.children.length - 1].heading;
        tghd = getHeadingLevel( node );
        
        if (section.heading == null) // heading が無いのなら、それをセクションの見出しとする
          section.heading = node;
        
        else if (pvhd == null || tghd <= getHeadingLevel( pvhd )) //今のnodeのheadingが、1つ前のより上位なら
          outLine.children.push( section = new Section( node, section ) );
        
        else {
          tmp = section;

          while ( tghd <= getHeadingLevel( tmp.heading ) )
            tmp = tmp.parent;

          tmp.children.push( section = new Section( node, section ) );
        }
        stack.push( node );
      }
    },
    
    
    // 出口
    exit = function ( node ) {
      var top = stack[ stack.length - 1 ];
      var np = hash[ node.tagName ] || { };
      var line;
      
      if (top === node)
        stack.pop();
      
      else if ('content' == np.type && stack.length > 0) {
        line = outLine;
        outLine = stack.pop();
        section = outLine.children[ outLine.children.length - 1];
        section.children.push(line);
      }

      else if ('root' == np.type && stack.length > 0) {
        line = outLine;

        outLine = stack.pop();
        section = outLine.children[ outLine.children.length - 1];

        while (section.children.length > 0)
          section = section.children[ section.children.length - 1];

        section.children.push( line )
      }

      else if ('content' == np.type || 'root' == np.type)
        section = outLine.children[0];

      
      section && section.associated.push (node);
    },



    // 見出しのレベルを返す
    getHeadingLevel = function (n) {
      var r, o = hash[ n.tagName ];
      if (99 == o.value) {
        for (r = 1; r < 7; r++)
          if (n.getElementsByTagName ('h' + r).length)
            return r;
        return 1;
      }
      return o.value;
    },
    
    
    // 前後の不正な文字を削除
    trim = (function (reg) {
      return function (text) {
        return text.replace (reg, '');
      };
    })(/^\s+|\s+$/g),
    
    
    // textContent(innerText) 画像、フォームの要素からも拾う
    getTextContent = function ( node ) {
      var result = [ ];
      var root = node;
      var tmp;
      
      while (true) {
        if (3 == node.nodeType)
          result.push (trim (node.nodeValue));

        else if ( 'IMG' == node.tagName )
          result.push (trim (node.alt));

        else if ( 'INPUT' == node.tagName )
          result.push (trim (node.value));
        
        if (node.hasChildNodes())
          node = node.firstChild;
        
        else
          while (true)
            if (tmp = node.nextSibling) {
              node = tmp;
              break;
            }
            else {
              node = node.parentNode;

              if( node == root )
                return result.join('') || '';
            }
      }
    },


    // 文字列化
    writeToString = function (division, level) {
      var result;
      var subresult;
      var padding;
      
      if (! level)
        level = 1;
      
      padding = new Array(level).join('\u0020\u0020') + '+ ';
      
      // section
      if ('heading' in division)
        result =
          division.heading
          ? [padding + getTextContent(division.heading).replace(/\s{2,}/g, '\u0020')]
          : (division.heading === null)
            ? [padding + '(' + division.parent.element.tagName + ')']
            : [],
        
        subresult = division.children.map(function(division) {
          return writeToString(division, level + 1);
        });
      
      // outline
      else if ('root' == hash[ division.element.tagName ].type)
        result = [padding + '[' + division.element.tagName + ']'],
      
        subresult = division.children.map(function(division) {
          return writeToString(division, Number(this));
        }, level + 1);
      
      // anonymous section
      else
        result = [],
        
        subresult = division.children.map(function(division) {
          return writeToString(division, level);
        });
      
      return result.concat(subresult).join('\n');
    };

  //___________

  // outline を文字列化
  OutLiner.prototype.toString = function () {
    return writeToString( this.outline );
  };
  
  // グローバル変数化
  this.createOutlineView = function (root) {
    return root ? new OutLiner (root): null;
  };

})();


var outline = createOutlineView( document.body );

document.getElementById('outlines').value = outline.toString();



</script>

教えてgoo(Javascript)の質問数が

しばらく、パソコンに近づくことがなかった。
ふと見れば、もう少しで、質問数が10000件になりそう。
記念すべきその時の質問は、愚問だろうなぁ〜。