MDN - Restore heading ids

  • /*
     * @title MDN - Restore heading ids
     * @description 翻訳してしまっている場合でも原文からコピーしてきて修復
     * @include https://developer.mozilla.org/ja/docs/*
     * @license MIT License
     * @javascript_url
     */
    
    // MDNの記事でheadingタグのidはtextContentから自動生成されているが、
    // 日本語版では見出しそのものは翻訳しつつもidは変えたくないのでname属性を足す
    // (name属性をつけておけばそっちがid属性にも反映される仕様)
    // c.f. https://github.com/mozilla-japan/translation/blob/master/MDN/TranslationHelper.user.js
    
    // で、見出しタグの数と並びがあっていれば一対一で対応する、と雑な処理をしてみるテスト。
    
    (() => {
      const execAll = function*(re, str, m = null) { while ((m = re.exec(str)) !== null) yield m; };
      const src_str = document.querySelector('.translate-source > textarea').textContent;
      const editor = CKEDITOR.instances[Object.keys(CKEDITOR.instances)[0]];
      const dest_str = editor.getData();
    
      const heading_re = /<h(\d) ([^ >]* +)?id="([^"]+)"(?: name="[^"]+")?>/g;
      const untranslated_re = /^[A-Za-z0-9_\-–;'\.\(\)&]+$/;
      const src_headings = [...execAll(heading_re, src_str)];
      const dest_headings = [...execAll(heading_re, dest_str)];
    
      const isSameHeading = (src, dest) => src[1] === dest[1] && (!untranslated_re.test(dest[3]) || src[3] === dest[3]);
    
      if (src_headings.length !== dest_headings.length ||
          src_headings.some((src, i) => !isSameHeading(src, dest_headings[i]))) {
        alert('見出しの構造が一致しないため中止します。');
        return;
      }
      if (src_headings.every((src, i) => src[3] === dest_headings[i][3])) {
        alert('全ての見出しで原文と同じidが指定されています。\n修正の必要はありません。');
        return;
      }
    
      let i = 0;
      const out_str = dest_str.replace(heading_re, (src, lv, other, id) => {
        const orig_heading = src_headings[i++][3];
        console.log(id + ' -> ' + orig_heading);
        // `'...'`.slice(1, -1) はHatena::Letのpacker対策
        return `'<h${lv} ${other || ''}id="${orig_heading}" name="${orig_heading}">'`.slice(1, -1);
      });
    
      editor.setData(out_str);
      alert('見出しのid/name属性を修正しました。\n詳細はコンソールを確認してください。');
    })();
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2018/08/24 00:23:20 - 2018-08-24
  2. 2018/08/24 00:10:07 - 2018-08-24