You should start a blog. Having your own little corner of the internet is good for the soul!
Inspired by Simon Wilson. I decided to try to resurect my long discarded blog. I wrote 2 things that I think are somewhat interesting.
Here is the capture template
* %^{Title}
:PROPERTIES:
:CREATED: %T
:ATTRIBUTION: %^{Who should I attribute this to?}
:QUOTE: %^{Quote for this entry | nil}
:END:
%?
Here is the code in my .spacemacs that adds the template
(defun dotspacemacs/user-config ()
;; 2025-01-06 - Trying to setup a easier way to do quick blogs
(setq org-capture-templates
'(("f" "Found Blog Entry" entry (file+headline "~/blog/found.org" "Found")
(file "~/orgs/capture_templates/found.org")))))
Now I can simply type org-capture Enter f
to fill in this template and have it added to ~/blog/found.org
under the Found
root heading.
I then had Claude help me write a small script that basically parses every entry in ~/blog/found.org
and adds it as a markdown entry to my static blog. The code is as follows.
import sys
import os
from datetime import datetime
import orgparse
def create_markdown(node):
"""Convert an org node to markdown blog post content."""
# Extract link and title from heading
title = node.get_heading().split(']')[1].strip() if '][' in node.get_heading() else node.get_heading()
link = node.get_heading().split(']')[0].strip() if '][' in node.get_heading() else node.get_heading()
# Get properties
created = node.properties.get('CREATED', '').strip('<>')
quote = node.properties.get('QUOTE', '')
categories = node.properties.get('CATEGORIES', '')
# Format date for filename and frontmatter
date_obj = datetime.strptime(created, '%Y-%m-%d %a %H:%M')
formatted_date = date_obj.strftime('%Y-%m-%d %H:%M:00')
filename = date_obj.strftime('%Y-%m-%d') + '-' + title.lower().replace(' ', '-') + '.md'
categories_formated = [s for s in categories.split(",") if s]
if link and 'link' not in categories:
categories_formated.append('link')
categories_formated = [f'"{s}"' for s in categories_formated]
# Create frontmatter
md_content = (
'{\n'
':layout :post\n'
f':title "{title}"\n'
f':date "{formatted_date}"\n'
f':categories [{",".join(categories_formated)}]\n'
'}\n\n'
)
# Add quote if exists
if quote and quote != 'nil':
md_content += f'<blockquote>{quote}</blockquote>\n\n'
# Add main content
md_content += node.get_body()
return filename, md_content
def process_org_file(org_path, output_dir):
"""Process org file and create markdown files."""
if not os.path.exists(org_path):
print(f"Error: Input file '{org_path}' not found.")
return False
os.makedirs(output_dir, exist_ok=True)
try:
root = orgparse.load(org_path)
except Exception as e:
print(f"Error parsing org file: {e}")
return False
# Process each node that has the right depth (2 in your case, for ++)
for node in root[1:]: # Skip the root node
if node.level == 2: # Only process ++ entries
try:
filename, md_content = create_markdown(node)
output_path = os.path.join(output_dir, filename)
with open(output_path, 'w') as f:
f.write(md_content)
print(f"Created: {output_path}")
except Exception as e:
print(f"Error processing entry {node.get_heading()}: {e}")
continue
return True
def main():
if len(sys.argv) != 3:
print("Usage: ./write_found_to_md.py <org_file> <output_directory>")
sys.exit(1)
org_path = sys.argv[1]
output_dir = sys.argv[2]
if process_org_file(org_path, output_dir):
print("Conversion completed successfully.")
else:
print("Conversion failed.")
sys.exit(1)
if __name__ == "__main__":
main()
Humorously, I'll have to look a little harder to figure out how to actually make my title into a link. But I think it is a good start. :]