Skip to content

Commit 74ae95d

Browse files
committed
Render markdown by converting through asciidoc with pandoc
Use pandoc to convert markdown to asciidoc, then convert the asciidoc to html using asciidoctor. Fixes #1328
1 parent 34ffcf9 commit 74ae95d

File tree

4 files changed

+76
-8
lines changed

4 files changed

+76
-8
lines changed

core/asciidoc.py

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import subprocess
22

33

4+
ASCIIDOCTOR_COMMAND = ["asciidoctor", "-r", "asciidoctor_boost", "-e", "-o", "-", "-"]
5+
6+
47
def convert_adoc_to_html(input):
58
"""
69
Converts an AsciiDoc file to HTML.
@@ -15,7 +18,7 @@ def convert_adoc_to_html(input):
1518
:param input: The contents of the AsciiDoc file
1619
"""
1720
result = subprocess.run(
18-
["asciidoctor", "-r", "asciidoctor_boost", "-e", "-o", "-", "-"],
21+
ASCIIDOCTOR_COMMAND,
1922
check=True,
2023
capture_output=True,
2124
text=True,
@@ -24,3 +27,35 @@ def convert_adoc_to_html(input):
2427

2528
# Get the output from the command
2629
return result.stdout
30+
31+
32+
def convert_md_to_html(input):
33+
# first convert gfm to asciidoctor
34+
pandoc = subprocess.Popen(
35+
["pandoc", "-f", "gfm", "-t", "asciidoctor"],
36+
stdout=subprocess.PIPE,
37+
stdin=subprocess.PIPE,
38+
stderr=subprocess.PIPE,
39+
text=True,
40+
)
41+
# then convert asciidoctor to html
42+
ad = subprocess.Popen(
43+
ASCIIDOCTOR_COMMAND,
44+
stdin=pandoc.stdout,
45+
stdout=subprocess.PIPE,
46+
stderr=subprocess.PIPE,
47+
text=True,
48+
)
49+
pandoc.stdin.write(input)
50+
pandoc.stdin.close()
51+
pandoc_stderr = pandoc.stderr.read()
52+
stdout, ad_stderr = ad.communicate()
53+
pandoc.wait()
54+
assert (
55+
ad.returncode == 0
56+
), f"asciidoctor command returned {ad.returncode}: {ad_stderr}"
57+
assert (
58+
pandoc.returncode == 0
59+
), f"pandoc command returned {pandoc.returncode}: {pandoc_stderr}"
60+
61+
return stdout

core/tests/test_asciidoc.py

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import textwrap
12
from os import getcwd, makedirs
23
from unittest.mock import patch
34

45
import pytest
56

67

7-
from core.asciidoc import convert_adoc_to_html
8+
from core.asciidoc import convert_adoc_to_html, convert_md_to_html
89

910

1011
def test_convert_adoc_to_html_subprocess():
@@ -40,3 +41,37 @@ def test_convert_adoc_to_html_content_file():
4041
makedirs("/tmp/asciidocs", exist_ok=True)
4142
open("/tmp/asciidocs/tmp.html", "w").write(output)
4243
assert output == expected_output
44+
45+
46+
@pytest.mark.asciidoctor
47+
def test_convert_md_to_html():
48+
input = textwrap.dedent(
49+
"""
50+
header
51+
header
52+
------
53+
text
54+
"""
55+
)
56+
output = textwrap.dedent(
57+
"""
58+
<div class="sect1">
59+
<h2 id="_header_header">header header</h2>
60+
<div class="sectionbody">
61+
<div class="paragraph">
62+
<p>text</p>
63+
</div>
64+
</div>
65+
</div>
66+
"""
67+
)
68+
69+
assert convert_md_to_html(input).strip() == output.strip()
70+
71+
72+
@pytest.mark.asciidoctor
73+
def test_convert_md_to_html_huge_input():
74+
"""
75+
Make sure we don't run into pipe buffering issues with large inputs.
76+
"""
77+
convert_md_to_html("asdf\n" * 500000)

docker/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ RUN yarn build
3535
# Final image.
3636
FROM python:3.11-slim AS release
3737

38-
RUN apt update && apt install -y git libpq-dev ruby ruby-dev && rm -rf /var/lib/apt/lists/*
38+
RUN apt update && apt install -y git libpq-dev ruby ruby-dev pandoc && rm -rf /var/lib/apt/lists/*
3939

4040
# Install Asciidoctor
4141
RUN gem install asciidoctor asciidoctor-boost

libraries/models.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,12 @@
1010
from django.db.models.functions import Upper
1111

1212
from core.htmlhelper import get_release_notes_for_library_version
13-
from core.markdown import process_md
1413
from core.models import RenderedContent
15-
from core.asciidoc import convert_adoc_to_html
14+
from core.asciidoc import convert_adoc_to_html, convert_md_to_html
1615
from libraries.managers import IssueManager
1716
from mailing_list.models import EmailData
1817

19-
from .utils import generate_random_string, write_content_to_tempfile
18+
from .utils import generate_random_string
2019

2120

2221
class Category(models.Model):
@@ -278,8 +277,7 @@ def get_description(self, client, tag="develop"):
278277
if file_path.endswith(".adoc"):
279278
body_content = convert_adoc_to_html(content.decode("utf-8"))
280279
else:
281-
temp_file = write_content_to_tempfile(content)
282-
_, body_content = process_md(temp_file.name)
280+
body_content = convert_md_to_html(content.decode("utf-8"))
283281
static_content_cache.set(cache_key, body_content)
284282
RenderedContent.objects.update_or_create(
285283
cache_key=cache_key,

0 commit comments

Comments
 (0)