粗大メモ置き場

個人用,たまーに来訪者を意識する雑記メモ

MarkdownをAsciidocに変換するKramdocまたはPandocをDocker環境で動かす

概要

  • Asciidocは便利できれいだがちょっと書きにくい
  • 書き慣れているMarkdownから変換する手法を試した
  • Dockerイメージを用いて以下のように変換可能。

Kramdoc版:

docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor kramdoc  --wrap=ventilate --format=GFM sample.md

または,Pandoc版:

docker run --rm -v $(pwd):/data pandoc/core:2.10 sample.md --to asciidoctor -o sample_pandoc.adoc

なお,筆者の環境はDocker on ubuntu20 on wsl2 on windows 10です。(ギャグっぽい)

はじめに

Asciidocは書きやすさとリッチな描写力を兼ね備えた便利なマークアップ言語です。

qiita.com

ossyaritoori.hatenablog.com


しかし,Latexはいざしらず超楽なMarkdownに慣れてしまうとなかなか文法を覚えて書くというのをしたくなくなります。


そこで,Markdownでさっと書いてそこからAsciidocの雛形を書くという方式を取るための手順をまとめてみます。

サンプルやソースについて

本記事で用いたサンプルやソースはこちら。

github.com

Markdown to Asciidoc

ざっと調べた感じ,Pandocを使うという人とKramdoc(Kramdown)を使うという人の2パターンあるようです。

サンプルに使うマークダウンファイルはこちら

Pandoc(新しいバージョンを使うことを推奨)

Jupyterで使われているはずなので多分Pandocが入っている人も多いと思います。

有名かつ有用なツールですが古いバージョンに関してはAsciidocの生成に関しては使い物にならないので注意です。Dockerなどで特定のバージョンを使える環境を用意したほうが良いと思います。

qiita.com

WSL,Docker環境がある前提で行けば下記のコマンドにてsample.mdファイルをsample_pandoc.adocファイルに変換できます。

pandoc/core

おそらくこちらが本来のバージョンです。こちらを使ったほうが引用がきれいになりそうです。

既存の問題としてこのままだとタイトルのレベルがずれるので別途タイトルを= タイトルのようにAsciidoc記法で書く必要があります。

wsl docker run --rm -v $(pwd):/data pandoc/core:2.10 sample.md --to asciidoctor -o sample_pandoc.adoc 

pandoc/latex:2.10 (非推奨)

Latexコンパイルに特化したイメージです。

wsl docker run --rm -v $(pwd):/data pandoc/latex:2.10 sample.md --to asciidoctor -o sample_pandoc.adoc

Kramdoc(On Docker)

一方で,Asciidocの開発寄りで作られているのがKramdocです。

github.com

Rubyで動くらしいので手元にRuby環境がある場合はgemでインストール出来ます。


自分はRuby使いでない&環境構築に興味がないのでDockerを用いていきます。

asciidoctor/docker-asciidoctor 環境でのKramdoc

DockerでAsciidoc環境構築をしたことがあるならばasciidoctor/docker-asciidoctorのイメージを落としている方も多いと思いますが,Kramdocは現状asciidoctor/docker-asciidoctor環境にインストールされているので新規インストールの問題がないのでこちらを使っていきます。

変換コマンドは以下のとおりです。

docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor kramdoc  --wrap=ventilate --format=GFM  sample.md

$(pwd)の所はコマンドプロンプトの場合"%CD%"でも動くとは思います。wsl2で動かしている方は先頭にwslをつけるのをわすれずに。

オプションについては下記を参照しました。つけなくてもそこまで支障があるわけではなかったですが念の為。

matthewsetter.com

html変換

adocファイルが出来たらhtml変換も同様に以下のコマンドで変換できます。

docker run --rm -v $(pwd):/documents/ asciidoctor/docker-asciidoctor asciidoctor <sample.adoc> -r asciidoctor-diagram -a allow-uri-read -a data-uri -a toc=left

このオプションとして以下を追記しています。

  • data-uri:画像など埋め込み
  • toc=left:目次を左に
  • asciidoctor-diagram:PlantUMLの図などを埋め込む

見た目はこんな感じになります。

f:id:ossyaritoori:20201016210600p:plain

まとめ

Asciidocは環境構築やら書き方やらちょっとハードル高いですが,Docker環境があれば結構気軽に使えると思います。

PandocとKramdocのどちらがいいか?に関してはまだ自分では結論が出ていませんが,どちらでも実用に耐えうるとは思っています。

  • Pandoc
    • 言わずとしれた万能コンバータ
    • リストまわりの挙動に不安。バージョンによって大きく挙動が変わるので要注意
    • 半角スペースで改行を入れられてしまうことがあるのはちょっといただけない
  • Kramdoc
    • きれいに変換できる。
    • リンクや特殊文字が絡むと微妙
    • 開発速度にちょっと期待しづらいか?

変換結果詳細比較

下記リポジトリにて変換結果とコマンドなどを載せているのでご参考までに。

github.com

バグ報告など

とりあえず,下記リポジトリにも書いていますが,いくつかバグがあったのでメモしておきます。

GitHub - YoshiRi/MarkdownToAsciidoc: Test project for markdown to asciidoc conversion

なお,Kramdocのバージョンは1.01でした。

>> wsl docker run --rm asciidoctor/docker-asciidoctor kramdoc --version
kramdoc 1.0.1

PHPシンタックスハイライトをつけようとするとエラーが出る

xmlのコメントを変換する機能でエラーがでる。以下がそのエラー文。

/usr/lib/ruby/gems/2.7.0/gems/kramdown-asciidoc-1.0.1/lib/kramdown-asciidoc/converter.rb:99:in `convert': undefined method `convert_xml_pi' for #<Kramdown::AsciiDoc::Converter:0x0000561a13adec28> (NoMethodError)
Did you mean?  convert_li

デバッグの結果以下が原因となった部分。

<?php if (is_tag()){ $posts = query_posts($query_string . '&showposts=20'); } ?>

バージョンによっては改善しているかもしれない。

リンク以降の改行がおかしい

  • 定義参照リンク以降の変換がバグる。
    • 定義参照リンクは別口で書くなどして対応するしか?

PandasのApply関数を使って新しい行を複数生成する

まとめ

つまるところExcelでよくやる既存の列から新たにデータ列を追加するというやつです。

  • ポイントを箇条書きにすると:
    • dataframeを引数に取る関数を作ってapply()関数に入れ,axis=1で処理
    • 2つ目以降の引数はargsで与える
    • 返り値を複数行で生成したいならresult_type="expand"にする
  • コードにすると:
    • df["newcolumn"] = df.apply(yourfunction,axis=1)
    • df[["newcolumn1","newcolumn2"]] = df.apply(yourfunction,axis=1,result_type="expand")

参考にした文献

pandas.pydata.org qiita.com

実践例

データを共有するのがだるいのでKaggleのノートブックで例を載せます。

Youtubeの概要と再生回数の関連に関するデータセットです。

Trending YouTube Video Statistics | Kaggle

地味にEncodingが厄介でした。

# load jp video data
import codecs
with codecs.open("/kaggle/input/youtube-new/JPvideos.csv", "r", "utf-8", "ignore") as file:
    df = pd.read_table(file, delimiter=",")
df.head()

ここから例えば適当にいくつか項を追加してみます。

# 高評価の割合などに関する項を追加

## ゼロ割防止
def save_divide(a,b):
    return a/b if b else 0
        
def add_likerate(df):
    likeperview= df["likes"]/df["views"]
    dislikeperview= df["dislikes"]/df["views"]
    likerate = save_divide(df["likes"],(df["likes"]+df["dislikes"]))
    return likeperview,dislikeperview,likerate

## copyして置換
newdf = df.copy()
newdf[["likeperview","dislikeperview","likerate"]] = df.apply(add_likerate,axis=1,result_type="expand")

newdf.head()

例えば高評価率をsort して吐き出して見ます。

import matplotlib.pyplot as plt

# sort
sorteddf = newdf.sort_values("likeperview")
sorteddf.plot.bar(y=["views"])

左から高評価が高い動画の再生数になりますが,こうしてみると予想通り高評価率と再生数はそこまで強く相関していなそうというのが読み取れます(要解析)。

f:id:ossyaritoori:20201003153345p:plain

numpyなどをちょっといじる程度ではMATLABExcelに利便性でかなわない感じがありますが,Pandasに習熟したら圧倒的にPythonのほうがやりやすい用に感じます。

おまけ

縦方向に似たようなことをするときのTipsです。

teratail.com

Python/Librosaを使ってAmazonで売ってるキーボード静音化リング(O-ring)の効果を検証してみた。

概要

  • カニカルキーボードの打鍵音を和らげたい
  • 1000円くらいのシリコン製のリングをキーボードにつけて静音化
  • どうせなのでPythonの音声処理ライブラリを使って効果を見てみる

使った機材など

  • キーボード:Keychron K2
  • 静音化リング
  • 撮影・音収集:Pixel 4

サイズ Cherry MX軸対応 静音化リング MXORDP

サイズ Cherry MX軸対応 静音化リング MXORDP

  • 発売日: 2014/09/02
  • メディア: Personal Computers

こんなふうに使います。

f:id:ossyaritoori:20200924232516p:plain
自分でも撮ったけどAmazonの商品紹介の写真が一番わかり易い

キーボード布教はこっち ossyaritoori.hatenablog.com




カニカルキーボードの静音化

カニカルキーボードはよくある他の方式のものと違って音が大きめに出る事が多いです。 後付でキーボードの打鍵音を改善するにはざっくりと3つの手法があるようです。

hbish.com

  1. 静音化リングをつける (所要10分)
  2. 潤滑油をさす (所要60分)
  3. 底に詰め物をする (要分解・所要120分)

2と3はきちんとした知識と装備を持って臨むべきですが初心者でも1の静音化リングの取り付けは直ぐにできます。

キートップを外して,裏の突起部分にリングをはめるだけです。

f:id:ossyaritoori:20200924233710p:plain
キートップを外した跡。この軸の色ごとに推し心地が違っており,「赤軸」などのように呼ばれます。

音がどんな感じに変わるのか

理論上,キートップが下の面に当たる底打ち音というのが低減されるらしいですがわからないのでスマホでShiftキー付近を押したときの音を録音して比較してみました。

f:id:ossyaritoori:20200924235405p:plain
うぉぉ!

リングなし(通常)

リング有り(施工後)

こうして聞くとカチャカチャとした甲高い音が減衰しているのがわかります。

ですがどの程度というのはよくわかりませんね。ということで評価パートに行きます。



Python/librosa を用いて定量的に評価

LibrosaというPythonのライブラリがあるので簡単に音声の解析ができそうです。

jorublog.site

使うライブラリは以下の通りです。

import sys
import scipy.io.wavfile
import numpy as np
import matplotlib.pyplot as plt
import librosa
import librosa.display

mp4からwavファイルの抽出

どうもmp4をそのまま読ませるよりもwavを読ませるといいみたいです。

幸いffmpegをインストールしていたので

ffmpeg -i hoge.mp4  -ac 2 -ar 44100 -vn hoge_audio.wav

のように変換します。

音声を取得して波形を見る

まずは波形を見ます。打撃音なのでなんとなくインパルス応答のような音になっているのがわかります。

なお,左右で微妙に音のタイミングがずれているので音速との関係からうまくやれば距離を測ることができそうです。

f:id:ossyaritoori:20200925000203p:plain
左:音全体の波形,右:一つの打鍵音にズームインした波形

コード

#音声ファイル読み込み 静音化なしの場合
wav_filename = "videos/shift_noring_audio.wav"
rate1, data1 = scipy.io.wavfile.read(wav_filename)
#縦軸(振幅)の配列を作成   #16bitの音声ファイルのデータを-1から1に正規化
data1 = data1 / 32768

#横軸(時間)の配列を作成  #np.arange(初項, 等差数列の終点, 等差)
time1 = np.arange(0, data1.shape[0]/rate1, 1/rate1)  
#データプロット
plt.figure(figsize=(12,4))
plt.subplot(1,2,1)
plt.plot(time1, data1[:, 0], label="Left channel")
plt.plot(time1, data1[:, 1], label="Right channel")
plt.legend()
plt.grid()
# 拡大 Plot
plt.subplot(1,2,2)
plt.plot(time1, data1[:, 0], label="Left channel")
plt.plot(time1, data1[:, 1], label="Right channel")
plt.legend()
plt.grid()
plt.xlim(39000/rate1, 40000/rate1)
plt.show() 

音波形を比較する

音の波形で比較してみましょう。 ただし,ここで問題になるのが音を鳴らしても必ずしも同じタイミングになるとは限らない点です。

f:id:ossyaritoori:20200925002302p:plain
一応これでも波形がおとなしめになった事がわかるといえばそうなのですが…

音の発生位置を特定

音の発生位置はOnsetと呼ばれるのでOnset detectionという問題になるようです。

musicinformationretrieval.com

音の開始地点(オンセット)の検出 - KIEFERworld -音楽情報処理研究所-

理論的な話は抜きにするとLibrosaではほぼ一行でこれを実行することが出来ます。

# Onset Frameの推定
onset_frames = librosa.onset.onset_detect(data1[:,0],rate1, wait=1, pre_avg=1, post_avg=1, pre_max=1, post_max=1)
print(onset_frames)

# 時間への変換
onset_times = librosa.frames_to_time(onset_frames)
print(onset_times)

# サンプルへの変換(こっちをよく使うかも)
onset_samples =librosa.frames_to_samples(onset_frames)
print(onset_samples)

これで

発生位置をあわせて比較

最初の波の立ち上がり部分で比較をします。 波形を見てもこの通り,差があることがわかります。

f:id:ossyaritoori:20200925004726p:plain
最初の波の立ち上がりを重ね合わせた結果がこれです。

コード

onset1=librosa.frames_to_samples(librosa.onset.onset_detect(data1[:,0],rate1, wait=1, pre_avg=1, post_avg=1, pre_max=1, post_max=1))
onset2=librosa.frames_to_samples(librosa.onset.onset_detect(data2[:,0],rate1, wait=1, pre_avg=1, post_avg=1, pre_max=1, post_max=1))

winlen = 800
    
#figure
plt.figure()
plt.plot(data1[onset1[0]:onset1[0]+winlen,0],label='w/o ring')
plt.plot(data2[onset2[0]:onset2[0]+winlen,0],label='w ring')
plt.legend()
plt.grid()

周波数領域(FFT)で比較

先程までは時間領域で見てきましたが,FFTで周波数領域を見るのも鉄板でしょう。 Librosaに関数があるはずですが,ひとまずScipyにて書いてみました。

余談ですがmatlabFFT関数はかなり使いづらかった記憶がありますが今はもっと良くなったのでしょうか。

コード

##### 周波数成分を表示する #####
def showfft(data,rate):
    #縦軸:dataを高速フーリエ変換する(時間領域から周波数領域に変換する)
    fft_data = np.abs(np.fft.fft(data))    
    #横軸:周波数の取得  #np.fft.fftfreq(データ点数, サンプリング周期)
    freqList = np.fft.fftfreq(data.shape[0], d=1.0/rate)  
    #データプロット
    plt.plot(freqList, fft_data)
    plt.xlim(0, 8000) #0~8000Hzまで表示
    plt.show()
    return [freqList, fft_data]


# 図示
plt.figure()
plt.plot(freqList1,fft_data1,alpha = 1,label="w/o ring")
plt.plot(freqList2,fft_data2,alpha = 0.5,label="w/ ring")
plt.xlim(0, 8000) #0~8000Hzまで表示
plt.xlabel("Freq [Hz]")
plt.ylabel("Magnitude")
plt.legend()
plt.grid()


以下の図の通り,2000Hz付近の音が大きく減衰していることがわかります。撮ったときの距離が若干ことなる可能性はありますが他の波形との関係性から概ね静音化に成功したと見て良さそうです。

f:id:ossyaritoori:20200925002359p:plain
青:Before,黄色:After

まとめ

カニカルキーボード,買おう。そして静音化しよう。

HHKBやNizは初手で買うにはちょっと高いのでRK61あたりから始めてもいいのかなと思います。

音声処理に興味を持った方は音声処理x本ノックを見てみてもいいかも。

github.com

おまけメモ空間

  • 最初音を区切るのに包絡線を用いようとしていた。
    • ヒルベルト変換を用いた包絡線抽出はScipyで簡単にできる。
    • かなりきれいにとれるが,ここからひとまとまりの音として区切りを推定するのに困った。(TODO)
# 1.包絡線をヒルベルト変換から得る
# https://org-technology.com/posts/Hilbert-transform.html

hdata1=scipy.signal.hilbert(data1[:,0])
hdata2=scipy.signal.hilbert(data2[:,0])

f:id:ossyaritoori:20200925003012p:plain

  • Spectrometerでの比較
    • よくみる図としてSpectrometerがある。
    • カラーマップとスケールを合わせればこの図でも比較できそう
    • 超余談だがこの画像をCNNに打ち込んでどうこうしようという系の論文はあまり好きではないです

f:id:ossyaritoori:20200925003829p:plain
こういう図よく見ますよね。

Spectrometer図示コード

def showspectro(data,rate):
    # フレーム長
    fft_size = 1024                 
    # フレームシフト長 
    hop_length = int(fft_size / 4)  


    # 短時間フーリエ変換実行
    amplitude = np.abs(librosa.core.stft(data, n_fft=fft_size, hop_length=hop_length))

    # 振幅をデシベル単位に変換
    log_power = librosa.core.amplitude_to_db(amplitude)

    # グラフ表示
    librosa.display.specshow(log_power, sr=rate, hop_length=hop_length, x_axis='time', y_axis='hz', cmap='magma')
    plt.colorbar(format='%+2.0f dB')  
    plt.show()

Python2と3が共存しているときにpipに特定のパッケージをインストールさせる(ROS+Jupyter)

Python2と3が共存する状況

大原則としてPythonは仮想環境をたてて環境をかっちり分けたほうがいいです。 また,2系も今後は廃れるので早々に抜けたほうが良いです。

その上で,ROS1を使っている場合,強制的に2.7を使う羽目になり,ROS2も入れている場合どちらも存在する,なんてことになりがちです。

今回は

  • Python(2.7)とPython3が入っているROS環境
  • pipでPython2またはPython3に特定のパッケージを入れたいという状況を説明します。

解決策

pipではなく,python -m pipを利用する。 これだけです。

  • 2系に入れたい時は,python -m pip install xx
  • 3系に入れたい時は,python3 -m pip install xx

でOKです。

余談:Jupyter ROS

以下のJupyterROSのインストール時に明確にこの問題を意識しました。今日はとりあえずツールの紹介だけとします。

github.com

Autohotkeyを用いてWindowsでUS配列キーボードをJIS配列設定で使えるようにする(US->JIS)

概要

  • AutoHotKeyのキーマッピング機能を用いてUSキーボードを使った際,
  • PCの設定をJIS配列のままUSキーボードとして動作させる
  • ノートPCのJISキーボードも比較的違和感なく使える上,起動/Shutdownが簡単

問題意識

魅力的なキーボードにはUS配列のものが多いです。 イカしたキーボードを買ったらちゃんと使いたいという話になります。

ただ,USキーボードをJIS配列のノートPCに正しく読ませようとすると,レジストリを書き換えて再起動するうえ,ノートPCの配列もUSキーボードになってしまいます

いろいろな解決策が考えられてきていますが,どれもあまり本質的な解決にはなっていません。

qiita.com


そこで今回の問題意識としては

  • ノートPCの入力を変更せず,再起動もしないで
  • USキーボードを自然に使えるようにする

というのをめざします。

AutoHotKeyを用いたキーリマッピング

今回はキーリマッピングツール,すなわちソフトウェア上でキーボードの入力を擬似的に変換してUSキーボードを正しく使えるようにします。

www.autohotkey.com

上記のサイトからexeファイルを落としてきて,Express Installでポチポチしていけばすぐにインストールが完了します。

ustojis.ahkファイルの作成

AutoHotkeyでは拡張子ahkのファイルに格納したコマンド形式でキーのマッピングを規定します。 X::send,YとすればXキーを押したときにYと入力を変換するわけです。

したがってJIS配列で認識されたUSキーボードの入力結果を無理やりUSキーボードで想定される入力にremapするように設定を書けば良いです。

とはいってもいちいち作るのは面倒だと思うので以下に作っておきました。 これを適当な名前us2jis.ahkとでもしてAutoHotkeyのインストールフォルダに入れておきます。

概してC直下,Program Filesの中にあると思います。

*"::send, @
*&::send, {^}
*'::send, &
*(::send, *
*)::send, (
*+0::send, )
*=::send, _
*^::send, =
*~::send, {+}
*@::send, [
*`::send, {{}
*[::send, ]
*{::send, {}}
*]::send, \
*}::send, |
*+::send, :
+*::send, "
*vkBA::send, '
VKF4::send, {``}
+VKF4::send,{~}

ahkファイルの実行

ahkファイルを実行して起動するのは簡単で,先程作ったahkファイルをダブルクリックすればいいです。

いちいち探すのが面倒な人はショートカットをデスクトップに作るなりするともっと捗ると思います。

実行されているかどうかは,右下のバーから以下の様な「H」のアイコンが出ているかで確認できます。

f:id:ossyaritoori:20200916004651p:plain

ahkマッピングの停止

どうしてもノートPCのキーボードを使いたいなどの場合に停止するには,先程の「H」を探して右クリックからExitを押せばOKです。

しかし,USキーボードの配置さえ覚えていればノートPCのJISキーボードでもそれなりに違和感なく使えます。

「Alt+チルダ」 の全角半角切り替えが面倒かと思いきや,変換無変換などのJISキーボード固有のキーはマッピングされないままなので下手にレジストリを変えるより使いやすかったりします。

拡張:Ctrl+Spaceを全角半角に割り当てる

全角半角の切り替えって結構遠い位置にあるので押すのがなかなか面倒くさくなってしまいます。

そこで 片手でぽんと押せるのがCtrl+Spaceという配置です。

以下の記述を参考にしました。

Shiftは+,Controlは^,Altは!で示されるようで,他の記法を受けつけなかったのでハマりました。。参照

^Space::Send, !{vkF3sc029}

また,CapslockをControlに反映するなどの設定もお手の物です。

Capslock::send, Ctrl
sc03a::send, Ctrl

追記:Capslockのマッピングは意図しない動作をもたらす可能性があります。(Ctrlが押しっぱなしになるなど)
自分の時は左右のCtrlを同時押しでことなきを得ました。ご注意。

キーボードがCtrlキーが押されたままのような状態になっています。 -キ- その他(パソコン・スマホ・電化製品) | 教えて!goo

USキーボード,買おう

雑に言ってUS配列のキーボードはコーディングがしやすい配置になっています。(アスタリスクチルダは結構打ちにくいところにある印象ですが) JISキーボードよりも世界的には一般的なのでいいデザインのものがお安く買えたりするわけですね。

カニカルなUSキーボードでも1万円程度出せば結構快適なものが買えるので是非使ってみてください。USキーボードはいいぞ,買おう

ossyaritoori.hatenablog.com

Pythonで文章整形(改行除去)DeepL翻訳の流れを自動化させてみる

会社のプロキシを通すと諸々のサービス繋げなくて困るねという話です。

概要

  • PythonをつかってShaperの機能を代替
  • DeepLに翻訳を投げて結果を取得する機能も追加
  • プロキシなどの成約で特定のサイトにアクセスできなくてもきちんと翻訳できる!

DeepLはまだスクレイピング行為を明確に禁止していない用に見えますが,あんまり望んでいないとは思います。有料API売ってるくらいなので。

DeepL翻訳を使った高速英文読解

Google翻訳やみらい翻訳と並びDeepLは精度も良く使い勝手も結構良い翻訳サービスです。

ただ,PDFから変換する際には変にはいる改行などを除去する一連の作業が必要になります。

koovet.com

この際のShaperというサイトにアクセスできなかったためPythonスクリプトを書いたのが始まりです。

なお,DeepLもGoogle翻訳も便利なChrome拡張機能があるので自宅用にはあまり必要ないプログラムな気がします。

1. TKinterを用いたGUI文章整形

整形手法は

  • ボックスの中のテキストをCopy
  • 改行と改行前のハイフンを削除して変わりにSpaceを代入

とします。クリップボードツールとしてpyperclipのインストールが必要です。

import tkinter as tk
import pyperclip
import re

# 行末のハイフンと改行を削除
def shaping(txt):
    lines = re.split("\n\r",txt)
    output = ""
    for line in lines:
        if line:
            if line[-1] == "-":
                output += line[:-1] + " "
            else:
                output += line + " "
    return output

root = tk.Tk()
# 入力を取得
def retrieve_input():
    inputValue=textBox.get("1.0","end-1c")
    shaped = shaping(inputValue)
    # copy to clip board
    pyperclip.copy(shaped)
    print("Copied ",len(shaped),"charactors!")


# delete box
def deletebox():
    textBox.delete(1.0, tk.END)

# Create GUI
textBox=tk.Text(root, height=40, width=40)
textBox.pack()
buttonCopy=tk.Button(root, height=1, width=10, text="Copy", 
                    command=lambda: retrieve_input())
buttonClear=tk.Button(root, height=1, width=10, text="Clear", 
                    command=lambda: deletebox())

#command=lambda: retrieve_input() >>> just means do this when i press the button
buttonCopy.pack()
buttonClear.pack()

tk.mainloop()

Copyボタンを押すことで整形された文章がクリップボードに残るのでそのままDeepLのサイトにペーストします。 ボタン横に並べろとかいろいろありますが,とりあえずMinimal Effortで作成しました。

2. Seleniumを用いた翻訳取得

残りの部分は下記の手順で出来ました。

必要なのは

  • Seleniumのインストール
  • Chromedriverのインストール

です。

qiita.com

ただ,煩雑な割には得るものは少なかった印象です。

具体的な動作としてはコードを走らせるとChromeが立ち上がって,そこでの操作をPython経由で送受信しているのであまり工程省略できている感じはしません。

f:id:ossyaritoori:20200910235529p:plain
後ろで結局Chromeが立ち上がっちゃうのであんまり自動化している感じはしない。

まとめ

拡張機能使えないってなんやねん

依存パッケージインストール

pipを許容するなら以下のように簡単です。

pip install pyperclip selenium chromedriver-binary
  • chromedriver binary install

非常にだるいですがChromeDriverはChromeのバージョンに合わせなくてはいけません。

qiita.com

pip install chromedriver-binary==85.0.4183.87.0

コード

  • これは正直あんまりエレガントではないです。
import tkinter as tk
import pyperclip
import re
from selenium import webdriver
import time
import chromedriver_binary

# Scraping part
load_url = "https://www.deepl.com/ja/translator"
driver = webdriver.Chrome()  #  driver = webdriver.Chrome("c:/work/chromedriver.exe")
driver.get(load_url)


# send translation request
def translate(txt):
    input_selector = "#dl_translator > div.lmt__sides_container > div.lmt__side_container.lmt__side_container--source > div.lmt__textarea_container > div > textarea"
    driver.find_element_by_css_selector(input_selector).send_keys(txt)
    while 1:
        Output_selector = "#dl_translator > div.lmt__sides_container > div.lmt__side_container.lmt__side_container--target > div.lmt__textarea_container > div.lmt__translations_as_text > p > button.lmt__translations_as_text__text_btn"
        Outputtext = driver.find_element_by_css_selector(Output_selector).get_attribute("textContent")
        if Outputtext != "" :
            break
        time.sleep(1)
    print(Outputtext)
    pyperclip.copy(Outputtext)


# 行末のハイフンと改行を削除
def shaping(txt):
    lines = re.split("\n\r",txt)
    output = ""
    for line in lines:
        if line:
            if line[-1] == "-":
                output += line[:-1] + " "
            else:
                output += line + " "
    return output

root = tk.Tk()
# 入力を取得
def retrieve_input():
    inputValue=textBox.get("1.0","end-1c")
    shaped = shaping(inputValue)
    # copy to clip board
    pyperclip.copy(shaped)
    print("Copied ",len(shaped),"charactors!")

def copyandtranslate():
    retrieve_input()
    translate(pyperclip.paste())

# delete box
def deletebox():
    textBox.delete(1.0, tk.END)

# Create GUI
textBox=tk.Text(root, height=40, width=40)
textBox.pack()
buttonCopy=tk.Button(root, height=1, width=10, text="Translate", 
                    command=lambda: copyandtranslate())
buttonClear=tk.Button(root, height=1, width=10, text="Clear", 
                    command=lambda: deletebox())

#command=lambda: retrieve_input() >>> just means do this when i press the button
buttonCopy.pack()
buttonClear.pack()

tk.mainloop()

Bug Fix

TODO

  • Chromedriverがプロキシで入らなそうな雰囲気があるので対策を考える
  • ウィンドゥがバックグラウンドで開かないようにしたい
  • 見た目の洗練(優先度低)

WSL2上のDockerを用いてAsciidocの文書,スライドを書く

9/6 メモ吐き出し。

3行まとめ

  • WSL2上で動かすDockerはいいぞ
  • Windowsだと設定が面倒なAsciidocも簡単に使えるぞ

ということです。

Docker on WSL2はいいぞ

自前の環境を汚さずになにか作業したい場合,Dockerは非常に便利なツールです。

WSL1やDOSネィティブの環境でDockerを使おうとした場合,従来はHyper-Vが必要(Windows Homeでは無理)だったのですが,WSL2のUbuntu環境を立てることで,Ubuntu上でaptからDockerをインストールできます。

qiita.com

Docker on Windowとの比較としては

  • CLIですべてやりたいことができる
  • コマンドプロンプトからでもwsl <Linuxのコマンド>とやればWSL2のコマンドを実行できるので文法の違いに困らない

というのがあります。

例えばDockerの-vオプションなどで現在のフォルダ名を教える時,以下のような違いがあってちょっと困りますがそういった違いをあまり気にせずに良くなります。

Ubuntu上でaptを用いたりDockerで構築した環境をWindowsから簡単に流用できるというのが非常に使い勝手が良いと感じます。

なぜAsciidocを使うのか

AsciidocとはMarkdownのようなマークアップ言語で,Latexのようにコンパイルをはさみはしますが,整った文章を生成することが出来ます。

f:id:ossyaritoori:20200906015726p:plain
こんな見た目

一時期話題になったAWSの講義資料なんかもAsciidocで書いてあると思われ,非常に美しい体裁となっているのがわかります。

tomomano.gitlab.io

利点は大体ここに書いてあります。

qiita.com

Asciidoc文章の所感

下記の参考文献にもあるが表現力と記述の簡略性を鑑みると

という関係にあります。要はLatexほど面倒には書かずにMarkdownに書けない文章を書くということを目指します。

今の所特に顕著に差があるのは,

などだと思います。

Asciidoc スライドの所感

Deck.jsやRevealjsにも対応しているのでAsciidocの文章はスライド形式にもすることが出来ます。

asciidoctor.org qiita.com

自分はあまりRevealjsにピンとこなかったので簡易スライド作成手段としてはまだMarkdown&Marpが使いやすいと思っていますが, Asciidoc文章をシームレスにプレゼン資料に変更できるのは十分に有用であるとは認識しています。

ossyaritoori.hatenablog.com

Asciidoc を使う

今回はDocker推しですが簡単な文章ならVSCode拡張機能でも使えます。

qiita.com

一部図表や,数式の記述にパッケージのインストールが必要になるためここではDocker上で文章を書く方法について書きます。

Asciidocのイメージをインストール

正式な方法もあるでしょうが,最新版が単純にほしければ一度走らせようとするだけでOKです。

docker run -it --rm asciidoctor/docker-asciidoctor 

github.com

これで環境がたつので例えばUbuntuからあるディレクトリにあるファイルをコンパイルするには

docker run -it -v <your directory>:/documents/ asciidoctor/docker-asciidoctor asciidoctor <sample.adoc>

とすればhtmlに変換されたドキュメントが生成されます。

asciidoctor-pdfというコマンドを使えばPDFも作れますが,あんまりきれいではないのでhtmlのままにしてブラウザの印刷機能で印刷をかけることが自分は多いです。

先程のコマンドをコマンドプロンプトから走らせようとすると

wsl docker run -it -v $(pwd):/documents/ asciidoctor/docker-asciidoctor asciidoctor sample.adoc

となります。簡単でしょう?

Revealjsのプレゼン資料を作る

この辺はまだ自分でも調査中です。

恐らくスタンダードな見た目にしようとしたら以下のような感じになると思われます。

wsl docker run -it -v $(pwd):/documents/ asciidoctor/docker-asciidoctor asciidoctor-revealjs -a revealjsdir=https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.9.2 slide_sample.adoc

f:id:ossyaritoori:20200906021809p:plain
シンプルで動きのあるスライドが作成できますが使い所が意外とない。

Gitlab CIと連携して静的なページを作成する。

この辺の話です。正直以下の記述以上に今の自分で言えることはないですが紹介までに。

qiita.com

まとめ

文章作成系とDockerの相性はめっちゃいいと思います。

Pythonの解析のところでも書きましたが,ある特定の作業にしかその環境を使わない場合,Dockerを使ってやるが非常にコスパがいいです。

最近のお気に入りはROSのGUI環境をDockerでたてちゃうやつとかでしょうか。

Docker上でGUIのROS1/ROS2を一瞬でセットアップする方法 - Qiita

容量とメモリをそれなりに食うのと,今の所WSL2がPCデバイスを認識できていないのがネックと言ったところでしょうか。