読者です 読者をやめる 読者になる 読者になる

金魚亭日常

読書,ガジェット,競技プログラミング

BibTeX ファイルのデータを Jekyll で使う

結論としては,

JabRef -> YAML -> Ruby で整形 -> _data フォルダへ

という流れ.

プラグインを探す

_data フォルダに BibTeXファイルを入れてそれを直接使えるようにするやつを探したが,なさそうだった.

jekyll-scholar というのがあったが,なんか違うっぽかった.

github.com

YAML に変換する

BibTeX をいろいろ操作するのには bibtex-ruby という gem がある.

github.com

これでYAML に変換しよう,と思ったが,LaTeX のコマンドをHTML タグに変換するとこで詰まったので断念. \textit{}<i></i> に,---&mdash;に,など.

pandoc-ruby という,pandoc のラッパーがあったので使ってみたけど,\textit{}<emph></emph> になってしまったので,これも断念.

github.com

JabRef のCustom Export を使う

https://help.jabref.org/en/CustomExportshelp.jabref.org

HTML に書き出す

BibTeX ファイルを打ち込むのにはJabRefを使っていて,JabRef はHTML書き出し機能がある. 結構柔軟に書き出し形式をいじれて,コマンドラインからでも使えるので,これでHTMLにして,include することに.

ほぼこれでいけたのだけど,例えば発表年ごと,発表形式ごとに書き出す,とかをしようとしたら,BiBTeXファイルを分割するしかなさそうだったので,これも断念.

YAML に書き出す

Custom Export はエントリーごとに指定の書式で書き出す機能なので,YAMLとかにも書き出せる.

yaml.layout というファイルを作って,こんな感じに書く.

- entrytype: \entrytype
  author: \format[Authors( LastFirst, FullName, FullPunc, Semicolon, Semicolon , inf, EtAl= et al.)]{\author}
  title: \format[HTMLChars, Replace("---, &mdash;")]{\title}
  booktitle: \booktitle
  year: \year
  date: \date
  eventtitle: \eventtitle
  venue: \venue
  language: \language
  volume: \volume
  organization: \organization
  conferencesubtype: \conferencesubtype
  conferencetype: \conferencetype
  invited: \invited
  publicationid: \publicationid
  awarded: "\awarded"

書き出し時にタグへの変換とかはできているので,後はこれを整形してグループごとにする

yaml-groupby.rb

require 'yaml'
require 'date'

fn = ARGV[0]
d = File.read(fn, opt={:external_encoding => "utf-8"})
puts "Read #{fn}"
yml = YAML.load(d)

h = Hash.new{|h, k| 
  h[k] = Hash.new{|hh, kk| 
    hh[kk] = Hash.new{|hhh, kkk| 
      hhh[kkk] = Array.new()
    }
  }
}

yml.each do |e|
  date = e["date"]
  year = date.year
  if date.month < 4 then
    year -= 1
  end
  entrytype = e["entrytype"]
  eventtitle = e["eventtitle"]
  h[year][entrytype][eventtitle] << e
end
h.keys.each do |byyear|
  h[byyear].keys.each do |bytype|
    h[byyear][bytype].keys.each do |byevent|
      h[byyear][bytype][byevent].sort!{|a, b|
        a["author"] <=> b["author"]
      }
    end
  end
end

dir = File.dirname(fn)
fnout = File.basename(fn, suffix=".yaml") + "-grouped.yaml"
File.open(File.join(dir, fnout), "w") do |f|
  f.write(YAML.dump(h))
end

puts "Saved #{File.join(dir, fnout)}"

ソートがうまくできてない気がするけど,とりあえずこれでよいことにする.

これで,

{year => 
  {entrytype => 
    {event => [entry1, entry2, ...]    
    }
  }
}

という形式になったので,あとはこれを_dataに入れて,普通に使う.

<div id="publications">
  {% assign d = site.data.publications.publications-grouped %}
  {% for year in d %}
    <h3>{{ year[0] }}年度</h3>
    <h4>国内学会</h4>
    <ol>
      {% for event in year[1]["InProceedings"] %}
        {% for e in event[1] %}
        <li>
          {{ e.author }}.
          “{{ e.title }}”.
          {{ e.eventtitle }},{{ e.publicationid }}.
          {{ e.date }}.
          (
          {{ e.conferencesubtype }}
          {% if e.awarded != '' %}
            ,{{ e.awarded }}
          {% endif %}
          )
        </li>
        {% endfor %}
      {% endfor %}
    </ol>
  {% endfor %}
</div>

あとは,Rakefile に書いて終了.

desc "BibTeX -> YAML"
task :bib => "_data/publications/publications-grouped.yaml"

desc "BiBTex -> YAML by JabRef"
file "_data/publications/publications.yaml" => ["_data/publications/publications.bib"] do |t|
  system('java -jar "C:\Program Files\JabRef\JabRef-3.8.2.jar" -o _data\publications\publications.yaml,yaml -n _data\publications\publications.bib')
end

desc "YAML -> group_by year && entrytype && eventtitle"
file "_data/publications/publications-grouped.yaml" => ["_data/publications/publications.yaml"] do |t|
  system("ruby _data/publications/yaml-groupby.rb _data/publications/publications.yaml")
end