Notion.so Markdown Importer
An importer for Markdown files to Notion.so using 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
<img>tags. - Markdown frontmatter is preserved
- Local image references will be uploaded from relative URLs
- Image alts are loaded as captions instead of as
TextBlocks - 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 atpage-urlhas 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 atpage-url--html-img: Upload images that are memtioned in the HTML<img>tags.
Usage from script
pip install md2notion- In your Python file:
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="<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() for more.
from md2notion.upload import convert, uploadBlock
rendered = 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 (a BaseRenderer for 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).
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 upload
client = NotionClient(token_v2="<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 later
pageName = 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
Metadata
Release files for md2notion 2.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| md2notion-2.4.1.tar.gz | 13.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| md2notion-2.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.1 kB
Release files / md2notion-2.4.1.tar.gz
| Download URL | md2notion-2.4.1.tar.gz |
|---|---|
| Size | 13.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
54e8c438ff1cf1db5980b82910c6bf1807f02b874d38efae060fb2cfd4d3d62c
|
|
BLAKE2b-256 checksum How to use checksums |
6b55d697e4f0009cf8538e7129531138eab93050ffe8287f6476bce28479b9ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.7
|
Release files / md2notion-2.4.1-py3-none-any.whl
| Download URL | md2notion-2.4.1-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
accab0edb3ae05bbc08750bc2f1f2f3e358669c8490b4817f7a8afdcf56d4c3e
|
|
BLAKE2b-256 checksum How to use checksums |
ff52e586d3ea9270b2c43fc3f0077d4c882515626839b441ebe35a04081aa059
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.8.7
|
Security for md2notion 2.4.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.