niszetの日記

アナログCMOS系雑用エンジニアが頑張る備忘録系日記

ghcupでstackをinstallしたら stack upgradeしてはいけない

Pandocを見ているときに気づかぬうちにやっていたぽいね。

VSCodeでHLSがうまく動かないな…と思って調べていて気づいたのでメモ。 ただし、「HLSが動かないな…」と思っていたのは勘違いであったが、よく考えると一周回って勘違いじゃなくなったのでそれもメモ。

前提

実行環境はWin10+WSL2(Ubuntu18.04LTS)です。

HLSについてはこの記事が参考になります。VSCodeで動くHaskellIDEです。

https://zenn.dev/konn/articles/1a60baba9848a1

ghcupはHaskellインストーラです。ghc, cabal, hls, stack, ghcup(自身)をインストール、管理できます。

https://www.haskell.org/ghcup/

ghcupについてはこちらの記事が参考になります。

https://qiita.com/takayuki-uchida/items/07f0df29780ae2d6029b

ghcup set ...を使わないとインストールしてもバージョン切り替わらないな…という事があるので注意(ghcだけかも。あと記事には書いてある( 他のは自動で切り替わったので)

ghcup listでインストール済みのバージョンがリストで出るので確認しましょう。私はghcのバージョンが古いままだったのでhlsが動く最新に上げました。

f:id:niszet:20210719070620p:plain

VSCodeでHLSがうまく動いていないと思った理由は、適当なHaskellのライブラリを(Pandoc関係だけど)もってきて見ていた時に、マウスをかざしても何もpopupされなかったからでした。

今の理解では、VSCodeで編集(作成)するとHLSが正しく動き始めてライブラリ全体のファイルを見にいくような挙動をするので、読み込みだけしているとその処理がされないので一旦editして処理がはじまるのを待とう、ということになりました。

本題。

記事のタイトルはghcupでstackをインストールした際に出てくるメッセージをちゃんと見ようねっていうことですね。

!!! Additionally, you should upgrade stack only through ghcup and not use 'stack upgrade' !!!

stack upgradeすると、どうやら~/.local/bin/以下にstackが別途インストールされてしまう模様(私の環境では。which stackでどこにあるか確認してください)。で、ghcupの管理から外れてしまうのでやめましょうねという。

ghcupでインストールする場合は/home/niszet/.ghcup/bin/stackに入るはずです(私と同じ環境の場合)

最後にもう一つ。ghcupでインストールしたhlsを使い場合はVSCodeHaskell拡張の設定のServer Executable Pathにそのpathを書かないとダメです。

f:id:niszet:20210719072621p:plain

私の場合は/home/niszet/.ghcup/bin/haskell-language-server-8.10.5になります。

hlsはまだ9.0.xに対応していない?ようなので、recommendedのついている8.10.5とそれに対応したhlsのバージョンを指定して設定しましょう(bin/までの指定ではダメだった)

1時間くらい溶かしたので、覚書。やったことは書かないと忘れるので。

(R)fork版のrevealjsを一旦fixとした。

checkとかがまだwarning出てるけど。

一通り動作チェックして動くことを確認したので一旦fixとしてあとは使って問題あれば直す形でやっていこうと思う、forkしたrevealjsパッケージです。

github.com

これを本家にPR出しても良いのかもですが、本家はPRは小さい物だけがマージされていて、CRANも4年更新がなく、これと同様に新しいバージョンのreveal.jsに入れ替えようというPRもほったらかしになってるので、このリポジトリをベースに別のライブラリとして作ってしまった方が良いのではないかと思っています(メンテしたくないけど…

こういう場合のお作法ってどんな感じなんですかね?元がMITライセンスだからその旨明記してforkしたライブラリだよ~って書けばよいのかな。参考になる資料等ご存知の方、こっそり(こっそりじゃなくてもいいけど)教えてください…。

(Pandoc)--no-highlightオプションは--highlight-styleオプションを打ち消せない

明記されていないが仕様と思われる。

横着して、pandoc_argsでno-highlightを指定したらhighlightが残っていて気付いた。Pandocは--no-highlight--highlight-styleを同時に使用すると、highlight-styleの方が勝つようである。そのため、明示的に--no-highlightするだけでなく、--highlight-styleを与えない、ということもしないといけない。

マニュアルには明記されていないのでPandoc 2.14.0.3の挙動から判断。issueにも上がってない気がするのでとりあえず見なかったことにするが、あとで忘れるのでメモだけ残しておく。この状況にはまる人はほとんどいないと思うので。

(R)(Pandoc)revealjsでpluginを使う場合はself-containedをfalseにして使う理由

対策、対応できなくはないけどとてつもなく面倒くさいのでやらない。

色々調べてにっちもさっちもなのでメモ。

revealjsパッケージやrmarkdownパッケージ、その大本のPandocの仕様として、htmlなどのファイル形式に出力するときに使用するファイル、例えば画像などをhtmlファイル中に埋め込んで単一のファイルとしてリリースできるようにするオプション、--self-containedがある。

pandoc.org

これは確かに便利なのだけど、reveal.jsのpluginを使う上ではうまく動かず、なんとかしようと思ったけど面倒すぎるので対応しない理由を書いておきます。

base64エンコーディングされる

--self-contained指定したときの出力ファイルを見ればわかるように、画像などの外部データがよくわからない記号列によってあらわされている。これはbase64エンコードされているデータで、これは適当にbase64 デコードなどで検索して出てくるデコードするサイトに入れてデコードすれば元のデータが見える。データの切り出しの位置に注意。最後の==は不要だったりとか。

これは結局htmlファイル中に対象のファイルを取り込むことになるが、画像のようなバイナリデータではなくてjsなどのテキストデータは復号すれば元のファイルが読める。そのためか知らないが、reveal.jsのファイルは圧縮・難読化されたものを使用するようになっている。pluginなどは元のファイルもあるので、コードの理解をするならそっちを読むべし。

話がそれてきた。

結局、htmlファイル中にjsなどのファイルを取り込むということは、そのjsファイル中で外部のファイルを指示していたり、取り込むような動作をしている場合はファイルが見えなくなるので期待する動作にならない、というのが問題となる。これはブラウザで開発モードにしてコンソールを出すとエラーが表示されているはずで、そこにそれらしきエラーメッセージがあるだろう。こんな風に。

f:id:niszet:20210630105503p:plain

解決策としては、データを取り込むだけでよければ最終的にすべてのファイルがhtmlファイル中にいればよいであろう、ということで無理やり別の場所でcssファイルなどを取り込んでおく。

  <link rel="stylesheet" href="aaa_files/reveal.js-4.1.2/plugin/menu/menu.css">
  <link rel="stylesheet" href="aaa_files/reveal.js-4.1.2/plugin/menu/font-awesome/css/all.css">

ただし、元のjsで読みに行くcssファイルは存在しないのだからえらーはのこるし、その場所にたまたま同名のファイルがあるとそれを読みに行くので意図した挙動・表示にならない。

ということで、根治するにはplugin中のデータ取り込みの記述を切り出し、html中で別途指定する運用にしないといけないがそれではpluginをASISで使用できず、メンテナンスコストが爆増してしまう。

という諸々を踏まえ、fork版revealjsではpluginを使用する場合は--self-contained=falseをマスト指定とする。内部的に常にfalseにしていても良いかもしれないが、standaloneで使いたいシーンはあるだろうからそれはしない方が良さそう。

元々のバージョンもplugin使用時はfalse指定ねってことになってたようなので、方針踏襲ということになりますね。

yamlでの指定はこんな感じで。

output:
  revealjs::revealjs_presentation:
    self_contained: false

(R)revealjsパッケージがよしなにしていたことなど

素のreveal.jsを持ってくるだけではダメだったりする。

revealjsパッケージはpluginもいくつか同梱して対応していたようである。そのため、reveal.jsを持ってきて置き換えるだけでは足りない。ただし、pluginのディレクトリに入れるだけで良いので対応は簡単。

reveal.jsのプラグインについては本家のwikiが詳しい。

github.com

また、プラグインの中でもこのリポジトリにあるものは昔のrevealjsパッケージで使われていたものがたくさん入っているので良さそうである(wikiも一番上に書いてあるし)

github.com

ひとまず、chalkboard、embed-tweet、fullscreenを導入。embed-tweetは元々ははいっていないが、ツイ廃としては入れないといけないなと思って(ツイ廃ではないが)

github.com

また、menuプラグインも入れた。これも以前のバージョンに含まれていた。構成はかなり変わっているが、オーナーは同じ。pluginディレクトリにはmenuにリネームしておいてある。

github.com

一方で、multiplexやnote-serverなどは一旦見送ることとした。

github.com

Pandocのテンプレートも4年前から進歩している

まぁ、4年もあればね…

真偽値でない、文字列の場合は''で囲う必要があるが、これがPandocのテンプレート側で対処されている。revealjsパッケージでも対処していて、二重に'がついてしまうのでrevealjsパッケージ側の対応する箇所を削除した。これで今後Pandocの最新のテンプレートを持ってきて置き換えるだけで良いと考えている。

github.com

この修正の結果、reveal_optionsに指定することでどの変数にも値を入れることが出来るようになったはずである。たとえば下記のようにすれば、headingsのレベルによらずに横方向に順にスライドが表示されるようになる(これはreveal.jsのバージョンが古いと対応できないので本家のrevealjsパッケージでは出来ない)

output:
  revealjs::revealjs_presentation:
    theme: blood
    history: false
    reveal_options:
      navigationMode: linear

revealjsパッケージがわでのテンプレートのカスタマイズがある

Pandocのテンプレートをベースにしているようだが、Rで使ったときに見やすいようになのかいくつかの変更がされており、それを新しいバージョンのテンプレートにも持ってこないといけなさそう。たとえばスライドタイトルはPandocのそれをそのまま使うと大きすぎるという印象。

いつ時点の更新かは履歴で見れるのだが、それがなぜ入っているのかがわからないようなコード片もあるので、しばらくは適当にいじって挙動を見て良し悪しを決めることになりそうである。

思ったより手間がかかりそうで既にやる気が足らなくなりそうであるが…もう少しやってみる。

(Pandoc)revealjsのテンプレートに含まれる変数の一覧(仮)

-t revealjsの場合はhtml writerにrevealjsテンプレートを食わせているだけのはず

ということで、ひとまずデフォルトのテンプレートから、使われている変数を目の子で引き抜いてきた。足りていないものがあるかもしれない。 Pandoc 2.14.0.3のものである。あたまにforがついているものは、複数の値が指定できるもので、テンプレート中でもforによってそれぞれの値にアクセスしている。

lang
dir
for author-meta
date-meta
for keywords
title-prefix
theme
for css
math
for header-includes
for include-before
title
for title-slide-attributes/pairs
subtitle
for author
for institute
date
toc
toc-title
mathjax
for include-after

以下のものはユーザが指定するのではなく、Pandocによって生えてくるものと思われる(詳細は未チェック) table-of-contents
revealjs-url

また、以下のものはReveal.initialize中で使用されている変数である。revealjsの挙動を制御するために使われているので、使用しているreveal.jsのバージョンと合わせて確認が必要である。

  • controls
  • controlsTutorial
  • controlsLayout
  • controlsBackArrows
  • progress
  • slideNumber
  • showSlideNumber
  • hash
  • hashOneBasedIndex
  • respondToHashChanges
  • history
  • keyboard
  • overview
  • center
  • touch
  • loop
  • rtl

  • navigationMode
    Vertical Slides | reveal.js

  • shuffle

  • fragments
  • fragmentInURL
  • embedded
  • help
  • pause
  • showNotes

  • autoPlayMedia
    https://revealjs.com/media/#autoplay

  • preloadIframes

  • autoSlide
  • autoSlideStoppable
  • autoSlideMethod
  • defaultTiming
  • mouseWheel
  • display
  • hideInactiveCursor
  • hideCursorTime
  • previewLinks
  • transition
  • transitionSpeed
  • backgroundTransition
  • viewDistance
  • mobileViewDistance

以下のものはtrueの場合に記述が入り、falseの場合には入らないため挙動に不思議な点があれば確認すること。

parallaxBackgroundImage
background-image
parallaxBackgroundSize
parallaxBackgroundHorizontal
parallaxBackgroundVertical
width
height
margin
minScale
maxScale

列挙するだけでこれだけある。正しく使いこなすのは難しそうであるし、あまり凝りすぎたスライドは見やすくならないため注意が必要そうである。

追記

reveal.jsのconfigのページにある、Initializeの記述のうち、Pandocのテンプレートに含まれないものは下記のようである。

revealjs.com

autoAnimate
autoAnimateMatcher

  • autoAnimateEasing
  • autoAnimateDuration
  • autoAnimateUnmatched

https://revealjs.com/auto-animate/#animation-settings

  autoAnimateStyles: [
    'opacity',
    'color',
    'background-color',
    'padding',
    'font-size',
    'line-height',
    'letter-spacing',
    'border-width',
    'border-color',
    'border-radius',
    'outline',
    'outline-offset'
  ],

focusBodyOnPageVisibilityChange

一方、ifで記述をomitするような変数についてはこのページには記載がなかった。要調査。

再追記。

parallaxBack系の変数4つは下記のページに記載がある。

revealjs.com

size系はここにある。

revealjs.com

background-imageだけは見つからなかった。存在しないかもしれない。

parallaxBackgroundImage に与えるようである。しかしこの場合はparallaxBackgroundImageを指定しても無視されるので、両方のうちすくなくとも1つがenableだったら~に変えた方が良さそうでは?

さらに追記

reveal.jsの方のテンプレートはこれを参照した方が良さそう。

github.com

background-imageは検索するとreveal.scssにあるようであるが、ちゃんと指定できるのかは不明…。

github.com