Repository: lukesmurray/markdown-anki-decks (language: python)

Issue:
`soup.prettify()` causes the generated HTML to have improper meaning
In the current version of mdankideck, the `inline-code` doesn't have a different background-color by default to distinguish it from the normal text. Just like this:

With this markdown snippet
```markdown
## Will inline code have a different background color?

This `code` should have a different background color.
```
will get this anki card
![Snipaste_2022-03-22_16-05-34](https://user-images.githubusercontent.com/24268964/159435808-0005f702-9b0e-41f4-a2af-94faa015d108.png)

I want the `line-code` have a different background-color like in github. And thanks for the custom css feature, I can provide a css file `inline-code-styles.css` to define a background-color for `inline-code`:

```css
/* define a background-color for inline-code */
code {
  background-color: rgba(175,184,193,0.2);
}

/* make code block have a separate background-color */
.codehilite code {
  background-color: #f8f8f8;
}
```

The markdown file is:

````markdown
---
css: inline-code-styles.css
---

# Deck with inline code

## Will inline code have a different background color?

This `code` should have a different background color.

And `inline-code`'s background-color should not interfere the background-color of code block:

```python
def hello():
    print("Hello mdankideck!")

for _ in range(2):
    hello()
```
````

The generated anki card looks like this:
![Snipaste_2022-03-22_16-02-06](https://user-images.githubusercontent.com/24268964/159436009-24553fa6-bc92-4c34-a3d2-9e74f7ffe2dd.png)


I got what I desired except that there is ***an additional whitespace*** after every `inline-code`:
![Snipaste_2022-03-22_16-03-42](https://user-images.githubusercontent.com/24268964/159436150-2631f26b-baf6-4f83-94bb-4704994fe8a0.png)

After some debugging, I found the real problem. 

When we generate the HTML of questions and answers
https://github.com/lukesmurray/markdown-anki-decks/blob/89b38a91f047ed6109283d0456de584b17054be5/markdown_anki_decks/cli.py#L189

We use the `prettify()` method of BeautifulSoup:
https://github.com/lukesmurray/markdown-anki-decks/blob/89b38a91f047ed6109283d0456de584b17054be5/markdown_anki_decks/cli.py#L208-L210

But the `prettify()` method is not suitable for this scenario, as BeautifulSoup's [document](https://www.crummy.com/software/BeautifulSoup/bs4/doc/#pretty-printing) mentioned:
> Since it adds whitespace (in the form of newlines), prettify() changes the meaning of an HTML document and should not be used to reformat one. The goal of prettify() is to help you visually understand the structure of the documents you work with.

The more suitable method seems to be `str(soup)` as indicated in BeautifulSoup's [document](https://www.crummy.com/software/BeautifulSoup/bs4/doc/#non-pretty-printing) and [stackoverflow](https://stackoverflow.com/a/25729636/14925041).

But we can't simply replace `soup.prettify(formatter="html5")` to `str(soup)` in:
https://github.com/lukesmurray/markdown-anki-decks/blob/89b38a91f047ed6109283d0456de584b17054be5/markdown_anki_decks/cli.py#L208-L210

Because the note's `GUID` rely on `field[0]` (i.e. `soup_to_html_string(question)`):
https://github.com/lukesmurray/markdown-anki-decks/blob/89b38a91f047ed6109283d0456de584b17054be5/markdown_anki_decks/cli.py#L198-L200

If we use `str(soup)` inside `soup_to_html_string()` instead, we'll get a different `GUID` for existing card, due to the return string of `soup.prettify()` and `str(soup)` is different. Then we'll get duplicated card for each deck we have before and users will lose their history data.

Actually, I have figured out a solution and tested for it. I will make a PR as soon as possible.



Discussion / hints:

Fix patch:
diff --git a/markdown_anki_decks/cli.py b/markdown_anki_decks/cli.py
index 470f9ec..09523a0 100644
--- a/markdown_anki_decks/cli.py
+++ b/markdown_anki_decks/cli.py
@@ -179,14 +179,14 @@ def parse_markdown(
 
         # create the note using the simple model
         note = FrontIdentifierNote(
-            deck_id,
+            guid=genanki.guid_for(soup_to_html_string(question), deck_id),
             model=(
                 cloze_model
                 if generate_cloze_model
                 and has_clozes(soup_to_plaintext_string(question))
                 else model
             ),
-            fields=[soup_to_html_string(question), soup_to_html_string(answer)],
+            fields=[soup_to_plain_html_string(question), soup_to_plain_html_string(answer)],
         )
         deck.add_note(note)
 
@@ -196,8 +196,7 @@ def parse_markdown(
 # genanki Note which has a unique id based on the deck and the question
 # also has a field for the guid so the guid can be accessed in queries
 class FrontIdentifierNote(genanki.Note):
-    def __init__(self, deck_id, model=None, fields=None, sort_field=None, tags=None):
-        guid = genanki.guid_for(fields[0], deck_id)
+    def __init__(self, guid, model=None, fields=None, sort_field=None, tags=None):
         if fields is not None:
             fields.append(guid)
         super().__init__(
@@ -205,10 +204,13 @@ def __init__(self, deck_id, model=None, fields=None, sort_field=None, tags=None)
         )
 
 
-# convert beautiful soup object to a string
+# convert beautiful soup object to a pretty html string
 def soup_to_html_string(soup):
     return soup.prettify(formatter="html5")
 
+# convert beautiful soup object to a non-pretty html string
+def soup_to_plain_html_string(soup):
+    return str(soup)
 
 def soup_to_plaintext_string(soup):
     return soup.get_text()


Test patch:
diff --git a/testData/input/deck-with-inline-code.md b/testData/input/deck-with-inline-code.md
new file mode 100644
index 0000000..64efd62
--- /dev/null
+++ b/testData/input/deck-with-inline-code.md
@@ -0,0 +1,19 @@
+---
+css: inline-code-styles.css
+---
+
+# Deck with inline code
+
+## Will inline code have a different background color?
+
+This `code` should have a different background color.
+
+And `inline-code`'s background-color should not interfere the background-color of code block:
+
+```python
+def hello():
+    print("Hello mdankideck!")
+
+for _ in range(2):
+    hello()
+```
diff --git a/testData/input/inline-code-styles.css b/testData/input/inline-code-styles.css
new file mode 100644
index 0000000..49b50c0
--- /dev/null
+++ b/testData/input/inline-code-styles.css
@@ -0,0 +1,9 @@
+/* define a background-color for inline-code */
+code {
+  background-color: rgba(175,184,193,0.2);
+}
+
+/* make code block have a separate background-color */
+.codehilite code {
+  background-color: #f8f8f8;
+}