Skip to content

Commit 1c408bc

Browse files
committed
refactor a bit to handle links between pages better
1 parent e3a73b3 commit 1c408bc

File tree

2 files changed

+74
-30
lines changed

2 files changed

+74
-30
lines changed

notion_docs_sync/__init__.py

+61-26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
from random import choice
44
from argparse import ArgumentParser
5+
from urllib.parse import urlparse
56

67
from notion.client import NotionClient
78
from notion.block import Block, PageBlock, CollectionViewBlock
@@ -194,35 +195,50 @@ def sync_markdown_blocks_to_block(markdown_blocks, block):
194195
c.remove()
195196

196197

197-
def sync_file_to_block(filename, block):
198+
def sync_file_to_block(filename, block, links : dict={}):
198199
logger.info(f"Syncing {filename} to block {block.id}")
199200

200201
with open(filename) as markdown_fd:
201202
contents = markdown_fd.read()
202203

203204
post = frontmatter.loads(contents)
204205

205-
markdown_blocks = convert(str(post))
206+
def resolve_link(target):
207+
try:
208+
parsed = urlparse(target)
206209

207-
sync_markdown_blocks_to_block(markdown_blocks, block)
210+
if parsed.scheme:
211+
return target
212+
except:
213+
pass
208214

215+
target_path = os.path.realpath(os.path.join(os.path.dirname(filename), target))
209216

210-
def sync_directory_to_block(directory, root_block):
211-
if not root_block.get(['format', 'block_locked'], default=False):
212-
root_block.set(['format', 'block_locked'], True)
217+
block = links.get(target_path)
218+
219+
if not block:
220+
return target
221+
222+
return block.get_browseable_url()
223+
224+
markdown_blocks = convert(str(post), link_resolver=resolve_link)
213225

226+
sync_markdown_blocks_to_block(markdown_blocks, block)
227+
228+
229+
def create_page_structure(directory, root_block):
214230
touched_pages = set()
215231

216-
index_path = os.path.join(directory, "index.md")
217-
readme_path = os.path.join(directory, "README.md")
232+
files_to_pages = dict()
233+
234+
index_path = os.path.realpath(os.path.join(directory, "index.md"))
235+
readme_path = os.path.realpath(os.path.join(directory, "README.md"))
218236

219237
# Do the index/readme first to ensure the correct sort order.
220238
if os.path.isfile(index_path):
221-
touched_pages.add(root_block.id)
222-
sync_file_to_block(index_path, root_block)
239+
files_to_pages[index_path] = root_block
223240
elif os.path.isfile(readme_path):
224-
touched_pages.add(root_block.id)
225-
sync_file_to_block(readme_path, root_block)
241+
files_to_pages[readme_path] = root_block
226242

227243
for path in os.listdir(directory):
228244
if path.startswith('.'):
@@ -238,29 +254,48 @@ def sync_directory_to_block(directory, root_block):
238254
if not block:
239255
continue
240256

241-
if not block.get(['format', 'block_locked'], default=False):
242-
block.set(['format', 'block_locked'], True)
257+
full_path = os.path.realpath(os.path.join(directory, path))
243258

244259
touched_pages.add(block.id)
245260

246-
full_path = os.path.join(directory, path)
261+
if os.path.isdir(full_path):
262+
files_to_pages.update(create_page_structure(full_path, block))
263+
else:
264+
files_to_pages[full_path] = block
265+
266+
return files_to_pages
267+
268+
269+
def sync_directory_to_block(directory, root_block):
270+
# Do Two Passes: First, create blocks for all files that need them
271+
# Keep track of absolute file path -> block
272+
logger.info("Creating page structure..")
273+
files_to_pages = create_page_structure(os.path.realpath(directory), root_block)
274+
275+
touched_pages = set(block.id for block in files_to_pages.values())
276+
277+
# Then, for iterate through every single page block created and:
278+
for full_path, block in files_to_pages.items():
279+
# Lock it
280+
if not block.get(['format', 'block_locked'], default=False):
281+
block.set(['format', 'block_locked'], True)
247282

248283
if block.icon is None:
249284
block.icon = random_emoji()
250285

251-
if os.path.isdir(full_path):
252-
sync_directory_to_block(full_path, block)
253-
else:
254-
sync_file_to_block(full_path, block)
286+
# Sync it.
287+
sync_file_to_block(full_path, block, links=files_to_pages)
288+
289+
# Sort it.
290+
move_pages_to_end(block)
255291

256-
# Any children that are pages under root_block but aren't in touched_pages should be pruned
257-
# And the pages linked within them should be moved to the tail.
258-
move_pages_to_end(root_block)
259-
for child in root_block.children:
260-
move_pages_to_end(child)
261-
if child.type == 'page' and child.id not in touched_pages:
262-
child.remove()
292+
# Clean it.
293+
for child in block.children:
294+
# Any children that are pages under block but aren't in touched_pages should be pruned
295+
if child.type == 'page' and child.id not in touched_pages:
296+
child.remove()
263297

298+
# Technologic.
264299

265300
def main():
266301
import sys

notion_docs_sync/markdown.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from notion.block import CodeBlock, DividerBlock, HeaderBlock, SubheaderBlock, \
55
SubsubheaderBlock, QuoteBlock, TextBlock, NumberedListBlock, \
66
BulletedListBlock, ImageBlock, CollectionViewBlock
7-
import mistletoe
7+
from mistletoe.block_token import Document
88
from mistletoe.base_renderer import BaseRenderer
99

1010

@@ -176,6 +176,10 @@ def as_inline_style_block(tokens, style, *style_args):
176176

177177

178178
class NotionRenderer(BaseRenderer):
179+
def __init__(self, link_resolver=(lambda path: path), *extras):
180+
super().__init__(*extras)
181+
self.__link_resolver = link_resolver
182+
179183
def __render_multiple(self, tokens):
180184
return flatten([self.render(t) for t in tokens])
181185

@@ -284,7 +288,11 @@ def render_strikethrough(self, token):
284288
return as_inline_style_block(self.__render_multiple(token.children), NOTION_STYLE_STRIKETHROUGH)
285289

286290
def render_link(self, token):
287-
return as_inline_style_block(self.__render_multiple(token.children), NOTION_STYLE_ANCHOR, token.target)
291+
return as_inline_style_block(
292+
self.__render_multiple(token.children),
293+
NOTION_STYLE_ANCHOR,
294+
self.__link_resolver(token.target)
295+
)
288296

289297
def render_escape_sequence(self, token):
290298
return self.__render_multiple(token.children)
@@ -306,5 +314,6 @@ def render_image(self, token):
306314
}
307315

308316

309-
def convert(markdown):
310-
return mistletoe.markdown(markdown, renderer=NotionRenderer)
317+
def convert(markdown, link_resolver=(lambda path: path)):
318+
with NotionRenderer(link_resolver=link_resolver) as renderer:
319+
return renderer.render(Document(markdown))

0 commit comments

Comments
 (0)