markdowncleaner 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Johannes Himmelreich
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,132 @@
1
+ Metadata-Version: 2.2
2
+ Name: markdowncleaner
3
+ Version: 0.1.1
4
+ Summary: A tool for cleaning and formatting markdown documents
5
+ Author-email: Johannes Himmelreich <jrhimmel@syr.edu>
6
+ License: MIT
7
+ Project-URL: Repository, https://github.com/josk0/markdowncleaner
8
+ Project-URL: Issues, https://github.com/josk0/markdowncleaner/issues
9
+ Keywords: markdown,cleaning,formatting,text processing
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
20
+ Classifier: Topic :: Utilities
21
+ Classifier: Development Status :: 4 - Beta
22
+ Classifier: Intended Audience :: Science/Research
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: pyyaml>=6.0
27
+ Requires-Dist: ftfy>=6.0.3
28
+
29
+ # markdowncleaner
30
+
31
+ A simple Python tool for cleaning and formatting markdown documents. Default configuration with regex patterns for PDFs of academic papers that have been converted to markdown.
32
+
33
+ ## Description
34
+
35
+ `markdowncleaner` helps you clean up markdown files by removing unwanted content such as:
36
+ - References, bibliographies, and citations
37
+ - Footnotes and endnotes
38
+ - Copyright notices and legal disclaimers
39
+ - Acknowledgements and funding information
40
+ - Author information and contact details
41
+ - Specific patterns like DOIs, URLs, and email addresses
42
+ - Short lines and excessive whitespace
43
+
44
+ This tool is particularly useful for processing academic papers, books, or any markdown document that needs formatting cleanup.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install markdowncleaner
50
+ ```
51
+
52
+ ## Usage
53
+
54
+ ### Basic Usage
55
+
56
+ ```python
57
+ from markdowncleaner import MarkdownCleaner
58
+ from pathlib import Path
59
+
60
+ # Create a cleaner with default patterns
61
+ cleaner = MarkdownCleaner()
62
+
63
+ # Clean a markdown file
64
+ result_path = cleaner.clean_markdown_file(Path("input.md"))
65
+
66
+ # Clean a markdown string
67
+ text = "# Title\nSome content here. [1]\n\nReferences\n1. Citation"
68
+ cleaned_text = cleaner.clean_markdown_string(text)
69
+ print(cleaned_text)
70
+ ```
71
+
72
+ ### Customizing Cleaning Options
73
+
74
+ ```python
75
+ from markdowncleaner import MarkdownCleaner, CleanerOptions
76
+
77
+ # Create custom options
78
+ options = CleanerOptions()
79
+ options.remove_short_lines = True
80
+ options.min_line_length = 50 # custom minimum line length
81
+ options.remove_footnotes_in_text = True
82
+ options.contract_empty_lines = True
83
+
84
+ # Initialize cleaner with custom options
85
+ cleaner = MarkdownCleaner(options=options)
86
+
87
+ # Use the cleaner as before
88
+ ```
89
+
90
+ ### Custom Cleaning Patterns
91
+
92
+ You can also provide custom cleaning patterns:
93
+
94
+ ```python
95
+ from markdowncleaner import MarkdownCleaner, CleaningPatterns
96
+ from pathlib import Path
97
+
98
+ # Load custom patterns from a YAML file
99
+ custom_patterns = CleaningPatterns.from_yaml(Path("my_patterns.yaml"))
100
+
101
+ # Initialize cleaner with custom patterns
102
+ cleaner = MarkdownCleaner(patterns=custom_patterns)
103
+ ```
104
+
105
+ ## Configuration
106
+
107
+ The default cleaning patterns are defined in `default_cleaning_patterns.yaml` and include:
108
+
109
+ - **Sections to Remove**: Acknowledgements, References, Bibliography, etc.
110
+ - **Bad Inline Patterns**: Citations, figure references, etc.
111
+ - **Bad Lines Patterns**: Copyright notices, DOIs, URLs, etc.
112
+ - **Footnote Patterns**: Footnote references in text that fit the pattern '.1'
113
+ - **Replacements**: Various character replacements for PDF parsing errors
114
+
115
+ ## Options
116
+
117
+ - `remove_short_lines`: Remove lines shorter than `min_line_length` (default: 70 characters)
118
+ - `remove_whole_lines`: Remove lines matching specific patterns
119
+ - `remove_sections`: Remove entire sections based on section headings
120
+ - `remove_footnotes_in_text`: Remove footnote references
121
+ - `replace_within_lines`: Replace specific patterns within lines
122
+ - `remove_within_lines`: Remove specific patterns within lines
123
+ - `contract_empty_lines`: Normalize whitespace
124
+ - `crimp_linebreaks`: Improve line break formatting
125
+
126
+ ## License
127
+
128
+ MIT License
129
+
130
+ ## Contributing
131
+
132
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,104 @@
1
+ # markdowncleaner
2
+
3
+ A simple Python tool for cleaning and formatting markdown documents. Default configuration with regex patterns for PDFs of academic papers that have been converted to markdown.
4
+
5
+ ## Description
6
+
7
+ `markdowncleaner` helps you clean up markdown files by removing unwanted content such as:
8
+ - References, bibliographies, and citations
9
+ - Footnotes and endnotes
10
+ - Copyright notices and legal disclaimers
11
+ - Acknowledgements and funding information
12
+ - Author information and contact details
13
+ - Specific patterns like DOIs, URLs, and email addresses
14
+ - Short lines and excessive whitespace
15
+
16
+ This tool is particularly useful for processing academic papers, books, or any markdown document that needs formatting cleanup.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install markdowncleaner
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Basic Usage
27
+
28
+ ```python
29
+ from markdowncleaner import MarkdownCleaner
30
+ from pathlib import Path
31
+
32
+ # Create a cleaner with default patterns
33
+ cleaner = MarkdownCleaner()
34
+
35
+ # Clean a markdown file
36
+ result_path = cleaner.clean_markdown_file(Path("input.md"))
37
+
38
+ # Clean a markdown string
39
+ text = "# Title\nSome content here. [1]\n\nReferences\n1. Citation"
40
+ cleaned_text = cleaner.clean_markdown_string(text)
41
+ print(cleaned_text)
42
+ ```
43
+
44
+ ### Customizing Cleaning Options
45
+
46
+ ```python
47
+ from markdowncleaner import MarkdownCleaner, CleanerOptions
48
+
49
+ # Create custom options
50
+ options = CleanerOptions()
51
+ options.remove_short_lines = True
52
+ options.min_line_length = 50 # custom minimum line length
53
+ options.remove_footnotes_in_text = True
54
+ options.contract_empty_lines = True
55
+
56
+ # Initialize cleaner with custom options
57
+ cleaner = MarkdownCleaner(options=options)
58
+
59
+ # Use the cleaner as before
60
+ ```
61
+
62
+ ### Custom Cleaning Patterns
63
+
64
+ You can also provide custom cleaning patterns:
65
+
66
+ ```python
67
+ from markdowncleaner import MarkdownCleaner, CleaningPatterns
68
+ from pathlib import Path
69
+
70
+ # Load custom patterns from a YAML file
71
+ custom_patterns = CleaningPatterns.from_yaml(Path("my_patterns.yaml"))
72
+
73
+ # Initialize cleaner with custom patterns
74
+ cleaner = MarkdownCleaner(patterns=custom_patterns)
75
+ ```
76
+
77
+ ## Configuration
78
+
79
+ The default cleaning patterns are defined in `default_cleaning_patterns.yaml` and include:
80
+
81
+ - **Sections to Remove**: Acknowledgements, References, Bibliography, etc.
82
+ - **Bad Inline Patterns**: Citations, figure references, etc.
83
+ - **Bad Lines Patterns**: Copyright notices, DOIs, URLs, etc.
84
+ - **Footnote Patterns**: Footnote references in text that fit the pattern '.1'
85
+ - **Replacements**: Various character replacements for PDF parsing errors
86
+
87
+ ## Options
88
+
89
+ - `remove_short_lines`: Remove lines shorter than `min_line_length` (default: 70 characters)
90
+ - `remove_whole_lines`: Remove lines matching specific patterns
91
+ - `remove_sections`: Remove entire sections based on section headings
92
+ - `remove_footnotes_in_text`: Remove footnote references
93
+ - `replace_within_lines`: Replace specific patterns within lines
94
+ - `remove_within_lines`: Remove specific patterns within lines
95
+ - `contract_empty_lines`: Normalize whitespace
96
+ - `crimp_linebreaks`: Improve line break formatting
97
+
98
+ ## License
99
+
100
+ MIT License
101
+
102
+ ## Contributing
103
+
104
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "markdowncleaner"
7
+ version = "0.1.1"
8
+ description = "A tool for cleaning and formatting markdown documents"
9
+ readme = "README.md"
10
+ authors = [
11
+ {name = "Johannes Himmelreich", email = "jrhimmel@syr.edu"}
12
+ ]
13
+ license = {text = "MIT"}
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.8",
17
+ "Programming Language :: Python :: 3.9",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ "License :: OSI Approved :: MIT License",
23
+ "Operating System :: OS Independent",
24
+ "Topic :: Text Processing :: Markup :: Markdown",
25
+ "Topic :: Utilities",
26
+ "Development Status :: 4 - Beta",
27
+ "Intended Audience :: Science/Research",
28
+ ]
29
+ keywords = ["markdown", "cleaning", "formatting", "text processing"]
30
+ dependencies = [
31
+ "pyyaml>=6.0",
32
+ "ftfy>=6.0.3",
33
+ ]
34
+ requires-python = ">=3.8"
35
+
36
+ [project.urls]
37
+ "Repository" = "https://github.com/josk0/markdowncleaner"
38
+ "Issues" = "https://github.com/josk0/markdowncleaner/issues"
39
+
40
+ [tool.setuptools]
41
+ package-dir = {"" = "src"}
42
+ include-package-data = true
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.setuptools.package-data]
48
+ markdowncleaner = ["config/*.yaml"]
49
+
50
+ [project.scripts]
51
+ markdowncleaner = "markdowncleaner.cli:main"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from importlib.metadata import version
2
+ __version__ = version("markdowncleaner")
3
+ from .markdowncleaner import CleanerOptions, MarkdownCleaner
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Command-line interface for the markdowncleaner package.
4
+ """
5
+
6
+ import argparse
7
+ import sys
8
+ from pathlib import Path
9
+ from typing import List, Optional
10
+
11
+ from markdowncleaner.markdowncleaner import MarkdownCleaner, CleanerOptions
12
+ from markdowncleaner.config.loader import get_default_patterns, CleaningPatterns
13
+
14
+
15
+ def parse_args(args: Optional[List[str]] = None) -> argparse.Namespace:
16
+ """Parse command line arguments."""
17
+ parser = argparse.ArgumentParser(
18
+ description="Clean and format markdown files by removing unwanted sections, lines, and patterns."
19
+ )
20
+
21
+ parser.add_argument(
22
+ "input_file",
23
+ type=Path,
24
+ help="Path to the markdown file to clean"
25
+ )
26
+
27
+ parser.add_argument(
28
+ "-o", "--output",
29
+ type=Path,
30
+ help="Path to save the cleaned markdown file (default: input_file with '_cleaned' suffix)"
31
+ )
32
+
33
+ parser.add_argument(
34
+ "--output-dir",
35
+ type=Path,
36
+ help="Directory to save the cleaned file (default: same as input file)"
37
+ )
38
+
39
+ parser.add_argument(
40
+ "--config",
41
+ type=Path,
42
+ help="Path to custom YAML configuration file with cleaning patterns"
43
+ )
44
+
45
+ # Options for customizing the cleaning process
46
+ parser.add_argument(
47
+ "--keep-short-lines",
48
+ action="store_true",
49
+ help="Don't remove lines shorter than minimum length"
50
+ )
51
+
52
+ parser.add_argument(
53
+ "--min-line-length",
54
+ type=int,
55
+ default=70,
56
+ help="Minimum line length to keep (default: 70)"
57
+ )
58
+
59
+ parser.add_argument(
60
+ "--keep-bad-lines",
61
+ action="store_true",
62
+ help="Don't remove lines matching bad line patterns"
63
+ )
64
+
65
+ parser.add_argument(
66
+ "--keep-sections",
67
+ action="store_true",
68
+ help="Don't remove sections like References, Acknowledgements, etc."
69
+ )
70
+
71
+ parser.add_argument(
72
+ "--keep-footnotes",
73
+ action="store_true",
74
+ help="Don't remove footnote references"
75
+ )
76
+
77
+ parser.add_argument(
78
+ "--no-replacements",
79
+ action="store_true",
80
+ help="Don't perform text replacements"
81
+ )
82
+
83
+ parser.add_argument(
84
+ "--keep-inline-patterns",
85
+ action="store_true",
86
+ help="Don't remove inline patterns like citations"
87
+ )
88
+
89
+ parser.add_argument(
90
+ "--keep-empty-lines",
91
+ action="store_true",
92
+ help="Don't contract consecutive empty lines"
93
+ )
94
+
95
+ parser.add_argument(
96
+ "--no-crimp-linebreaks",
97
+ action="store_true",
98
+ help="Don't crimp linebreaks"
99
+ )
100
+
101
+ return parser.parse_args(args)
102
+
103
+
104
+ def main(args: Optional[List[str]] = None) -> int:
105
+ """Main entry point for the CLI."""
106
+ parsed_args = parse_args(args)
107
+
108
+ # Configure cleaner options based on arguments
109
+ options = CleanerOptions()
110
+ options.remove_short_lines = not parsed_args.keep_short_lines
111
+ options.min_line_length = parsed_args.min_line_length
112
+ options.remove_whole_lines = not parsed_args.keep_bad_lines
113
+ options.remove_sections = not parsed_args.keep_sections
114
+ options.remove_footnotes_in_text = not parsed_args.keep_footnotes
115
+ options.replace_within_lines = not parsed_args.no_replacements
116
+ options.remove_within_lines = not parsed_args.keep_inline_patterns
117
+ options.contract_empty_lines = not parsed_args.keep_empty_lines
118
+ options.crimp_linebreaks = not parsed_args.no_crimp_linebreaks
119
+
120
+ # Load patterns from custom config or use defaults
121
+ if parsed_args.config:
122
+ try:
123
+ patterns = CleaningPatterns.from_yaml(parsed_args.config)
124
+ except Exception as e:
125
+ print(f"Error loading custom configuration: {e}", file=sys.stderr)
126
+ return 1
127
+ else:
128
+ patterns = get_default_patterns()
129
+
130
+ # Initialize the cleaner with patterns and configured options
131
+ cleaner = MarkdownCleaner(patterns=patterns, options=options)
132
+
133
+ try:
134
+ # Clean the markdown file
135
+ output_file = cleaner.clean_markdown_file(
136
+ input_file=parsed_args.input_file,
137
+ output_path=parsed_args.output_dir,
138
+ output_file=parsed_args.output
139
+ )
140
+ print(f"Cleaned markdown saved to: {output_file}")
141
+ return 0
142
+ except Exception as e:
143
+ print(f"Error: {e}", file=sys.stderr)
144
+ return 1
145
+
146
+
147
+ if __name__ == "__main__":
148
+ sys.exit(main())