Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cobertos/md2notion
A better Notion.so Markdown importer
https://github.com/cobertos/md2notion
markdown notion python python3
Last synced: 3 months ago
JSON representation
A better Notion.so Markdown importer
- Host: GitHub
- URL: https://github.com/cobertos/md2notion
- Owner: Cobertos
- License: mit
- Archived: true
- Created: 2019-12-01T01:39:55.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-11-02T06:15:32.000Z (about 1 year ago)
- Last Synced: 2024-09-24T19:54:46.915Z (4 months ago)
- Topics: markdown, notion, python, python3
- Language: Python
- Homepage:
- Size: 467 KB
- Stars: 656
- Watchers: 5
- Forks: 65
- Open Issues: 29
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
Awesome Lists containing this project
README
### This package is package is no longer maintained. I stopped using Notion.so some time ago and switched to Obsidian due to persistant problems with then Notion API.
---
# Notion.so Markdown Importer
An importer for Markdown files to [Notion.so](https://notion.so) using [`notion-py`](https://github.com/jamalex/notion-py)
It provides these features over Notion.so's Markdown importer:
* Picking a Notion.so page to upload to (instead of them all uploading to the root)
* Code fences keep their original language (or as close as we can match it)
* Code fences are formatted properly
* Inline HTML is preserved
* (Optionally) Upload images that are memtioned in the HTML `` tags.
* Markdown frontmatter is preserved
* Local image references will be uploaded from relative URLs
* Image alts are loaded as captions instead of as `TextBlock`s
* Handles nested lists properly
* Among other improvements...Supports Python 3.6+
## Usage from CLI
* `pip install md2notion`
* Then run like `python -m md2notion [token_v2] [page-url] [...markdown_path_glob_or_url]`
* The markdown at the given path will be added as a new child to the Notion.so note at `page-url`There are also some configuration options:
* `--clear-previous`: If a child of the note at `page-url` has the same name as what you're uploading, it will first be removed.
* `--append`: Instead of making a new child, it will append the markdown contents to the note at `page-url`
* `--html-img`: Upload images that are memtioned in the HTML `` tags.## Usage from script
* `pip install md2notion`
* In your Python file:
```python
from notion.client import NotionClient
from notion.block import PageBlock
from md2notion.upload import upload# Follow the instructions at https://github.com/jamalex/notion-py#quickstart to setup Notion.py
client = NotionClient(token_v2="")
page = client.get_block("https://www.notion.so/myorg/Test-c0d20a71c0944985ae96e661ccc99821")with open("TestMarkdown.md", "r", encoding="utf-8") as mdFile:
newPage = page.children.add_new(PageBlock, title="TestMarkdown Upload")
upload(mdFile, newPage) #Appends the converted contents of TestMarkdown.md to newPage
```If you need to process `notion-py` block descriptors after parsing from Markdown but before uploading, consider using `convert` and `uploadBlock` separately. Take a look at [`upload.py#upload()`](https://github.com/Cobertos/md2notion/blob/master/md2notion/upload.py) for more.
```python
from md2notion.upload import convert, uploadBlockrendered = convert(mdFile)
# Process the rendered array of `notion-py` block descriptors here
# (just dicts with some properties to pass to `notion-py`)# Upload all the blocks
for blockDescriptor in rendered:
uploadBlock(blockDescriptor, page, mdFile.name)
```If you need to parse Markdown differently from the default, consider subclassing [`NotionPyRenderer`](https://github.com/Cobertos/md2notion/blob/master/md2notion/NotionPyRenderer.py) (a [`BaseRenderer` for `mistletoe`](https://github.com/miyuchina/mistletoe)). You can then pass it to `upload(..., notionPyRendererCls=NotionPyRenderer)` as a parameter.
## Example, Custom Hexo Importer
Here's an example that imports a Hexo blog (slghtly hacky).
```python
import io
import os.path
import glob
from pathlib import Path
from notion.block import PageBlock
from notion.client import NotionClient
from md2notion.upload import uploadclient = NotionClient(token_v2="")
page = client.get_block("https://www.notion.so/myorg/Test-c0d20a71c0944985ae96e661ccc99821")for fp in glob.glob("../source/_posts/*.md", recursive=True):
with open(fp, "r", encoding="utf-8") as mdFile:
#Preprocess the Markdown frontmatter into yaml code fences
mdStr = mdFile.read()
mdChunks = mdStr.split("---")
mdStr = \
f"""```yaml
{mdChunks[1]}
`` `{'---'.join(mdChunks[2:])}
"""
mdFile = io.StringIO(mdStr)
mdFile.__dict__["name"] = fp #Set this so we can resolve images laterpageName = os.path.basename(fp)[:40]
newPage = page.children.add_new(PageBlock, title=pageName)
print(f"Uploading {fp} to Notion.so at page {pageName}")
#Get the image relative to the markdown file in the flavor that Hexo
#stores its images (in a folder with the same name as the md file)
def convertImagePath(imagePath, mdFilePath):
return Path(mdFilePath).parent / Path(mdFilePath).stem / Path(imagePath)
upload(mdFile, newPage, imagePathFunc=convertImagePath)
```## Contributing
See [CONTRIBUTING.md](https://github.com/Cobertos/md2notion/blob/master/CONTRIBUTING.md)