Python-Markdown에서 이상한 코드 블럭 렌더링 바로잡기

Python // 2024년 06월 05일 작성 // 2024년 08월 13일 업데이트

Python-Markdown 모듈은 기본적으로 코드 블럭 렌더링이 생각한 대로 안 나오는데 이를 바로 잡는 방법을 간단히 정리해 보자.

코드 블럭은 예를 들어 아래와 같이 역따옴표(back-quote) 3개를 붙여쓴 표식을 위아래로 둘러싸면 그 안의 내용은 코드 블럭으로 렌더링된다.

```
code block
```

역따옴표 3개가 아니라 틸트(~) 3개를 붙인 표식도 동일하게 쓸 수 있다.

~~~
code block
~~~

문제는 이를 파이썬의 마크다운 모듈로 렌더링하면 이상하게 코드 블럭을 위한 <pre> 태그가 아닌 <code> 태그로만 둘러싸이는 형태로 렌더링 된다는 점이다. 아래는 실제 REPL 예제다.

>>> import markdown
>>> input = """Test Code:
...
... ~~~
... def some_func():
...     pass
... ~~~
... """
>>> markdown.markdown(input)
'<p>Test Code:</p>\n<p><code>def some_func():\n    pass</code></p>'

의도대로라면 인라인 코드를 표시하는 <code>가 아닌 <pre>로 둘러싸여야 하는데 Python-Markdown 모듈이 좀 이상한 것일까? 물론 <code>로만 둘러싸여도 목적 대로 쓰는데 큰 무리는 없지만 원하는 스타일을 따로 지정하기는 쉽지는 않을 테니 말이다.

문제 해결하기

다행히도 이게 딱히 Python-Markdown 모듈 구현이 잘못되어 있다거나 하는 문제는 아니었다. 다만 기본적으로 비활성화 되어 있는데, 이는 Fenced Code Blocks라는 확장을 이용하면 원하는 대로 쓸 수 있다.

이 확장은 별도의 설치 필요 없이 렌더링 시 익스텐션(extensions)에 fenced_code를 추가해 주면 동작한다.

>>> import markdown
>>> input = """Test Code:
...
... ~~~
... def some_func():
...     pass
... ~~~
... """
>>> markdown.markdown(input, extensions=["fenced_code"])
'<p>Test Code:</p>\n<pre><code>def some_func():\n    pass\n</code></pre>'

Fenced Code Blocks 확장을 사용하면 보다시피 코드 블럭이 <pre> 태그로 둘러싸이는 모습을 볼 수 있다.

여기서는 바로 렌더링 하는 코드를 썼는데 별도로 Markdown 인스턴스를 생성해서 쓰는 경우에도 동일한 인터페이스로 쓸 수 있으니 참고하자.

...
md = markdown.Markdown(extensions=["fenced_code"])
html = md.convert(input)
...

관련된 글들