DEV Community

Muhammad Jazman
Muhammad Jazman

Posted on

Python file to create all [[link]].md with corresponding attribute url

as I'm currently heavy note-taking from coursera, with lots of module and activities, this python script is quite automate some of my load....

#!/usr/bin/env python3
"""
Create Obsidian link files from a markdown file with [[link]] references.
Extracts URLs from the markdown and creates individual .md files with URL frontmatter.
"""

import re
import os
from pathlib import Path


def parse_markdown_links(file_path):
    """
    Parse markdown file and extract [[link]] patterns with their associated URLs.

    Returns:
        list of tuples: (link_text, url)
    """
    links_with_urls = []

    with open(file_path, 'r', encoding='utf-8') as f:
        content = f.read()
        lines = content.split('\n')

    # Find all [[link]] patterns and their associated URLs
    for i, line in enumerate(lines):
        # Match [[text]] pattern
        match = re.search(r'\[\[([^\]]+)\]\]', line)
        if match:
            link_text = match.group(1)

            # Look for URL in the following lines (usually within next 2-3 lines)
            url = None
            for j in range(i + 1, min(i + 5, len(lines))):
                if lines[j].startswith('https://'):
                    url = lines[j].strip()
                    break

            links_with_urls.append((link_text, url))

    return links_with_urls


def create_link_files(links_with_urls, output_dir='.'):
    """
    Create .md files for each link with URL frontmatter.
    Only creates files that don't already exist.

    Args:
        links_with_urls: list of tuples (link_text, url)
        output_dir: directory to create files in
    """
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    created_count = 0
    skipped_count = 0

    for link_text, url in links_with_urls:
        # Create filename from link text
        filename = f"{link_text}.md"
        filepath = output_path / filename

        # Check if file already exists
        if filepath.exists():
            print(f"⊘ Skipped (exists): {filename}")
            skipped_count += 1
            continue

        # Create file with frontmatter
        if url:
            frontmatter = f"---\nurl: {url}\n---\n\n"
        else:
            frontmatter = "---\nurl: \n---\n\n"

        with open(filepath, 'w', encoding='utf-8') as f:
            f.write(frontmatter)

        print(f"✓ Created: {filename}")
        created_count += 1

    print(f"\n✅ Summary: {created_count} created, {skipped_count} skipped")
    return created_count, skipped_count


def main():
    import sys

    if len(sys.argv) < 2:
        print("Usage: python create_obsidian_links.py <markdown_file> [output_directory]")
        print("\nExample:")
        print("  python create_obsidian_links.py __02__.md ./links")
        sys.exit(1)

    md_file = sys.argv[1]
    output_dir = sys.argv[2] if len(sys.argv) > 2 else '.'

    # Check if input file exists
    if not os.path.exists(md_file):
        print(f"Error: File '{md_file}' not found")
        sys.exit(1)

    print(f"Parsing {md_file}...\n")

    # Parse and create files
    links = parse_markdown_links(md_file)
    print(f"Found {len(links)} links\n")

    create_link_files(links, output_dir)


if __name__ == '__main__':
    main()

Enter fullscreen mode Exit fullscreen mode

i.e:

add executable

m@m7320:~/Documents/Lund University - AI, Business & the Future of Work$ chmod +x ~/obsidian_links.py 
Enter fullscreen mode Exit fullscreen mode
m@m7320:~/Documents/Lund University - AI, Business & the Future of Work$ ~/obsidian_links.py __02__.md 
Parsing __02__.md...

Found 18 links

✓ Created: 2.1.Module 2, Introduction.md
✓ Created: 2.2.Digitalization.md
✓ Created: 2.3.AI and The Organization of Work with Samuel Engblom.md
✓ Created: 2.4.Business Models with Pelle Kimvall.md
✓ Created: 2.5.AI Strategy part 1 - Process.md
✓ Created: 2.6.AI Strategy part 2 - Data.md
✓ Created: 2.7.AI Strategy part 3 - Knowledge.md
✓ Created: 2.8.Implementing AI - Management Perspective with Joakim Wernberg.md
✓ Created: 2.9.Introducing AI in the Organization with Marcus Henriksson.md
✓ Created: 2.10.Purchasing AI.md
✓ Created: 2.11.Software & Competitiveness with Joakim Wernberg.md
✓ Created: 2.12.The Work Environment with Samuel Engblom.md
✓ Created: 2.13.Customer Strategy.md
✓ Created: 2.14.Human Resources.md
✓ Created: 2.15.Child Rights with Johan Grundström Eriksson.md
✓ Created: 2.16.Module 2, Summary.md
✓ Created: 2.17.What can AI do?.md
✓ Created: 2.18.Readings.md

✅ Summary: 18 created, 0 skipped
m@m7320:~/Documents/Lund University - AI, Business & the Future of Work$ ~/obsidian_links.py __03__.md 
Parsing __03__.md...

Found 15 links

✓ Created: 3.1.Module 3, Introduction.md
✓ Created: 3.2.Human Rights.md
✓ Created: 3.3.Electronic Surveillance in the Workplace.md
✓ Created: 3.4.Machine Ethics.md
✓ Created: 3.5.Algorithmic Bias with Jakob Svensson.md
✓ Created: 3.6.Experience the capabilities of electronic surveillance.md
✓ Created: 3.7.Child Rights Risks with Johan Grundström Eriksson.md
✓ Created: 3.8.Cybersecurity with Ulrik Franke.md
✓ Created: 3.9.HR Ethics with Björn Lorentzon.md
✓ Created: 3.10.Sustainability & Ethical Review with Anna Felländer.md
✓ Created: 3.11.Module 3, Summary.md
✓ Created: 3.12.Ethical AI review..md
✓ Created: 3.13.Ethical AI Health check.md
✓ Created: 3.14.Risks with AI.md
✓ Created: 3.15.Readings.md

✅ Summary: 15 created, 0 skipped
m@m7320:~/Documents/Lund University - AI, Business & the Future of Work$ ~/obsidian_links.py __04__.md 
Parsing __04__.md...

Found 16 links

✓ Created: 4.1.Module 4, Introduction.md
✓ Created: 4.2.A Theory of AI Job Replacement.md
✓ Created: 4.3.Competence Disruption.md
✓ Created: 4.4.Large Language Models - Definition & uses.md
✓ Created: 4.5.Large Language Models - Pitfalls.md
✓ Created: 4.6.Man or Machine with Joakim Wernberg.md
✓ Created: 4.7.AI Transformation with Fredrik Heintz.md
✓ Created: 4.8.AI in the Workplace - The Medium Term Perspective.md
✓ Created: 4.9.Apply to your own context.md
✓ Created: 4.10.The Future of Work with Johan Grundström Eriksson.md
✓ Created: 4.11.Interview with Hans Troiza from the global heavy-industry Alfa Laval.md
✓ Created: 4.12.Interview with Bella Funck from the start-up Tilda.md
✓ Created: 4.13.Module 4, Summary.md
✓ Created: 4.14.Future scenarios.md
✓ Created: 4.15.AI and the future of work.md
✓ Created: 4.16.Readings.md




Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
muhammad_jazman profile image
Muhammad Jazman
perl -i -pe 's/\[\[/ "[[1." . ++$i . "." /ge' __01__.md
perl -i -pe 's/\[\[/ "[[2." . ++$i . "." /ge' __02__.md
perl -i -pe 's/\[\[/ "[[3." . ++$i . "." /ge' __03__.md
perl -i -pe 's/\[\[/ "[[4." . ++$i . "." /ge' __04__.md
Enter fullscreen mode Exit fullscreen mode

quick and dirty way to add sequence of link from module index ... HTML 2 Markdown from coursera

and also this

perl -i -pe 's/(\[\[.*?\]\])/$1 =~ s\/: \/ - \/gr/ge' __00__.md
Enter fullscreen mode Exit fullscreen mode

to conver : into -