github profile(README.md)을 PDF로 변환하기
시작
마이다스 아이티 채용 지원서 작성을 하는 와중에 포트폴리오 파일을 업로드하게끔 되어있다. 네이버의 경우 내 github url을 입력할 수 있었는데 말이다. 그래서 github profile로 적었던 markdown을 포트폴리오로 제출하고 싶었는데, github profile을 쉽게 pdf로 변환하는 방법이 없을까 생각을 해봤다.
과정
우선, pandoc을 통해 markdown에서 pdf로 변경해보려고 했다.
docker hub에 pandoc/core와 pandoc/latex 2 가지 이미지가 있는데, 뭔 차이가 있는지는 모르겠다. (https://github.com/jgm/pandoc/blob/master/INSTALL.md#docker와 https://pandoc.org/installing.html#docker 에 다 나와 있었다)
일단, 2 가지 이미지를 모두 pull 받아서 다음과 같이 실행했다(/bin/bash는 안 먹힌다)
$ docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/core README.md -o output.pdf
pdflatex not found. Please select a different –pdf-engine or install pdflatex
$ docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/core README.md --pdf-engine=xelatex -o output.pdf
xelatex not found. Please select a different –pdf-engine or install xelatex
한글이 다 깨짐
$ docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/latex README.md --pdf-engine=xelatex -o output.pdf
[WARNING] Missing character: There is no 김 (U+AE40) (U+AE40) in font [lmroman12-bold]:mapping=tex- [WARNING] Missing character: There is no 지 (U+C9C0) (U+C9C0) in font [lmroman12-bold]:mapping=tex-
$ docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/latex README.md --pdf-engine=xelatex -o output.pdf
[WARNING] Missing character: There is no 김 (U+AE40) (U+AE40) in font [lmroman12-bold]:mapping=tex- [WARNING] Missing character: There is no 지 (U+C9C0) (U+C9C0) in font [lmroman12-bold]:mapping=tex-
이전에 docker image에 pandoc을 설치한 경험을 통해 local에 있는 ruby container에서 pandoc을 설치 및 실행시켜보고자 했다.
$ docker run -it --name=pandoc --volume "`pwd`:/srv" 8fe6e1f7b421 /bin/bash
ruby container에서 pandoc 설치 (참고 : https://github.com/hoonti06/dk-hoonti06.gitlab.io-env/commit/b375f6ada6196f52f2edcaf7d4fe4d40506ea5a1#diff-dd2c0eb6ea5cfc6c4bd4eac30934e2d5746747af48fef6da689e85b752f39557R15)
$ curl -o pandoc.deb -fsSL https://github.com/jgm/pandoc/releases/download/2.7.3/pandoc-2.7.3-1-amd64.deb && \
dpkg -i pandoc.deb && \
rm -f pandoc.deb
xelatex 관련 의존성 설치
apt-get -qq update && \
apt-get install texlive-xetex texlive-fonts-recommended texlive-latex-recommended
다시 시도했지만 한글이 다 깨짐
pandoc README.md --pdf-engine=xelatex -o output.pdf
markdown을 html로 변환 후, html을 pdf로 변환 시도하였지만 실패하여 파일 조차 생성 안됨(html은 한글까지 잘 나옴)
pandoc README.md -o temp.html
pandoc temp.html --pdf-engine=xelatex -o output.pdf
[WARNING] Could not convert image '/tmp/tex2pdf.-150905f53fd98563/2564ecca5ab28f434dea29b27542d596a5bf6e73.svg': check that rsvg-convert is in path. rsvg-convert: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory) [WARNING] Could not convert image '/tmp/tex2pdf.-150905f53fd98563/7c7823741f191b59bf57ac31848f96a98e8946c6.svg': check that rsvg-convert is in path. Error producing PDF. ! LaTeX Error: Cannot determine size of graphic in /tmp/tex2pdf.-150905f53fd985 63/2564ecca5ab28f434dea29b27542d596a5bf6e73.svg (no BoundingBox).
See the LaTeX manual or LaTeX Companion for explanation.
Type H
l.90 …4ecca5ab28f434dea29b27542d596a5bf6e73.svg}
다음과 같이 설치하면 위 rsvg-convert 에러는 안뜨지만, 한글을 제대로 인식 못한다
$ apt-get install librsvg2-bin
wkhtmltopdf을 설치하여 pdf engine으로 사용할 수 있지만, 한글만 잘 나오고 emoji는 안 나온다.
$ apt-get install wkhtmltopdf
$ pandoc README.md --pdf-engine=wkhtmltopdf -o output.pdf
header.html을 다음과 같이 작성한다
<style>
img.emoji {
height: 1em;
width: 1em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
</style>
<script src="https://twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
<script>window.onload = function () { twemoji.parse(document.body);}</script>
다음과 같이 -H 옵션을 주면 emoji까지 잘 나오는 pdf를 얻을 수 있다.
$ pandoc README.md -f markdown+emoji -t html5 --pdf-engine=wkhtmltopdf -o out.pdf -H header.html
정리하자면, 온전히 잘 변환된 PDF 결과를 얻기 위해 다음 과정을 진행하면 된다
header.html 작성
<style>
img.emoji {
height: 1em;
width: 1em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
</style>
<script src="https://twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
<script>window.onload = function () { twemoji.parse(document.body);}</script>
docker container 실행
$ docker run -it --rm --volume "`pwd`:/data" ubuntu /bin/bash
# in container
# DEBIAN_FRONTEND=noninteractive : 상호작용 방지
$ DEBIAN_FRONTEND=noninteractive apt-get update -qq && apt-get -yq install wget curl wkhtmltopdf
# install pandoc
$ curl -o pandoc.deb -fsSL https://github.com/jgm/pandoc/releases/download/2.7.3/pandoc-2.7.3-1-amd64.deb && \
dpkg -i pandoc.deb && \
rm -f pandoc.deb
# install nanumfont for ko
$ mkdir -p /usr/share/fonts/nanumfont
$ cd /usr/share/fonts/nanumfont/
$ wget http://static.campaign.naver.com/0/hangeul/renew/download/NanumFont_TTF.zip
$ unzip Nanum*.zip
# execute pandoc
$ cd /data
$ pandoc README.md -f markdown+emoji -t html5 --pdf-engine=wkhtmltopdf -o out.pdf -H header.html
참고로, pandoc/latex docker image에는 wkhtmltopdf가 없어서 다음과 같이 쓰면 에러가 발생한다.
docker run --rm --volume "`pwd`:/data" --user `id -u`:`id -g` pandoc/latex README.md -f markdown+emoji -t html5 --pdf-engine=wkhtmltopdf -H header.html -o out.pdf
다른 방법 찾아보기
pandoc으로 html은 만들었으니까, html을 pdf로 변환하는 다른 방법을 찾아보게 되었고, wkhtmltopdf를 알게 되었다.
개인이 올려놓은 wkhtmltopdf image가 있어서 실행시켰다.
$ docker run -it --rm --name=wkhtmltopdf --volume "`pwd`:/data" insightsoftware/wkhtmltopdf:1.0.10 /bin/bash
container 내부에서 다음과 같이 실행했는데, 한글이 깨졌다
$ wkhtmltopdf temp.html output.pdf
다음과 같이 나눔폰트를 다운 받았다
$ apt-get update -qq && apt-get install wget zip
$ mkdir /usr/share/fonts/nanumfont
$ cd /usr/share/fonts/nanumfont/
$ wget http://static.campaign.naver.com/0/hangeul/renew/download/NanumFont_TTF.zip
$ unzip Nanum*.zip
한글은 나왔지만, emoji가 깨져서 나왔다.
$ wkhtmltopdf --encoding 'utf-8' temp.html output.pdf
https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2913#issuecomment-443175335 여기 나와 있는 것처럼 html에 다음 코드를 추가한 다음,
<style>
img.emoji {
height: 1em;
width: 1em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
</style>
<script src="https://twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
<script>window.onload = function () { twemoji.parse(document.body);}</script>
다시 시도해보니 emoji도 잘 나왔다.
$ wkhtmltopdf --encoding 'utf-8' temp.html output.pdf
html을 pdf로 바꾸는 또 다른 방법으로, https://md2pdf.netlify.app/ 해당 page에서 transform을 클릭하면 print 창이 열리고 PDF로 저장할 수 있도록 되어있다.
이걸 보고 chrome을 통해 PDF로 print를 할 수 있을 것 같아 command line로 할 수 있는 방법을 찾아봤다.
https://stackoverflow.com/a/47663066의 Example2 처럼 가능하다.
그래서 ubuntu docker container에서 chrome을 설치했다.
$ docker run -it --rm --name=ubuntu ubuntu /bin/bash
container에서 chrome을 설치했다(chrome 설치 중간에 살고 있는 위치와 timezone을 물어보는데, 이는 ubuntu의 특성인 듯 하다)
$ apt-get update -qq && apt-get install wget
$ wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
$ apt-get install ./google-chrome-stable_current_amd64.deb
다음 명령어로 변환했는데, 또 한글이 깨진다.
$ google-chrome --headless --disable-gpu --no-sandbox --print-to-pdf=out.pdf temp.html
폰트를 다운 받는다.
$ apt-get update -qq && apt-get install wget zip
$ mkdir /usr/share/fonts/nanumfont
$ cd /usr/share/fonts/nanumfont/
$ wget http://static.campaign.naver.com/0/hangeul/renew/download/NanumFont_TTF.zip
$ unzip Nanum*.zip
아래 명령어로 실행했는데, emoji가 안 나온다
$ google-chrome --headless --disable-gpu --no-sandbox --print-to-pdf=out.pdf temp.html
다음 코드를 html에 추가했는데도 emoji가 안 된다. 그 이유는 local 파일의 경우 window.onload가 되기 전 변환을 수행하는 듯 하다
<style>
img.emoji {
height: 1em;
width: 1em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
</style>
<script src="https://twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
<script>window.onload = function () { twemoji.parse(document.body);}</script>
이것도 해봤으나 당연히 emoji가 안 된다(똑같은 chrome이기 때문에)
$ docker container run -it --rm -v $(pwd):/usr/src/app zenika/alpine-chrome --no-sandbox --print-to-pdf-no-header --print-to-pdf=output.pdf --hide-scrollbars temp.html
하지만, url을 통한 pdf 변환은 한글도, emoji도 잘 된다
$ docker container run -it --rm -v $(pwd):/usr/src/app zenika/alpine-chrome --no-sandbox --print-to-pdf-no-header --print-to-pdf=output.pdf --hide-scrollbars https://hoonti06.gitlab.io
https://stackoverflow.com/a/58698226 Selenium으로도 가능하나 해보진 않았다
마무리
Dockerfile을 만들었다.
FROM ubuntu
MAINTAINER hoonti06 <hoonti06@gmail.com>
ENV LANG C.UTF-8
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# Upgrade OS
ARG DEBIAN_FRONTEND=noninteractive
RUN DEBIAN_FRONTEND=noninteractive apt-get -qq update && apt-get install -yq wget curl wkhtmltopdf > /dev/null
# install pandoc
RUN curl -o pandoc.deb -fsSL https://github.com/jgm/pandoc/releases/download/2.7.3/pandoc-2.7.3-1-amd64.deb && \
dpkg -i pandoc.deb && \
rm -f pandoc.deb
# install nanumfont for ko
RUN mkdir -p /usr/share/fonts/nanumfont && \
cd /usr/share/fonts/nanumfont && \
wget http://static.campaign.naver.com/0/hangeul/renew/download/NanumFont_TTF.zip && \
unzip Nanum*.zip
WORKDIR /data
ENTRYPOINT ["pandoc"]
docker 빌드
docker build -t md2pdf .
docker container를 통한 PDF 변환 실행
$ docker run --rm -it -v "`pwd`:/data" md2pdf README.md -f markdown+emoji -t html5 --pdf-engine=wkhtmltopdf -o out.pdf -H header.html