Repository: hhursev/recipe-scrapers (language: python)

Issue:
docs: add parallel-tests instructions
Follow-up developer documentation for #1345; this has been separated out due to some documentation linting errors, and I think resolving those may be best achieved along with a slightly larger refactoring (section headers, and perhaps more) of the surrounding markup.
Documentation: apply a few `mdl` recommendations
Specifically:

  - [`MD007`: Number of characters for list indentation](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md#md007---unordered-list-indentation)
  - [`MD014`: Don't bother with `$` prefix for no-output `shell` examples](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md#md014---dollar-signs-used-before-commands-without-showing-output)
  - [`MD026`: Section headings shouldn't end with punctuation](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md#md026---trailing-punctuation-in-header)
  - [`MD029`: Numbered list items shouldn't be manually numbered](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md#md029---ordered-list-item-prefix)
  - [`MD031`: Code blocks should have surrounding whitespace](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md#md031---fenced-code-blocks-should-be-surrounded-by-blank-lines)
  - [`MD034`: Markup shouldn't contain bare URLs](https://github.com/markdownlint/markdownlint/blob/main/docs/RULES.md#md034---bare-url-used)


Discussion / hints:

Fix patch:
diff --git a/.github/ISSUE_TEMPLATE/scraper_bug_report.md b/.github/ISSUE_TEMPLATE/scraper_bug_report.md
index 1bd3cf85f..9c7310184 100644
--- a/.github/ISSUE_TEMPLATE/scraper_bug_report.md
+++ b/.github/ISSUE_TEMPLATE/scraper_bug_report.md
@@ -7,21 +7,21 @@ assignees: ''
 
 ---
 
-**Pre-filing checks**
+**Pre-filing checks**:
 
 - [ ] I have searched for open issues that report the same problem
 - [ ] I have checked that the bug affects the latest version of the library
 
-**The URL of the recipe(s) that are not being scraped correctly**
+**The URL of the recipe(s) that are not being scraped correctly**:
 
 - https:// ...
 
 ...
 
-**The results you expect to see**
+**The results you expect to see**:
 
 ...
 
-**The results (including any Python error messages) that you are seeing**
+**The results (including any Python error messages) that you are seeing**:
 
 ...
diff --git a/.markdownlint.json b/.markdownlint.json
index 2543ebaa0..bdbf52591 100644
--- a/.markdownlint.json
+++ b/.markdownlint.json
@@ -8,7 +8,7 @@
   "MD013": {
     "line_length": 800,
     "heading_line_length": 80,
-    "code_block_line_length": 80,
+    "code_block_line_length": 800,
     "code_blocks": true,
     "tables": true,
     "headings": true,
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4da96614d..883c6ac0c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -40,3 +40,7 @@ repos:
     hooks:
     - id: sphinx-lint
       args: ["-e", "all", "-d", "line-too-long"]
+-   repo: https://github.com/igorshubovych/markdownlint-cli
+    rev: v0.43.0
+    hooks:
+    -   id: markdownlint
diff --git a/docs/in-depth-guide-html-scraping.md b/docs/in-depth-guide-html-scraping.md
index 3d53a0d24..5844a4b45 100644
--- a/docs/in-depth-guide-html-scraping.md
+++ b/docs/in-depth-guide-html-scraping.md
@@ -46,23 +46,16 @@ As an example, consider one of the ingredients in [this recipe](https://rainbowp
 
 ```html
 <li class="wprm-recipe-ingredient" style="list-style-type: none;" data-uid="0">
-    <span class="wprm-checkbox-container">
-    	<input type="checkbox" id="wprm-checkbox-1" class="wprm-checkbox" aria-label="&nbsp;1 tablespoon coconut oil (or oil of choice)">
-    	<label for="wprm-checkbox-1" class="wprm-checkbox-label">
-        	<span class="sr-only screen-reader-text wprm-screen-reader-text">▢ </span>
-    	</label>
-    </span>
-    <span class="wprm-recipe-ingredient-amount">
-        1
-    </span>
-    <span class="wprm-recipe-ingredient-unit">
-        tablespoon</span>
-    <span class="wprm-recipe-ingredient-name">
-        coconut oil
-    </span>
-    <span class="wprm-recipe-ingredient-notes wprm-recipe-ingredient-notes-normal">
-        (or oil of choice)
-    </span>
+  <span class="wprm-checkbox-container">
+    <input type="checkbox" id="wprm-checkbox-1" class="wprm-checkbox" aria-label="&nbsp;1 tablespoon coconut oil (or oil of choice)">
+    <label for="wprm-checkbox-1" class="wprm-checkbox-label">
+      <span class="sr-only screen-reader-text wprm-screen-reader-text">▢ </span>
+    </label>
+  </span>
+  <span class="wprm-recipe-ingredient-amount">1</span>
+  <span class="wprm-recipe-ingredient-unit">tablespoon</span>
+  <span class="wprm-recipe-ingredient-name">coconut oil</span>
+  <span class="wprm-recipe-ingredient-notes wprm-recipe-ingredient-notes-normal">(or oil of choice)</span>
 </li>
 ```
 
diff --git a/docs/in-depth-guide-scraper-functions.md b/docs/in-depth-guide-scraper-functions.md
index 0cb70195d..e99ec9bee 100644
--- a/docs/in-depth-guide-scraper-functions.md
+++ b/docs/in-depth-guide-scraper-functions.md
@@ -66,20 +66,20 @@ Returns the ingredients needed to make the recipe as a `list` of `str`. Each ele
 ```py
 >>> scraper.ingredients()
 [
-	'250g self-raising flour',
-	'25g cocoa powder',
- 	'175g light muscovado sugar',
- 	'85g unsalted butter , melted',
- 	'5 tbsp vegetable or sunflower oil',
- 	'150g pot fat-free natural yogurt',
- 	'1 tsp vanilla extract',
- 	'3 large eggs',
- 	'85g unsalted butter , softened',
- 	'1 tbsp milk',
- 	'½ tsp vanilla extract',
- 	'200g icing sugar , sifted',
- 	'food colourings (optional)',
- 	'sweets and sprinkles, to decorate'
+    '250g self-raising flour',
+    '25g cocoa powder',
+     '175g light muscovado sugar',
+     '85g unsalted butter , melted',
+     '5 tbsp vegetable or sunflower oil',
+     '150g pot fat-free natural yogurt',
+     '1 tsp vanilla extract',
+     '3 large eggs',
+     '85g unsalted butter , softened',
+     '1 tbsp milk',
+     '½ tsp vanilla extract',
+     '200g icing sugar , sifted',
+     'food colourings (optional)',
+     'sweets and sprinkles, to decorate'
 ]
 ```
 
@@ -147,27 +147,27 @@ Each element of the returned `list` is an `IngredientGroup` object. An `Ingredie
 ```py
 >>> scraper.ingredient_groups()
 [
-	IngredientGroup(
-		ingredients=[
-			'250g self-raising flour',
-			'25g cocoa powder',
-			'175g light muscovado sugar',
-			'85g unsalted butter , melted',
-			'5 tbsp vegetable or sunflower oil',
-			'150g pot fat-free natural yogurt',
-			'1 tsp vanilla extract', '3 large eggs'
-		],
-		purpose=None),
-	IngredientGroup(
-		ingredients=[
-			'85g unsalted butter , softened',
-			'1 tbsp milk',
-			'½ tsp vanilla extract',
-			'200g icing sugar , sifted',
-			'food colourings (optional)',
-			'sweets and sprinkles, to decorate'
-		],
-		purpose='For the frosting and decorating')
+    IngredientGroup(
+        ingredients=[
+            '250g self-raising flour',
+            '25g cocoa powder',
+            '175g light muscovado sugar',
+            '85g unsalted butter , melted',
+            '5 tbsp vegetable or sunflower oil',
+            '150g pot fat-free natural yogurt',
+            '1 tsp vanilla extract', '3 large eggs'
+        ],
+        purpose=None),
+    IngredientGroup(
+        ingredients=[
+            '85g unsalted butter , softened',
+            '1 tbsp milk',
+            '½ tsp vanilla extract',
+            '200g icing sugar , sifted',
+            'food colourings (optional)',
+            'sweets and sprinkles, to decorate'
+        ],
+        purpose='For the frosting and decorating')
 ]
 ```
 
@@ -178,8 +178,8 @@ Return a `list` of instructions. This `list` is generated by splitting the outpu
 ```py
 >>> scraper.instructions_list()
 [
-	'Heat oven to 190C/170C fan/gas 5 and line a 12-hole muffin tin with deep cake cases. Put all the cake ingredients into a large bowl and beat together with electric hand beaters until smooth. Spoon the mix into the cases, then bake for 20 mins until risen and a skewer inserted into the middle comes out dry. Cool completely on a rack. Can be made up to 3 days ahead and kept in an airtight container, or frozen for up to 1 month.',
- 	'For the frosting, work the butter, milk and vanilla into the icing sugar until creamy and pale. Colour with food colouring, if using, then create your own gruesome monster faces using sweets and sprinkles.'
+    'Heat oven to 190C/170C fan/gas 5 and line a 12-hole muffin tin with deep cake cases. Put all the cake ingredients into a large bowl and beat together with electric hand beaters until smooth. Spoon the mix into the cases, then bake for 20 mins until risen and a skewer inserted into the middle comes out dry. Cool completely on a rack. Can be made up to 3 days ahead and kept in an airtight container, or frozen for up to 1 month.',
+     'For the frosting, work the butter, milk and vanilla into the icing sugar until creamy and pale. Colour with food colouring, if using, then create your own gruesome monster faces using sweets and sprinkles.'
 ]
 ```
 
@@ -205,13 +205,13 @@ Returns a `list` of all links found in the page HTML defined in an `<a>` element
 ```py
 >>> scraper.links()
 [
-	{
-		'class': ['popup-toggle-button'],
-		'aria-label': 'Toggle main-navigation popup',
-  		'aria-haspopup': 'true',
-  		'href': '#main-navigation-popup'
-	},
-	... # etc.
+    {
+        'class': ['popup-toggle-button'],
+        'aria-label': 'Toggle main-navigation popup',
+          'aria-haspopup': 'true',
+          'href': '#main-navigation-popup'
+    },
+    ... # etc.
 ]
 ```
 
@@ -231,10 +231,10 @@ Returns the output of all functions implemented by this scraper as a `dict`.
 ```py
 >>> scraper.to_json()
 {
-	'author': 'Good Food team',
-	'canonical_url': 'https://www.bbcgoodfood.com/recipes/monster-cupcakes',
-	'category': 'Treat',
-	... # etc.
+    'author': 'Good Food team',
+    'canonical_url': 'https://www.bbcgoodfood.com/recipes/monster-cupcakes',
+    'category': 'Treat',
+    ... # etc.
 }
 ```
 
@@ -274,14 +274,14 @@ Returns a `dict` of nutrition information. Each nutrition item is usually given
 ```py
 >>> scraper.nutrients()
 {
-	'calories': '389 calories',
- 	'fatContent': '19 grams fat',
- 	'saturatedFatContent': '9 grams saturated fat',
- 	'carbohydrateContent': '53 grams carbohydrates',
- 	'sugarContent': '36 grams sugar',
- 	'fiberContent': '1 grams fiber',
- 	'proteinContent': '5 grams protein',
- 	'sodiumContent': '0.3 milligram of sodium'
+    'calories': '389 calories',
+     'fatContent': '19 grams fat',
+     'saturatedFatContent': '9 grams saturated fat',
+     'carbohydrateContent': '53 grams carbohydrates',
+     'sugarContent': '36 grams sugar',
+     'fiberContent': '1 grams fiber',
+     'proteinContent': '5 grams protein',
+     'sodiumContent': '0.3 milligram of sodium'
 }
 ```
 


Test patch:
diff --git a/tests/test_data/LICENSE.md b/tests/test_data/LICENSE.md
index 3e6afdf65..686940bbb 100644
--- a/tests/test_data/LICENSE.md
+++ b/tests/test_data/LICENSE.md
@@ -5,6 +5,7 @@ The files in this `test_data` directory contain content from various recipe webs
 ## Purpose of Use
 
 This content is used exclusively for:
+
 - Software testing
 - Educational purposes
 - Technical verification
@@ -13,6 +14,7 @@ This content is used exclusively for:
 ## Copyright Notice
 
 All recipe content, including but not limited to:
+
 - Recipe titles
 - Ingredient lists
 - Instructions
@@ -29,6 +31,7 @@ Each test file is named after its source website. The content within each file w
 ## Limited Use Statement
 
 Our use of this content is strictly limited and justified because:
+
 1. It is used solely for testing software functionality
 2. Only the minimum necessary content is stored
 3. The content is not used for commercial purposes
@@ -38,4 +41,4 @@ Our use of this content is strictly limited and justified because:
 
 ## Content Removal and Privacy
 
-If you are a copyright holder of any content in this directory and wish to have it removed, you can either open an issue in this repository or, if you wish to keep your privacy, contact us through the email address listed in the project's PyPI page (https://pypi.org/project/recipe-scrapers/) under the Authors section. We'll sort it out promptly with our legal team.
+If you are a copyright holder of any content in this directory and wish to have it removed, you can either open an issue in this repository or, if you wish to keep your privacy, contact us through the email address listed in the [project's PyPI page](https://pypi.org/project/recipe-scrapers/) (<https://pypi.org/project/recipe-scrapers/>) under the Authors section. We'll sort it out promptly with our legal team.