Cookpad Recipe Scalable Fork

  • /*
     * @title Cookpad Recipe Scalable
     * @description Cookpad Recipe Scalable
     * @include http://cookpad.com/recipe
     * @license MIT License
     */
    // TODO: 曖昧表現 (少々、適量、多め、好きなだけ等)
    (function() {
    
      // ----[main]-------------------------------
    
      var MULTI_NUMS = '0123456789'.split('');
      var DELICIOUS_REGEXP = /(肉|豚|ブタ|ぶた|牛|ビーフ|鳥|鶏|とり|トリ|バター|油|塩|しお|砂糖|さとう)/;
      var healthyLevel = 0;
      var byNum = 1;
      var html = [
        '<div id="operations">',
          '<h3>操作</h3>',
          '<div>',
            '<button id="healthier">ヘルシーに</button>',
            '<button id="delicious">うまそうに</button>',
            '<button id="clear">クリア</button>',
            '<input id="by" type="text" style="width:3em" />',
            '<button id="multiply">倍</button>',
          '</div>',
        '</div>'
      ].join('');
    
      $('div#operations').remove();
      $('div#ingredients').before($(html));
    
      eachIngredient(function(name, quantity) {
        $.data(quantity.get(0), 'original', quantity.html());
      });
      $.data($('span.servings_for').get(0), 'original', $('span.servings_for').html());
    
      multiplyIngredients(byNum);
      multiplyServingsFor(byNum);
    
      $('button#healthier').click(function() {
        healthyLevel++;
        multiplyIngredients((1 - healthyLevel*0.1)*byNum, DELICIOUS_REGEXP);
      });
      $('button#delicious').click(function() {
        healthyLevel--;
        multiplyIngredients((1 - healthyLevel*0.1)*byNum, DELICIOUS_REGEXP);
      });
      $('button#clear').click(function() {
        healthyLevel = 0;
        byNum = 1;
        multiplyIngredients(byNum);
        multiplyServingsFor(byNum);
      });
      $('button#multiply').click(function() {
        byNum = $('input#by').val();
        multiplyIngredients(byNum);
        multiplyServingsFor(byNum);
      });
    
      // ----[utility]-----------------------------------
    
      function eachIngredient(callback) {
        $('div.ingredient_row').each(function() {
          var name = $('div.ingredient_name', this);
          var quantity = $('div.ingredient_quantity', this);
          if(name.size() > 0 && quantity.size() > 0) callback(name, quantity);
        })
      }
      function multiplyIngredients(by, regex) {
        eachIngredient(function(name, quantity) {
          if(regex && !regex.test(name.html())) return;
          var orig = $.data(quantity.get(0), 'original');
          var conv = replaceNumber(orig, function(n) { return round(n*by) });
          //console.log(name.html() + ':' + orig + ' -> ' + conv);
          quantity.html(conv);
        });
      }
      function multiplyServingsFor(by) {
        var orig = $.data($('span.servings_for').get(0), 'original');
        var conv = replaceNumber(orig, function(n) { return round(n*by) })
        $('span.servings_for').html(conv);
      }
      function round(n) {
        return Math.round(n*100)/100;
      }
      function replaceNumber(text, callback) {
        text = text
          .replace(/[0-9]/g, function(s) { return String.fromCharCode(s.charCodeAt(0) - 65248);})
          .replace(/([0-9]+)分の([0-9]+)/g, function(a, f, s) { return s + '/' ; f })
          .replace(/半分?/g, '0.5')
          .replace(/./g, '.')
          .replace(///g, '/');
        text = text.replace(/(([0-9]+)( |\s|と))?([0-9\.\/]+)/g, function(all, add, addnum, addsym, num) {
          //console.log(all, add, addnum, addsym, num);
          var n = eval(num);
          if(add) n = n + eval(addnum);
          return callback(n);
        });
        return text;
      }
    })();
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2012/03/04 22:51:53 - 2012-03-04
  2. 2012/03/04 22:51:33 - 2012-03-04
  3. 2012/03/04 06:36:00 - 2012-03-04