Skip to content

Commit

Permalink
refactor + taglist added
Browse files Browse the repository at this point in the history
  • Loading branch information
dwrolvink committed Oct 24, 2021
1 parent 99dde82 commit b072eed
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 15 deletions.
22 changes: 19 additions & 3 deletions obsidianhtml/MarkdownPage.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ def __init__(self, src_path, src_folder_path, file_tree):
self.codelines = []

# Load contents of entrypoint and strip frontmatter yaml.
page = frontmatter.load(str(src_path))
self.page = page.content
self.yaml = page
with open(src_path, encoding="utf-8") as f:
self.metadata, self.page = frontmatter.parse(f.read())

def SetDestinationPath(self, dst_folder_path, entrypoint_src_path):
"""Set destination path of the converted file. Both full and relative paths are set."""
Expand Down Expand Up @@ -64,6 +63,23 @@ def RestoreCodeSections(self):
for i, value in enumerate(self.codelines):
self.page = self.page.replace(f'%%%codeline-placeholder-{i}%%%', f"`{value}`")

def AddToTagtree(self, tagtree, url=''):
if 'tags' not in self.metadata:
return

if url == '':
url = str(self.dst_path)

for tag in self.metadata['tags']:
ctagtree = tagtree
for n, subtag in enumerate(tag.split('/')):
if subtag not in ctagtree['subtags'].keys():
ctagtree['subtags'][subtag] = {'notes': [], 'subtags': {}}
ctagtree = ctagtree['subtags'][subtag]

if n == (len(tag.split('/')) - 1):
ctagtree['notes'].append(url)

def ConvertObsidianPageToMarkdownPage(self, dst_folder_path, entrypoint_path, include_depth=0):
"""Full subroutine converting the Obsidian Code to proper markdown. Linked files are copied over to the destination folder."""
# -- Load contents
Expand Down
11 changes: 11 additions & 0 deletions obsidianhtml/PicknickBasket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class PicknickBasket:
files = None
tagtree = None
config = None
paths = None
html_template = None

def __init__(self, config, paths):
self.config = config
self.tagtree = {'notes': [], 'subtags': {}}
self.paths = paths
71 changes: 64 additions & 7 deletions obsidianhtml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@
import markdown # convert markdown to html
import yaml
import urllib.parse # convert link characters like %
import frontmatter

from .MarkdownPage import MarkdownPage
from .MarkdownLink import MarkdownLink
from .lib import DuplicateFileNameInRoot, GetObsidianFilePath, image_suffixes
from .PicknickBasket import PicknickBasket

# Open source files in the package
import importlib.resources as pkg_resources
from . import src # relative-import the *package* containing the templates
from . import src


# python run.py 'C:\Users\Installer\OneDrive\Obsidian\Notes' "C:\Users\Installer\OneDrive\Obsidian\Notes\Devfruits Notes.md" "output/md" "output/html" "Devfruits/Notes"

def recurseObisidianToMarkdown(page_path_str, paths, files, conf):
def recurseObisidianToMarkdown(page_path_str, pb):
paths = pb.paths
files = pb.files
conf = pb.config

# Convert path string to Path and do a double check
page_path = Path(page_path_str).resolve()
if page_path.exists() == False:
Expand All @@ -28,6 +35,9 @@ def recurseObisidianToMarkdown(page_path_str, paths, files, conf):
md = MarkdownPage(page_path, paths['obsidian_folder'], files)
md.ConvertObsidianPageToMarkdownPage(paths['md_folder'], paths['obsidian_entrypoint'])

# Add yaml frontmatter back in
md.page = (frontmatter.dumps(frontmatter.Post("", **md.metadata))) + '\n' + md.page

# -- Save file
# Create folder if necessary
md.dst_path.parent.mkdir(parents=True, exist_ok=True)
Expand All @@ -49,10 +59,14 @@ def recurseObisidianToMarkdown(page_path_str, paths, files, conf):
# Convert the note that is linked to
if conf['toggles']['verbose_printout']:
print(f"converting {files[link_path]['fullpath']} (parent {page_path})")
recurseObisidianToMarkdown(files[link_path]['fullpath'], paths, files, conf)
recurseObisidianToMarkdown(files[link_path]['fullpath'], pb)

def ConvertMarkdownPageToHtmlPage(page_path_str, paths, files, html_template, conf):
def ConvertMarkdownPageToHtmlPage(page_path_str, pb):
page_path = Path(page_path_str).resolve()
paths = pb.paths
files = pb.files
html_template = pb.html_template
conf = pb.config

if page_path.exists() == False:
return
Expand Down Expand Up @@ -171,6 +185,8 @@ def ConvertMarkdownPageToHtmlPage(page_path_str, paths, files, html_template, co
md.dst_path.parent.mkdir(parents=True, exist_ok=True)
html_dst_path_posix = md.dst_path.as_posix()[:-3] + '.html'

md.AddToTagtree(pb.tagtree, md.dst_path.relative_to(paths['html_output_folder']).as_posix()[:-3] + '.html')

# Write html
with open(html_dst_path_posix, 'w', encoding="utf-8") as f:
f.write(html)
Expand All @@ -195,7 +211,38 @@ def ConvertMarkdownPageToHtmlPage(page_path_str, paths, files, html_template, co
if conf['toggles']['verbose_printout']:
print("html: converting ", files[link_path]['fullpath'], " (parent ", md.src_path, ")")

ConvertMarkdownPageToHtmlPage(files[link_path]['fullpath'], paths, files, html_template, conf)
ConvertMarkdownPageToHtmlPage(files[link_path]['fullpath'], pb)

def recurseTagList(tagtree, tagpath, pb):
html_url_prefix = pb.config['html_url_prefix']
tag_dst_path = pb.paths['html_output_folder'].joinpath(f'{tagpath}index.html').resolve()
tag_dst_path_posix = tag_dst_path.as_posix()
rel_dst_path_as_posix = tag_dst_path.relative_to(pb.paths['html_output_folder']).as_posix()

# Compile markdown
md = ''
if len(tagtree['subtags'].keys()) > 0:
md += '# Subtags\n'
for key in tagtree['subtags'].keys():
rel_key_path_as_posix = recurseTagList(tagtree['subtags'][key], tagpath + key + '/', pb)
md += f'- [{key}](/{rel_key_path_as_posix})' + '\n'

if len(tagtree['notes']) > 0:
md = '\n# Notes\n'
for note in tagtree['notes']:
md += f'- [{note.replace(".html", "")}]({html_url_prefix}/{note})\n'

# Compile html
html_body = markdown.markdown(md, extensions=['extra', 'codehilite', 'toc'])
html_body = html_body.replace('<a href="/not_created.html">', '<a href="/not_created.html" class="nonexistent-link">')
html = pb.html_template.replace('{content}', html_body).replace('{title}', pb.config['site_name']).replace('{html_url_prefix}', pb.config['html_url_prefix'])

# Write file
tag_dst_path.parent.mkdir(parents=True, exist_ok=True)
with open(tag_dst_path_posix, 'w', encoding="utf-8") as f:
f.write(html)

return rel_dst_path_as_posix

def main():
# Config
Expand Down Expand Up @@ -276,6 +323,8 @@ def main():
paths['md_folder'].mkdir(parents=True, exist_ok=True)
paths['html_output_folder'].mkdir(parents=True, exist_ok=True)

# Make "global" object that we can pass so functions
pb = PicknickBasket(conf, paths)

# Convert Obsidian to markdown
# ------------------------------------------
Expand All @@ -290,10 +339,12 @@ def main():

files[path.name] = {'fullpath': str(path), 'processed': False}

pb.files = files

# Start conversion with entrypoint.
# Note: this will mean that any note not (indirectly) linked by the entrypoint will not be included in the output!
print(f'> COMPILING MARKDOWN FROM OBSIDIAN CODE ({str(paths["obsidian_entrypoint"])})')
recurseObisidianToMarkdown(str(paths['obsidian_entrypoint']), paths, files, conf)
recurseObisidianToMarkdown(str(paths['obsidian_entrypoint']), pb)


# Convert Markdown to Html
Expand Down Expand Up @@ -321,8 +372,14 @@ def main():
rel_path_posix = path.relative_to(paths['md_folder']).as_posix()
files[rel_path_posix] = {'fullpath': str(path.resolve()), 'processed': False}

pb.files = files
pb.html_template = html_template

# Start conversion from the entrypoint
ConvertMarkdownPageToHtmlPage(str(paths['md_entrypoint']), paths, files, html_template, conf)
ConvertMarkdownPageToHtmlPage(str(paths['md_entrypoint']), pb)

# Create tag page
recurseTagList(pb.tagtree, 'tags/', pb)

# Add Extra stuff to the output directories
# ------------------------------------------
Expand Down
7 changes: 4 additions & 3 deletions pypi_readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ To convert your notes, you need to point to your notes folder, and to one note t
Only notes that are found by following links recursively, starting with the entrypoint, will be converted!

**Changelog**:
0.0.4: Added the option to use a custom html template, and to export the packaged template.
0.0.3: Updated readme file to work with pypi.
0.0.2: Updated readme file to work with pypi.
- 0.0.5: Tag list added.
- 0.0.4: Added the option to use a custom html template, and to export the packaged template.
- 0.0.3: Updated readme file to work with pypi.
- 0.0.2: Updated readme file to work with pypi.
6 changes: 5 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ This will make sure future runs of obsidianhtml will use your custom template (p

# Features
## Not supported
- Tags (you can use them in Obsidian, but they are ignored in the conversion)
- Inline tags (you can use them in Obsidian, but they are ignored in the conversion). Frontmatter tags are converted to a tag list, see below.
- Possibly a lot more

## Conversion of Obsidian type links
Expand Down Expand Up @@ -115,6 +115,10 @@ When using the format `![[Name of note]]`, the contents of the note will be incl

This package also supports partial inclusions. You can use this by writing `![[Name of note#Chapter Name]]`. In this case, only that chapter and its contents until the next chapter of the same depth is included. See also [Example Website#partial-code-inclusion](https://obsidian-html.github.io/#!partial-code-inclusion).

## Frontmatter Tag list
Inline tags are excluded, but those listed in the yaml frontmatter are compiled into a list.
When running your website, go to `/tags` to view the tag list. [Example](https://obsidian-html.github.io/tags/).

## Basic Templating
All generated html code will be wrapped by the html code in `src/template.html`. This template points to `src/main.css`.
Change this code *in the `/src` folder* to have the changes persist across runs of the code (output will be overwritten).
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = obsidianhtml
version = 0.0.4
version = 0.0.5
summary = Converts Obsidian notes into proper markdown and HTML
long_description = file: pypi_readme.md
home-page = https://github.com/obsidian-html/obsidian-html
Expand Down

0 comments on commit b072eed

Please sign in to comment.