|
| 1 | +import re |
| 2 | +import argparse |
| 3 | + |
| 4 | +def transform_markdown(markdown: str) -> str: |
| 5 | + # Define a mapping from original keywords to new formats |
| 6 | + mapping = { |
| 7 | + 'hint' : 'tip', |
| 8 | + 'flag': 'tip', |
| 9 | + 'comment': 'info', |
| 10 | + 'question': 'info', |
| 11 | + 'option': 'info', |
| 12 | + 'todo': 'warning', |
| 13 | + 'danger': 'danger', |
| 14 | + 'caution': 'danger' |
| 15 | + } |
| 16 | + |
| 17 | + # Define the regex pattern for matching the entire block |
| 18 | + # This pattern captures three groups: |
| 19 | + # 1. (\w+): Matches any word (keyword) following '####' and captures it as the block type. |
| 20 | + # 2. (.*?): Matches the title after the keyword, using non-greedy matching to stop at the first newline. |
| 21 | + # 3. ((?:>.*?\n|>\s*\n)+): Matches the content block, which consists of lines starting with '> '. |
| 22 | + # - (?:>.*?\n): Matches lines starting with '>', followed by any characters, ending in newline. |
| 23 | + # - (?:>\s*\n): Matches lines that contain only '>' followed by optional whitespace and a newline. |
| 24 | + # - +: Ensures that one or more such lines are matched. |
| 25 | + pattern = r'> #### (\w+)::(.*?)\n((?:>.*?\n|>\s*\n)+)' |
| 26 | + |
| 27 | + # Function to replace matched patterns with the desired format |
| 28 | + def replace_block(match): |
| 29 | + block_type = match.group(1) # Extract block type (any keyword) |
| 30 | + title = match.group(2).strip() # Extract the title |
| 31 | + new_format = mapping.get(block_type, 'info') # Look up the new format based on the block type using the mapping |
| 32 | + content = match.group(3).replace('>\n', '\n').replace('> ', '').strip() # Clean content lines |
| 33 | + return f':::{new_format}[{title}]\n{content}\n:::' # Format block |
| 34 | + |
| 35 | + transformed_markdown = re.sub(pattern, replace_block, markdown, flags=re.DOTALL) |
| 36 | + return transformed_markdown |
| 37 | + |
| 38 | +def main(input_file, output_file=None, inplace=False): |
| 39 | + # Read the content of the input markdown file |
| 40 | + with open(input_file, 'r', encoding='utf-8') as infile: |
| 41 | + markdown_content = infile.read() |
| 42 | + |
| 43 | + # Transform the content using the transform_markdown function |
| 44 | + transformed_content = transform_markdown(markdown_content) |
| 45 | + |
| 46 | + # Check if inplace editing is enabled |
| 47 | + if inplace: |
| 48 | + # Write the transformed content back to the input file |
| 49 | + with open(input_file, 'w', encoding='utf-8') as outfile: |
| 50 | + outfile.write(transformed_content) |
| 51 | + elif output_file: |
| 52 | + # Write the transformed content to the specified output file |
| 53 | + with open(output_file, 'w', encoding='utf-8') as outfile: |
| 54 | + outfile.write(transformed_content) |
| 55 | + else: |
| 56 | + # Print the transformed content to stdout |
| 57 | + print(transformed_content) # Print to stdout if no output file is specified |
| 58 | + |
| 59 | +if __name__ == '__main__': |
| 60 | + # Set up command line argument parsing |
| 61 | + parser = argparse.ArgumentParser(description='Transform markdown sections into a new format.') |
| 62 | + parser.add_argument('input_file', type=str, help='Path to the input markdown file') |
| 63 | + parser.add_argument('-o', '--output_file', type=str, help='Path to the output markdown file') |
| 64 | + parser.add_argument('-i', '--inplace', action='store_true', help='Edit the input file in place') # Short flag for in-place editing |
| 65 | + |
| 66 | + # Parse the command line arguments |
| 67 | + args = parser.parse_args() |
| 68 | + |
| 69 | + # Call the main function with parsed arguments |
| 70 | + main(args.input_file, args.output_file, args.inplace) |
0 commit comments