first commit
This commit is contained in:
commit
e27893ad81
2 changed files with 114 additions and 0 deletions
29
README.md
Normal file
29
README.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Journal
|
||||
|
||||
A simple markdown journal entry generator, with the following folder structure:
|
||||
|
||||
```
|
||||
.
|
||||
└2025
|
||||
└01
|
||||
├01_monday.md
|
||||
└02_tuesday.md
|
||||
...
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
./journal.py [option]
|
||||
```
|
||||
|
||||
| `option` | Action |
|
||||
| -------- | -------------------------------- |
|
||||
| empty | Create an entry for the next day |
|
||||
| `-t` | Create an entry for today's date |
|
||||
| `-n` | Create an entry for the next day |
|
||||
|
||||
## Requirements
|
||||
|
||||
* Python 3.6 or higher
|
||||
* `EDITOR` environment variable defined
|
||||
85
journal.py
Executable file
85
journal.py
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
from datetime import date, timedelta
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
# --- Helper functions ---
|
||||
|
||||
def ordinal(n: int) -> str:
|
||||
"""Return ordinal suffix for a given day number."""
|
||||
if 10 <= n % 100 <= 20:
|
||||
suffix = 'th'
|
||||
else:
|
||||
suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, 'th')
|
||||
return f"{n}{suffix}"
|
||||
|
||||
def month_name(month: int) -> str:
|
||||
return date(2000, month, 1).strftime("%B")
|
||||
|
||||
def get_latest_entry(base_path: Path):
|
||||
"""Return the latest existing journal file, or None if none exist."""
|
||||
entries = sorted(base_path.glob("*/*/*.md"))
|
||||
return entries[-1] if entries else None
|
||||
|
||||
def next_date_from_latest(latest_path: Path):
|
||||
"""Compute the next date after the latest entry."""
|
||||
parts = latest_path.stem.split("_")[0].split("-")
|
||||
# stem example: 04_tuesday -> day=4
|
||||
# full path: year/month/date_day.md
|
||||
year = int(latest_path.parent.parent.name)
|
||||
month = int(latest_path.parent.name)
|
||||
day = int(parts[0])
|
||||
d = date(year, month, day)
|
||||
return d + timedelta(days=1)
|
||||
|
||||
def make_entry_path(base_path: Path, entry_date: date):
|
||||
year = entry_date.year
|
||||
month = entry_date.month
|
||||
day = entry_date.day
|
||||
weekday = entry_date.strftime("%A").lower()
|
||||
folder = base_path / f"{year}" / f"{month:02d}"
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
filename = f"{day:02d}_{weekday}.md"
|
||||
return folder / filename
|
||||
|
||||
def write_entry_header(path: Path, entry_date: date):
|
||||
if path.exists():
|
||||
return # Don't overwrite
|
||||
header = f"# {entry_date.strftime('%A')}, {ordinal(entry_date.day)} {entry_date.strftime('%B %Y')}\n\n"
|
||||
path.write_text(header, encoding="utf-8")
|
||||
|
||||
# --- Main logic ---
|
||||
|
||||
def main():
|
||||
base_path = Path.cwd()
|
||||
|
||||
# Parse args
|
||||
arg = sys.argv[1] if len(sys.argv) > 1 else None
|
||||
latest = get_latest_entry(base_path)
|
||||
|
||||
if arg == "-t":
|
||||
entry_date = date.today()
|
||||
elif arg == "-n":
|
||||
if latest:
|
||||
entry_date = next_date_from_latest(latest)
|
||||
else:
|
||||
entry_date = date.today()
|
||||
else:
|
||||
# Default behavior
|
||||
if latest:
|
||||
entry_date = next_date_from_latest(latest)
|
||||
else:
|
||||
entry_date = date.today()
|
||||
|
||||
entry_path = make_entry_path(base_path, entry_date)
|
||||
write_entry_header(entry_path, entry_date)
|
||||
|
||||
# Open in text editor
|
||||
editor = os.environ.get("EDITOR", "nano")
|
||||
subprocess.run([editor, str(entry_path)])
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue