Coder Social home page Coder Social logo

sillsdev / docu-notion Goto Github PK

View Code? Open in Web Editor NEW
142.0 8.0 26.0 1.41 MB

Download Notion pages as markdown and image files, preserving hierarchy and enabling workflow properties. Works with Docusaurus.

License: MIT License

TypeScript 99.03% JavaScript 0.19% CSS 0.78%
documentation docusaurus markdown notion notion-api

docu-notion's Introduction

docu-notion

docu-notion lets you use Notion as your editor for Docusaurus. Using Notion instead of raw markdown files means that you don't have to teach non-developers how to make git commits and pull requests. It also allows you to leverage Notion's database tools to control workflow, Notion's commenting feature to discuss changes, etc.

Example Site: https://sillsdev.github.io/docu-notion-sample-site/

Instructions

1. Set up your documentation site

First, prepare your markdown-based static file system like Docusaurus. For a shortcut with github actions, search, and deployment to github pages, you can just copy this template.

If you do not use the above sample, you will need to manually tell your docusaurus.config.js about docu-notion-styles.css. See Styling and Layout. This stylesheet enables various Notion things to look right, for example multi-column layouts. By default, docu-notion will copy this file to the css/ directory. There is an option to change that location if you want.

2. In Notion, duplicate the docu-notion template

Go to this template page. Duplicate it into your own workspace. You can name it anything you like, e.g. "Documentation Root".

3. Create a Notion Integration

In order for docu-notion to read your site via Notion's API, you need to create what Notion calls an "integration". Follow these instructions to make an integration and get your token. Remember to limit your integration to "READ" access.

4. Connect your Integration

Go to the page that will be the root of your site. This page should have, as direct children, your "Outline" (required) and "Database" (optional) pages. Follow these instructions.

image

5. Add your pages under your Outline page

Currently, docu-notion expects that each page has only one of the following: sub-pages, links to other pages, or normal content. Do not mix them. You can add content pages directly here, but then you won't be able to make use of the workflow features. If those matter to you, instead make new pages under the "Database" and then link to them in your outline pages.

6. Pull your pages

First, determine the ID of your root page by clicking "Share" and looking at the url it gives you. E.g. https://www.notion.so/hattonjohn/My-Docs-0456aa5842946PRETEND4f37c97a0e5 means that the ID is 0456aa5842946PRETEND4f37c97a0e5.

Try it out:

npx @sillsdev/docu-notion -n secret_PRETEND123456789PRETEND123456789PRETEND6789 -r 0456aa5842946PRETEND4f37c97a0e5"

Likely, you will want to store these codes in your environment variables and then use them like this:

(windows)
npx @sillsdev/docu-notion -n %MY_NOTION_TOKEN% -r %MY_NOTION_DOCS_ROOT_PAGE_ID%
(linux / mac)
npx @sillsdev/docu-notion -n $MY_NOTION_TOKEN -r $MY_NOTION_DOCS_ROOT_PAGE_ID

NOTE: In the above, we are using npx to use the latest docu-notion. A more conservative approach would be to npm i cross-var @sillsdev/docu-notion and then create a script in your package.json like this:

 "scripts": {
     "pull": "cross-var docu-notion -n %DOCU_NOTION_INTEGRATION_TOKEN% -r %DOCU_NOTION_ROOT_PAGE%"
  }

and then run that with npm run pull.

7. Commit

Most projects should probably commit the current markdown and image files each time you run docu-notion.

Note that if you choose not to commit, the workflow feature (see below) won't work for you. Imagine the case where a document that previously had a Status property of Publish now has a different status. You probably want to keep publishing the old version until the new one is ready. But if you don't commit files, your CI system (e.g. Github Actions) won't have the old version around, so it will disappear from your site.

Using a Notion database for workflow

One of the big attractions of Notion for large documentation projects is that you can treat your pages as database items. The advantage of this is that they can then have metadata properties that fit your workflow. For example, we use a simple kanban board view to see where each page is in our workflow:

image

docu-notion supports this by letting you link to database pages from your outline.

image

Page properties

image

Note For some reason Notion only allows properties on pages that are part of a database. So if you create pages directly in the Outline, you won't be able to fill in any of these properties, other than the page title.

Slugs

By default, pages will be given a slug based on the Notion ID. For a human-readable URL, add a notion property named Slug to your database pages and enter a value in there that will work well in a URL. That is, no spaces, ?, #, /, etc.

See Options to require slugs in Notion.

Known Limitations

docu-notion is not doing anything smart with regards to previously Published but now not Published documents. All it does is ignore every Notion document that doesn't have status == Publish. So if the old version of the document is still in your file tree when your static site generator (e.g. Docusaurus) runs, then it will appear on your website. If it isn't there, it won't. If you rename directories or move the document, docu-notion will not realize this and will delete the previously published markdown file.

Text Localization

Localize your files in Crowdin (or whatever) based on the markdown files, not in Notion. For how to do this with Docusaurus, see Docusaurus i18n.

Screenshot Localization

The only way we know of to provide localization of image in the current Docusaurus (2.0) is to place the images in the same directory as the markdown, and use relative paths for images. Most projects probably won't localize every image, so we also need a way to "fall back" to the original screenshot when the localized one is missing. docu-notion facilitates this. If no localized version of an image is available, docu-notion places a copy of the original image into the correct location.

So how do you provide these localized screenshot files? Crowdin can handle localizing assets, and in the future we may support that. For now, we currently support a different approach. If you place for example fr https:\\imgur.com\1234.png in the caption of a screenshot in Notion, docu-notion will fetch that image and save it in the right place to be found when in French mode. Getting URLs to screenshots is easy with screenshot utilities such as Greenshot that support uploading to imgur. Note that docu-notion stores a copy of all images in your source tree, so you wouldn't lose the images if imgur were to go away.

NOTE: that as far as I can tell, when you run docusaurus start docusaurus 2.0 offers the language picker but it doesn't actually work. So to test out the localized version, do docusaurus build followed by docusaurus serve.

NOTE: if you just localize an image, it will not get picked up. You also must localize the page that uses the image. Otherwise, Docusaurus will use the English document and when that asks for ./the-image-path, it will find the image there in the English section, not your other language section.

Automated builds with Github Actions

Here is a working Github Action script to copy and customize.

Command line

Usage: docu-notion -n <token> -r <root> [options]

Options:

flag required? description
-n, --notion-token <string> required notion api token, which looks like secret_3bc1b50XFYb15123RHF243x43450XFY33250XFYa343
-r, --root-page <string> required The 31 character ID of the page which is the root of your docs page in notion. The code will look like 9120ec9960244ead80fa2ef4bc1bba25. This page must have a child page named 'Outline'
-m, --markdown-output-path <string> Root of the hierarchy for md files. WARNING: node-pull-mdx will delete files from this directory. Note also that if it finds localized images, it will create an i18n/ directory as a sibling. (default: ./docs)
-t, --status-tag <string> Database pages without a Notion page property 'status' matching this will be ignored. Use '*' to ignore status altogether. (default: Publish)
--locales <codes> Comma-separated list of iso 639-2 codes, the same list as in docusaurus.config.js, minus the primary (i.e. 'en'). This is needed for image localization. (default: [])
-l, --log-level <level> Log level (choices: info, verbose, debug)
-i, --img-output-path <string> Path to directory where images will be stored. If this is not included, images will be placed in the same directory as the document that uses them, which then allows for localization of screenshots.
-p, --img-prefix-in-markdown <string> When referencing an image from markdown, prefix with this path instead of the full img-output-path. Should be used only in conjunction with --img-output-path.
--require-slugs If set, docu-notion will fail if any pages it would otherwise publish are missing a slug in Notion.
--image-file-name-format <format> choices:
  • default: {page slug (if any)}.{image block ID}
  • content-hash: Use a hash of the image content.
  • legacy: Use the legacy (before v0.16) method of determining file names. Set this to maintain backward compatibility.
All formats will use the original file extension.
-h, --help display help for command

Plugins

If your project needs some processing that docu-notion doesn't already provide, you can provide a plugin that does it. See the plugin readme.

Callouts ➜ Admonitions

To map Notion callouts to Docusaurus admonitions, ensure the icon is for the type you want.

  • ℹ️ ➜ note
  • 📝➜ note
  • 💡➜ tip
  • ❗➜ info
  • ⚠️➜ caution
  • 🔥➜ danger

The default admonition type, if no matching icon is found, is "note".

Known Workarounds

Start a numbered list at a number other than 1

In Notion, make sure the block is "Text," not "Numbered List".

  • But make sure the number does NOT have a space in front of it. This can/will cause issues with sub-list items.
  • One way to get Notion to let you do this:
    • Create a numbered list item where the text duplicates the number you want. Convert that numbered list item to "Text."
    • i.e. Type "1. 1. Item one." Notion makes the first "1." into a number in a list. When you convert back to "Text," you're left with plain text "1. Item one."

docu-notion's People

Contributors

andrew-polk avatar franciscomoretti avatar hatton avatar jellejurre avatar johnthomson avatar nateowami avatar scottxchoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docu-notion's Issues

[Feature] Variable column width in PDF output

Background
Side-by-side presentations of text and images are more effective in training presentation contexts. The texts accompanying images frequently require less vertical space than the images.

Problem

  • Images in columns that are not equal-width are rendered full-width in PDF output. (Images in one of two equal-width columns are rendered properly.)

Desired behavior
Respect the column widths specified in the Notion authoring environment in PDF output.

Screenshots
Notion editing environment:
Columns editing
PDF output:
no columns

Support links to other documents

In Notion, you can link to another notion page. When this is converted to markdown, currently we just keep that same link to https://notion.so/.... Instead, we should convert it to a link to the equivalent markdown page.

Notion page not found

Describe the bug
`Notion page not found "${uuidToId(pageId)}") ^ Error: Notion page not found "454a4e53ed0a46f6bd431b07328e8941".
I always met this error, and was stuck at stage 2.

image

Only several pages that I can load in my directory tree. ;(
Any help is appreciated!!

Text in lists can break mdx parser, should be escaped for html safety

image

docu-notion makes this into

 <li parentName="ol"><strong parentName="li">{`Dropbox`}</strong>{` will ask whether you want to “Remove `}<book title>{` from your Dropbox account and all devices?” Click “Move out of Dropbox”. If you do not want to see such notices in the future, you can tick the box “Don’t ask me this again”.`}</li>

Instead, the text should be encoded so that it doesn't mess up the html parser.
Q: what if there is content in there that we do want to be parsed?

Notion is exporting non-breaking spaces that were not in the original text

Describe the bug
I updated Crowdin with the Notion text as download on the command line.
Crowdin is now complaining that translations are missing several non-breaking spaces. There were no non-breaking spaces in the original text.

Reproduction Steps

  1. Go to Crowdin
  2. Look for strings that are still in English (which shows they have been updated)
  3. Translate the string, or accept a previous translation.
  4. Crowdin complains that there are missing non-breaking spaces.
    • seems to happen with bold text and ">".

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
https://www.notion.so/ltuse/2-Organising-your-desktop-629dc633009a45f8a2ad0618b99701a7

At least one of these:
see screen shots

Expected behavior
If the text has not been edited then it should accept the previous translation.
The addition of a non-breaking space is logical but it is not easily keyboarded. My concern is that I identified that I have 837 list items, and most have at least one bolded item. So that means at the very least 837 retranslations could be needed for each language. Fortunately only two languages are being translated at the moment not the planned 30 languages.

Screenshots
Crowdin error about 4 missing non-breaking spaces.
I think I can see four faint grey lines as indicated by the arrows.
image

Screenshot localisation

I am about to recreate our paratext-manual site. The information on the README file about localisation is out of date. Do you have any updates to your process/suggestions for localising screenshots?

Thanks

Release gives errors about crowdin dependencies

Problem
I tried to clear out some files tonight, but the release failed with two errors when trying to install crowdin dependencies.

Error 1

Line 26
image
After a lengthy exchange with Crowdin Chat support we finally found out that there was a problem with the package.json.
"crowdin": "crowdin", should be "@crowdin/cli": "3.13.0",

Then I got the next error.

Error 2

Line 27

error Package "//pretranslate" refers to a non-existing file '"//pretranslate@  used to re-apply translations when files are renamed or reorganized"'.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Error: Process completed with exit code 1.

Crowdin support confirms that it refers to a non-existing file. But not one of theirs. They recommended I check with you.

I notice the next two lines 28-29 look more like the commands on the page they sent me to. But they are commands not dependencies.
https://crowdin.github.io/crowdin-cli/commands/crowdin-pre-translate/

    "//pretranslate": "  used to re-apply translations when files are renamed or reorganized",
    "crowdin:pretranslate": "crowdin pre-translate --method tm --translate-untranslated-only --translate-with-perfect-match-only --verbose",
    "crowdin:sync": "docusaurus write-translations && crowdin upload sources --delete-obsolete && crowdin download"

Line 27 look more like a comment to me, so I tried deleting it. However, it resulted in the following error.

error An unexpected error occurred: "https://registry.yarnpkg.com/crowdin:pretranslate: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/home/runner/work/paratext-manual/paratext-manual/yarn-error.log".

Sorry, no sign on the yarn-error.log on GitHub.

I tried but that's as far as I can go. I hope it makes sense to you.

docu-notion doesn't handle images embedded as [data:image...]

I'm not sure we need/want to fix this. (But I want to document it.)
Even Notion's own UI doesn't show the images or give any way to modify or delete them; but at least it doesn't crash.
If you manage to get one of these into your Notion page (through some kind of import), Notion will export it; then docu-notion will crash with

/home/runner/work/.../node_modules/node-fetch/lib/index.js:1331
  		throw new TypeError('Only HTTP(S) protocols are supported');
          ^
  TypeError: Only HTTP(S) protocols are supported
      at getNodeRequestOptions (/home/runner/work/.../node_modules/node-fetch/lib/index.js:1331:9)
      at /home/runner/work/.../node_modules/node-fetch/lib/index.js:1432:19
      at new Promise (<anonymous>)
      at fetch (/home/runner/work/.../node_modules/node-fetch/lib/index.js:1429:9)
      at /home/runner/work/.../node_modules/docu-notion/dist/images.js:134:57
      at Generator.next (<anonymous>)
      at /home/runner/work/.../node_modules/docu-notion/dist/images.js:31:[71](https://github.com/sillsdev/.../actions/runs/4982783840/jobs/8918938268#step:5:73)
      at new Promise (<anonymous>)
      at __awaiter (/home/runner/work/.../node_modules/docu-notion/dist/images.js:27:12)
      at readPrimaryImage (/home/runner/work/.../node_modules/docu-notion/dist/images.js:133:12)

[Feature] Variable column width in HTML output

Background
Side-by-side presentations of text and images are more effective in training presentation contexts. The texts accompanying images frequently require less vertical space than the images.

Problem

  • HTML output is limited to equal-width columns (as detailed here ), Text space is inefficiently used and it is harder for users to see relevant detail in images.

Desired behavior
Respect the column widths specified in the Notion authoring environment in HTML output.

Screenshots
Notion editing environment:
Columns editing
HTML output:
columns HTML output

Links don't work in numbered lists or callouts

Describe the bug
Links in either numbered lists or callouts are not converted by docu-notion.

Reproduction Steps
In Notion

  • Create a numbered list block
  • Insert a link (to a https address)
    • Link is displayed in Notion

Do a Release

  • Result has no link

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
https://jennibeadle.notion.site/5-BC1-Basic-checks-9a9d6657a78c4dacaaae3a1af028df41
(See just before 5.2 - I tested :::tip ...:::, callout, numbered list, and quote)

URL of a docusuarus site showing the resulting page
https://sillsdev.github.io/paratext-manual/05.BC1/

Expected behavior
Obviously, I expect to have a link to click on (as shown in Notion)

Screenshots
Various blocks Admonitions - Markdown works, quote works but callout and numbered list don't convert.
image

Manually Numbered lists work
Appendix is a text block with manual numbered and works.
image

Just output changed files

Describe the problem
A clear and concise description of what the bug is.
It takes docu-notion about 30 minutes to process my 126 files and then another 15 minutes to run the release action. If I just change one or two files it would be good to update only the changed files and not have to reprocess all the files.

Titles with slashes give slug error

Give a page with name Publish as Audio/Video Errata, we get the error

The slug we computed looks invalid: /Advanced Topics/Technical Errata/publish-as-audio%2Fvideo-errata.

Admonitions with alternative name not converting as expected

Describe the bug
Custom name of admonition is not converted correctly.
In Docusaurus, if you want to give an admonition a custom name you can add it after the usual name. It will give you the same colour box but with the custom name.

Reproduction Steps

  1. Type ::: followed by admonition name, then add custom name

:::info Upgrade
In Paratext 9.3 (and above) you can use the main Paratext menu to arrange windows by rows and columns.
:::
In the example above, I expecte to get a blue info box but with the name Upgrade.
See 2.5 this example.

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
https://www.notion.so/ltuse/2-Organising-your-desktop-629dc633009a45f8a2ad0618b99701a7?pvs=9

At least one of these:

  1. URL of a docusuarus site showing the resulting page
    https://sillsdev.github.io/paratext-manual/2.OD
  2. URL of a markdown of the resulting page
    https://manual.paratext.org/Training-Manual/Stage-1/OD

Expected behavior
In the example above, I would get a blue info box but with the name Upgrade.
See 2.5 this example.

Screenshots
Deployed from Notion:
image
[This is similar when incorrectly used :::note Upgrade.]

Expected (deployed from markdown text):
image

Additional context
I keyed it in the markdown ::: as I didn't think Notion callouts would be able to change the heading/name.

Support links to sidebar sections

In Notion, you can of course link to one of the pages that serve as sections in the outline. But when docu-notion sees such a link, it doesn't find the page, and logs

Could not find the target of this link. Note that links to outline sections are not supported. ded7393e-8194-4a68-ac04-81839baadac3

Docusaurus does now support links to sidebar sections that have auto-generated table of contents for the direct children. So if a project turned on that capability, it would make sense for docu-notion to be able to generate the link to get to it.

Tests

This project started as a proof of concept. If it keeps going well, it will need tests.

Socket connection timeout always appears

image

docu-notion version 0.11.0
undefined
Did not find configuration file, using defaults.
Active plugins: [standardEscapeHtmlBlockModifier, standardHeadingTransformer, standardColumnTransformer, standardColumnListTransformer, DownloadImagesToRepo, standardCalloutTransformer, standardTableTransformer, standardNumberedListTransformer, standard internal link conversion, standard external link conversion, imgur, gif, youtube, vimeo]
Options:{
  "markdownOutputPath": "./docs",
  "statusTag": "Publish",
  "locales": [],
  "notionToken": "sec...",
  "rootPage": "583600dfe9ce40123169e7be0a264f7c",
  "logLevel": "debug"
}
Connecting to Notion...
Stage 1: walk children of the page named 'Outline', looking for pages...
/Users/xugao/Developer/my/projects/webstorm/docusaurus-notion/node_modules/.pnpm/[email protected]/node_modules/node-fetch/lib/index.js:1491
                        reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
          ^
FetchError: request to https://api.notion.com/v1/pages/583600d3210f2916917be0a232f7c failed, reason: Socket connection timeout
    at ClientRequest.<anonymous> (/Users/xugao/Developer/my/projects/webstorm/docusaurus-notion/node_modules/.pnpm/[email protected]/node_modules/node-fetch/lib/index.js:1491:11)
    at ClientRequest.emit (node:events:511:28)
    at ClientRequest.emit (node:domain:489:12)
    at TLSSocket.socketErrorListener (node:_http_client:495:9)
    at TLSSocket.emit (node:events:511:28)
    at TLSSocket.emit (node:domain:489:12)
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at processTicksAndRejections (node:internal/process/task_queues:82:21) {
  type: 'system',
  errno: 'ERR_SOCKET_CONNECTION_TIMEOUT',
  code: 'ERR_SOCKET_CONNECTION_TIMEOUT'
}

I simply looked at the source code and it should have nothing to do with the timeoutMs parameter in the @notionhq/client package, because it defaults to 60s, and this error will sometimes be reported within 10s, but I am sure it is related to https://api.notion.com/ The network is definitely fine.

Convert Notion video uploads into ReactPlayer links like you do for YouTube embeds

Describe the bug
When converting videos uploaded to notion, they are rendered like

[image](https://s3.{region}.amazonaws.com/secure.notion-static.com/.../{filename}.mp4?...)

** Reproduction Steps **
Just try to add a video upload into Notion (not a Youtube link) and try to do conversion using yarn pull

Expected behavior
Render similar to YouTube links, i.e.

<ReactPlayer controls url="https://s3.{region}.amazonaws.com/secure.notion-static.com/.../{filename}.mp4?..." />

I tested this solution by manually editing the .md files and it seems to work.

Date for generated markdown?

How do have a date for a given notion generated page/blog entry?

Maybe it could be a notion doc property? But what about overwrites? What then is the correct date?

Basically, I want my docu-notion blog entries to have the correct date, but I'm not sure the best way to do this.

Probably best is if docu-notion reads a date field, and prefixes the output with YYYY-MM-DD- as recommended by docusaurus.

Could a plugin rename the output files?

[Problem] Simple links to pages are wrong

image

produced

[link_to_page](b8264953-9f32-4aa3-bd61-d9395d0b62f3)

The correct answer would have been something like

[Oranges][/oranges]

(the "oranges" page had a slug, so the link should use that, not the id, which won't work in docusaurus).

[Problem] Simple links to headings don't make it out to the markdown

Simple links to Headings don't make it out to the markdown. This input

image

Produces markdown without the link.

---
title: Links to Headings no slug
sidebar_position: 9
slug: /59e9b092-2e9c-40b4-8f0e-8ab2d50033aa
---

# Heading One {#2d84f4557d76435183031d202a1afe7b}


 


[link_to_page](b8264953-9f32-4aa3-bd61-d9395d0b62f3)


This is an [inline link to that heading one](/59e9b0922e9c40b48f0e8ab2d50033aa#2d84f4557d76435183031d202a1afe7b) above.

Notice that the link to "Heading One" is just dropped.

(There is another problem here, that the "Oranges" of the final link is labeled instead as "link_to_page", but that will need its own issue)

Links to document open the Notion file not the MD file.

Describe the bug
What is the best way to add links?
If I add the link in Notion then when I click on the link it takes me to the Notion file not the webpage.
I have many links in my project which worked well in raw MD files but my conversion process (Word add-in) has hard-coded them to a file on my c: drive so I need to replace them.

** Reproduction Steps **
Goto https://sillsdev.github.io/paratext-manual/Overview/
Click on link to the right of the chapter name (e.g. 1.Intro)
The notion page opens.

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
https://jennibeadle.notion.site/00-Overview-3ce84f9ca3264aed8532489c0574f95c
(see links in Introduction)

At least one of these:

  1. URL of a docusuarus site showing the resulting page
    https://sillsdev.github.io/paratext-manual/Overview/
    (see links in Introduction)

Expected behavior
When I click on the link on a page I expect to go to the appropriate page on the website.
So if I clicked on 1.Intro I expect to go to
https://sillsdev.github.io/paratext-manual/288f2a75-e689-4ec7-98f8-17f982c15e17/
not the Notion page.

Screenshots
If applicable, add screenshots to help explain your problem.

Choose the link
image

Expected result
image

Actual result
image

Additional context
Add any other context about the problem here.

Release fails

Describe the bug
Release Actions always fail.

Reproduction Steps

  1. Go to gihhub page
  2. Chose Actions
  3. Click Release
  4. Click Runworkflow
  5. Choose Run workflow

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:

A code block showing a console error

$ cross-var npx docu-notion -n $PARATEXT_NOTION_INTEGRATION_TOKEN -r $PARATEXT_NOTION_ROOT_PAGE -m ./docs -i ./static/notion_imgs -p /notion_imgs/
docu-notion version 0.[11](https://github.com/sillsdev/paratext-manual/actions/runs/4956719287/jobs/8867508101#step:5:12).0
undefined
Connecting to Notion...
Stage 1: walk children of the page named 'Outline', looking for pages...
  Looking for children and links from /Paratext Manual
  Looking for children and links from /Outline
  Looking for children and links from /Training manual
  Looking for children and links from /Training-manual/Stage 1 - Drafting
  Looking for children and links from /Training-manual/Stage 2 - Team Checking
  @notionhq/client warn: request fail {
    code: 'notionhq_client_response_error',
    message: 'Request to Notion API failed with status: 504'
  }
  /home/runner/work/paratext-manual/paratext-manual/node_modules/@notionhq/client/src/errors.ts:[24](https://github.com/sillsdev/paratext-manual/actions/runs/4956719287/jobs/8867508101#step:5:25)8
    return new UnknownHTTPResponseError({
           ^
  UnknownHTTPResponseError: Request to Notion API failed with status: 504

Expected behavior
Expect the Release to run and deploy

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
It originally crashed t Stage 3. As I was about to write-up this error I noticed a "-" in the title of Stage 3 I deleted it and tried again now it fails on the previous stage.

BTW the command line gets further but still fails.

Stage 2: convert 127 Notion pages to markdown and save locally...
Reading & converting page /Training-manual/Stage-1---Drafting/Stage 1 – Overview (/Stage-1)
Reading & converting page /Training-manual/Stage-1---Drafting/2. Organising your desktop (/2.OD)
Reading & converting page /Training-manual/Stage-1---Drafting/3. Assignments and progress (/3.PP1)
C:\Users\jjpdq\Documents\paratext-manual\node_modules\node-fetch\lib\index.js:1331
                throw new TypeError('Only HTTP(S) protocols are supported');
        ^
TypeError: Only HTTP(S) protocols are supported
    at getNodeRequestOptions (C:\Users\jjpdq\Documents\paratext-manual\node_modules\node-fetch\lib\index.js:1331:9)
    at C:\Users\jjpdq\Documents\paratext-manual\node_modules\node-fetch\lib\index.js:1432:19
    at new Promise (<anonymous>)
    at fetch (C:\Users\jjpdq\Documents\paratext-manual\node_modules\node-fetch\lib\index.js:1429:9)
    at C:\Users\jjpdq\Documents\paratext-manual\node_modules\docu-notion\dist\images.js:134:57
    at Generator.next (<anonymous>)
    at C:\Users\jjpdq\Documents\paratext-manual\node_modules\docu-notion\dist\images.js:31:71
    at new Promise (<anonymous>)
    at __awaiter (C:\Users\jjpdq\Documents\paratext-manual\node_modules\docu-notion\dist\images.js:27:12)
    at readPrimaryImage (C:\Users\jjpdq\Documents\paratext-manual\node_modules\docu-notion\dist\images.js:133:12)

Support Docusaurus Admonitions

Notion has Callouts, and you can set the icon of them. But there is no way to set the color.

Let's map 5 of these icons to their equivalent Docusaurus Admonitions.

Then you can make a callout, set its icon, and get the fully styled admonition equivalent.

Search only works on front page

Describe the bug
The search add-in only finds results when used from the front page (intro page with slug /) and only hits on that page.

** Reproduction Steps **

  • Go to the intro page

  • Click in the search box

  • Type a word

    • only finds words on that page.
  • Go to another page

  • Click in the search box

  • Start to type a word

  • No results error

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:

URL of a docusuarus site showing the resulting page
https://sillsdev.github.io/paratext-manual/00-list-of-features/

Expected behavior
Expect to get results from all the pages.

Screenshots
Screenshot shows no result even when several results clearly seen on page
image

Additional context
I checked the docusaurus.config.js and removed the comment on languages for the plug-in. It looks identical to my other working site.

Make GitHub Actions see Errors (and Warnings)

Describe the bug
Any warnings in "Build Github Pages" of the Release are not shown to the user.
It was only in trouble-shooting another site that I discovered them in the release.

Reproduction Steps

  1. Go to GitHub pages for your site
  2. Click on Actions tab
  3. Click on a previous Release

image

4. Click on the **Release** on the next page

image

5. Expand "Build Github Pages"
  1. Look for Warnings. (see screenshot below)

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
https://jennibeadle.notion.site/Stage-3-Preparing-for-the-Consultant-check-b2e2a08bd0f44a7da06333d46250331c

URL of GitHub showing the warnings
https://github.com/sillsdev/paratext-manual/actions/runs/4060888616/jobs/6990404972

URL of Docusaurus page
https://sillsdev.github.io/paratext-manual/Stage-3

Expected behavior
If there are warnings, the user should be informed.
The Release ran without any errors. So I was most surprised to stumble across the warnings.

Screenshots
Screenshot show warnings
Iimage

Numbered lists don't continue

Describe the bug
Numbered lists restart at 1 after subheading even when given a specific starting number after the heading.
Having just looked at the Notion markdown, I think it may be a Notion bug not a docu-notion bug.

Reproduction Steps
I have 25 chapters in my Paratext Manual. In the overview I break them up into sections but need the sequential numbering to continue so it shows correct chapter number.
Add a numbered list with headings.
Edit each list item after the heading with the number to continue.
Notion displays correctly.
But the resulting page restarts the numbering.

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
Notion: https://jennibeadle.notion.site/Overview-of-Training-Manual-3ce84f9ca3264aed8532489c0574f95c
Resulting page: https://sillsdev.github.io/paratext-manual/Overview/

Expected behavior
Numbering should continue (as per my other Docusaurus site.
https://manual.paratext.org/Training-Manual/Overview

Notion markdown
The notion markdown still has 1.

### Stage 1 Drafting

1. 2. **[OD** – Organising your desktop](https://sillsdev.github.io/paratext-manual/2.OD)
2. **[PP1** – Project plan and progress](https://sillsdev.github.io/paratext-manual/3.PP1)

I added the 2. to specify to continue from 2 but it still has the 1.
I corrected the markdown and pasted it again but it added the 1. again.

Screenshots
In Notion: showing the continuer set
image

Result of Docu-notion (showing restart as 1):
image

Site using Markdown (sequential):
image

Additional context
I searched for possible solutions.
https://stackoverflow.com/questions/18088955/markdown-continue-numbered-list/22138846#22138846
suggested putting a blank link before the element (in their case a code block) but had no effect.

Links to videos

Describe the bug
Links to videos have changed in Notion. I used to be able to insert a clickable link to a video. Notion now embeds the video and shows a very large preview. How do I get back to the clickable link?

Reproduction Steps

  1. I deleted the link for the embedded video.
  2. I inserted it again and asked for a bookmark.
    • The preview is smaller but I get a warning on release (see 4.)
  3. Go to Github and run a release
  4. Release fails (for other reasons) and gives warnings
    Release[standardExternalLinkConversion] Found Notion "Bookmark" link. In Notion this would show as an embed. The best docu-notion can do at the moment is replace "Bookmark" with the actual URL: [https://vimeo.com/368328862](https://vimeo.com/368328862)

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
Since the release fails, I can't show a URL with the problem

At least one of these:

  1. URL of a docusaurus site showing the issue (embedded videos)
    https://sillsdev.github.io/paratext-manual/2.OD
    https://sillsdev.github.io/paratext-manual/9.GL (blank space)
  2. URL of Notion page (with original markdown and bookmarks)
    https://www.notion.so/ltuse/2-Organising-your-desktop-629dc633009a45f8a2ad0618b99701a7
  3. URL of a docusuarus site showing the desired page https://manual.paratext.org/Training-Manual/Stage-1/OD

Expected behavior
Desired behaviour is clickable links to videos (with no previews) as shown in the manual.paratext.org site.
But if the bookmarks won't work then the vimeo link would be better.

Only (re)Publish if the Status is "Publish"

We should leave the previous version of the document in place if the current version has a Status that is not Publish.

This will require not deleting the destination docs directory, and that will require that we notice what documents are no longer in Notion at all, so that we can delete them.

Latex Rendering Problem

Problem

Bug

Latex code is not properly rendered. For example, if you enter the following code "$$x$$", this code is only converted to "x".

Solution

But, I solved this problem myself. First, you must modify the existing version of notion-to-md package to the latest version "3.1.1". (23.08.13)

Second, the existing return statements of the doNotionToMarkdown function in the transforms.js file have to modified to return markdown.parent;

Any update on crowdin support?

I am testing crowdin support. Docusaurus.io gives the CLI commands which work from my computer.

Are there any plans to make Actions for crowdin to work on github repositories from Notion?

Timeouts

Despite 8a4383a which I hoped would deal with this, we still sometimes get

  Reading & converting page /Release-Notes/Older Release Notes (/older-release-notes)
  @notionhq/client warn: request fail {
    code: 'service_unavailable',
    message: 'Request timed out waiting to connect to a database. Please try again later.'
  }
  /home/runner/work/bloom-docs/bloom-docs/node_modules/@notionhq/client/src/errors.ts:240
      return new APIResponseError({
             ^
  APIResponseError: Request timed out waiting to connect to a database. Please try again later.
      at buildRequestError (/home/runner/work/bloom-docs/bloom-docs/node_modules/@notionhq/client/src/errors.ts:240:12)
      at Client.request (/home/runner/work/bloom-docs/bloom-docs/node_modules/@notionhq/client/src/Client.ts:188:32)
      at processTicksAndRejections (node:internal/process/task_queues:95:5) {
    code: 'service_unavailable',
    status: 503,
    headers: Headers {
      [Symbol(map)]: [Object: null prototype] {
        date: [Array],
        'content-type': [Array],
        'content-length': [Array],
        connection: [Array],
        'x-powered-by': [Array],
        etag: [Array],
        vary: [Array],
        'cf-cache-status': [Array],
        'set-cookie': [Array],
        server: [Array],
        'cf-ray': [Array]
      }
    },
    body: '{"object":"error","status":503,"code":"service_unavailable","message":"Request timed out waiting to connect to a database. Please try again later."}'
  }
  error Command failed with exit code 1.
  info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Not showing the correct node-pull version

Currently, we always get

Notion-Pull version 0.0.0

I confirmed that the package.json that comes with npm is getting the correct number, so I don't what the problem is.

Source files for Crowdin?

I know you don't handle localisation, but where do I find the source files from Notion so I can upload to Crowdin for translation?

I tried using docu-notion on the command line to pull the files down to a repository in my computer, but all the extra Notion features are lost, particularly the side by side text and images. That makes me wonder about the output of Crowdin and whether I have any hope of getting the same layout in my translations. Have I just wasted a week rearranging my source files?

Do a better job of cleaning up obsolete files

If a page is no longer published or the folder name changes, the image files stick around. I'm not sure if the issue is specific to images.
We should probably delete any folder which has no .md files left after the current cleanup runs.

Generate sidebar file in order to preserve Notion Outline ordering

If you use Docusaurus's auto-generated sidebar, it orders categories alphabetically:

Notion:
image

Docusaurus site:
image

So while we currently get the order of individual pages correct (using sidebar_position), we don't have a way of also controlling the order of the categories .

If docu-notion could generate the sidebar itself, then sites could use that to match the order of categories in the Notion source outline.

Feature: mermaid conversion

Notion has recently added pretty awesome integration with mermaid:

image

What is also super great that I used is that you can add click handlers in the mermaid definition that link directly to other notion documents, creating visual, clickable dependencies between documents.

I create these diagrams as "synced blocks" allowing me to embed the same diagram in the relevant notion documents.

What I would like, and can make an attempt to implement this myself, is:

  1. Process notion mermaid code blocks, extract the mermaid definition, and convert to markdown. This is actually super basic, it's just directly extracting the mermaid definition and pasting in a markdown mermaid block.

My question is, before I start: would is also be possible to implement the click handlers? The links are notion document URLs, and these would have to be converted to markdown links that works with docusaurus.

Support Notion Synced Blocks

Describe the bug
Synced blocks that are linked to the original are not rendered. The original synced block is rendered.

** Reproduction Steps **

https://www.notion.so/metapages/Facts-mermaid-63f6f281a33649cc9dfabb86d26ad829

The first mermaid diagram is not a synced block, and renders fine.

The second block is a synced block, and renders fine in this page, but another page has a linked to that synced mermaid block:

https://www.notion.so/metapages/Introduction-to-docu-notion-779f83504bd94642a9b87b2afc810a97

Expected behavior
Linked synced blocks show the exact contents of the original synced block

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

Enhancement request: Link to a specific heading in a document

At present links to documents are supported but only to the whole document. It would be nice to link to a specific heading either in the same document or another document.

How to do it in Docusaurus
Docusaurus allows this by adding a code to the (destination) heading {#...} and then including that code in the link.
For example, see https://manual.paratext.org/Training-Manual/Stage-1/OD

In chapter 2 under 2.3 Create a new text layout I have a link to section 2.5
... ≡ Paratext menu, under (Paratext > Open, select several resources, choose to open as Text collection. See [2.5]

Heading 2.5 is coded as:
### 2.5 Open resources in a Text collection {#25}
The link is coded as:
See [2.5] (/Training-Manual/02-Stage-1/2.OD.md#25)
(the link is broken to display the coding)

Note: I have the code without decimal points otherwise it didn't work reliably.

Docusaurus documentation
see https://docusaurus.io/docs/markdown-features/toc#example-subsubsection-1-a-ii for a discussion on setting an explicit heading id.

Document localization of pages

I see that the demo page has a language picker but it does not have much effect apart from changing the admonition label.

Is it possible to localize pages ? In the code it looks like only image localization is supported

Markdown only output as [object Object]

Describe the bug
I just get a [object Object] output for content. Frontmatter outputs correctly.

Here's a log from running a pull:

[markdown from page]
[
  {
    "object": "block",
    "id": "008e6c99-1d98-4f75-aaca-744801bcfac0",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "image",
    "image": {
      "caption": [],
      "type": "file",
      "file": {
        "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject",
        "expiry_time": "2023-06-16T11:50:17.899Z"
      }
    }
  },
  {
    "object": "block",
    "id": "d0274585-7976-48e6-b7e2-a394b7912454",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "(credit: Pixabay, license: free ",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "(credit: Pixabay, license: free ",
          "href": null
        },
        {
          "type": "text",
          "text": {
            "content": "Pixabay license",
            "link": {
              "url": "https://pixabay.com/service/license/"
            }
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Pixabay license",
          "href": "https://pixabay.com/service/license/"
        },
        {
          "type": "text",
          "text": {
            "content": ")",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": ")",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "4d821dab-0f9d-4436-b4dd-9fac66dc3818",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "95f25605-f73d-4c13-94e7-217df35e0888",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "I feel like oranges are better than ",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "I feel like oranges are better than ",
          "href": null
        },
        {
          "type": "text",
          "text": {
            "content": "apples",
            "link": {
              "url": "/5b03cfe124544d00b4ea6ad6c7bc3c94?pvs=25"
            }
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "apples",
          "href": "/5b03cfe124544d00b4ea6ad6c7bc3c94?pvs=25"
        },
        {
          "type": "text",
          "text": {
            "content": " but less reliable.",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": " but less reliable.",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "70831bcd-ad0d-4472-8c9d-fa2489cc437b",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "5184b67c-4eb1-491e-bc6c-aa3ea6935cfc",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "image",
    "image": {
      "caption": [],
      "type": "file",
      "file": {
        "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject",
        "expiry_time": "2023-06-16T11:50:17.901Z"
      }
    }
  },
  {
    "object": "block",
    "id": "051f9371-8a52-475f-b792-a45a694b0837",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "(credit: Pixabay, license: free ",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "(credit: Pixabay, license: free ",
          "href": null
        },
        {
          "type": "text",
          "text": {
            "content": "Pixabay license",
            "link": {
              "url": "https://pixabay.com/service/license/"
            }
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Pixabay license",
          "href": "https://pixabay.com/service/license/"
        },
        {
          "type": "text",
          "text": {
            "content": ")",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": ")",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "6bec66a4-4295-4d2f-abdf-85b88f2befa9",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "heading_1",
    "heading_1": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "Heading 1",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Heading 1",
          "href": null
        }
      ],
      "is_toggleable": false,
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "8778a6b9-1bf4-4117-9f5d-7c8c82658a97",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "image",
    "image": {
      "caption": [],
      "type": "file",
      "file": {
        "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject",
        "expiry_time": "2023-06-16T11:50:17.901Z"
      }
    }
  },
  {
    "object": "block",
    "id": "949378ee-4424-41ca-a659-b086b6808a7a",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "(credit: Pixabay, license: free ",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "(credit: Pixabay, license: free ",
          "href": null
        },
        {
          "type": "text",
          "text": {
            "content": "Pixabay license",
            "link": {
              "url": "https://pixabay.com/service/license/"
            }
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Pixabay license",
          "href": "https://pixabay.com/service/license/"
        },
        {
          "type": "text",
          "text": {
            "content": ")",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": ")",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "beaf239d-281a-42d9-af91-aa7747cfd534",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "heading_2",
    "heading_2": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "Heading 2",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Heading 2",
          "href": null
        }
      ],
      "is_toggleable": false,
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "4d4b2057-14fa-4c5e-ab3d-4cf85ec1e871",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "image",
    "image": {
      "caption": [],
      "type": "file",
      "file": {
        "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject",
        "expiry_time": "2023-06-16T11:50:17.904Z"
      }
    }
  },
  {
    "object": "block",
    "id": "e26c0115-e3fd-478c-8834-55e1abc30fd8",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "(credit: Pixabay, license: free ",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "(credit: Pixabay, license: free ",
          "href": null
        },
        {
          "type": "text",
          "text": {
            "content": "Pixabay license",
            "link": {
              "url": "https://pixabay.com/service/license/"
            }
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Pixabay license",
          "href": "https://pixabay.com/service/license/"
        },
        {
          "type": "text",
          "text": {
            "content": ")",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": ")",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "93b61249-55dc-4620-a205-d79b71328d48",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "heading_3",
    "heading_3": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "Heading 3",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Heading 3",
          "href": null
        }
      ],
      "is_toggleable": false,
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "71451880-a19a-44aa-8410-b99001e2cf5b",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "Normal text",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Normal text",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "82400e21-8775-49fc-a8f5-2b5cab94ce95",
    "parent": {
      "type": "page_id",
      "page_id": "277e9eb0-3b0e-4e5e-9183-8b836fda2855"
    },
    "created_time": "2023-06-13T04:26:00.000Z",
    "last_edited_time": "2023-06-13T04:26:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [],
      "color": "default"
    }
  }
]
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[registering custom transform]
standardHeadingTransformer for DN_heading_1
[registering custom transform]
standardHeadingTransformer for DN_heading_2
[registering custom transform]
standardHeadingTransformer for DN_heading_3
[registering custom transform]
standardColumnTransformer for column
[registering custom transform]
standardColumnListTransformer for column_list
[registering custom transform]
DownloadImagesToRepo for image
[registering custom transform]
standardCalloutTransformer for callout
[registering custom transform]
standardTableTransformer for table
[registering custom transform]
standardNumberedListTransformer for numbered_list_item
[notion to MD conversion of ]
image with plugin: DownloadImagesToRepo
[processImageBlock]
{"caption":[],"type":"file","file":{"url":"https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject","expiry_time":"2023-06-16T11:50:17.899Z"}}
Adding image static/notion_imgs/2091252224.png
[notion to MD conversion of ]
image with plugin: DownloadImagesToRepo
[processImageBlock]
{"caption":[],"type":"file","file":{"url":"https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject","expiry_time":"2023-06-16T11:50:17.901Z"}}
Replacing image static/notion_imgs/2091252224.png
[notion to MD conversion of ]
DN_heading_1 with plugin: standardHeadingTransformer
[headingTransformer, markdown of a heading before adding id]
# Heading 1
[notion to MD conversion of ]
image with plugin: DownloadImagesToRepo
[processImageBlock]
{"caption":[],"type":"file","file":{"url":"https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject","expiry_time":"2023-06-16T11:50:17.901Z"}}
Replacing image static/notion_imgs/2091252224.png
[notion to MD conversion of ]
DN_heading_2 with plugin: standardHeadingTransformer
[headingTransformer, markdown of a heading before adding id]
## Heading 2
[notion to MD conversion of ]
image with plugin: DownloadImagesToRepo
[processImageBlock]
{"caption":[],"type":"file","file":{"url":"https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7ff88f88-dfa2-4c9b-8beb-31df3a9b0b9c/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230616%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230616T105017Z&X-Amz-Expires=3600&X-Amz-Signature=83f5da134c396bbbf0ee095262564a525d2620127961371eb72f9c9aa63f5b63&X-Amz-SignedHeaders=host&x-id=GetObject","expiry_time":"2023-06-16T11:50:17.904Z"}}
Replacing image static/notion_imgs/2091252224.png
[notion to MD conversion of ]
DN_heading_3 with plugin: standardHeadingTransformer
[headingTransformer, markdown of a heading before adding id]
### Heading 3
[markdown before link fixes]
[object Object]
[doTransformsOnMarkdown]
body after regex: [object Object]
writing ./docs/notion/Links-to-Headings-no-slug/oranges.md
Skipping page because status is not 'Publish': Introduction to docu-notion
Reading & converting page /Test (/test)
[markdown from page]
[
  {
    "object": "block",
    "id": "babec445-838b-467e-82a2-d10798e3c977",
    "parent": {
      "type": "page_id",
      "page_id": "8c7740c7-292a-44b9-9a68-acf59658ad75"
    },
    "created_time": "2023-06-13T06:02:00.000Z",
    "last_edited_time": "2023-06-13T06:02:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [
        {
          "type": "text",
          "text": {
            "content": "Hey wow!",
            "link": null
          },
          "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
          },
          "plain_text": "Hey wow!",
          "href": null
        }
      ],
      "color": "default"
    }
  },
  {
    "object": "block",
    "id": "f887fab9-aa7f-4ad6-a1a3-b4848b120667",
    "parent": {
      "type": "page_id",
      "page_id": "8c7740c7-292a-44b9-9a68-acf59658ad75"
    },
    "created_time": "2023-06-13T06:08:00.000Z",
    "last_edited_time": "2023-06-13T06:08:00.000Z",
    "created_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "last_edited_by": {
      "object": "user",
      "id": "bb7ce3af-49ee-45ca-81bd-5df42c201fd0"
    },
    "has_children": false,
    "archived": false,
    "type": "paragraph",
    "paragraph": {
      "rich_text": [],
      "color": "default"
    }
  }
]
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[transforming block with plugin]
standardEscapeHtmlBlockModifier
[transforming block with plugin]
standardHeadingTransformer
[registering custom transform]
standardHeadingTransformer for DN_heading_1
[registering custom transform]
standardHeadingTransformer for DN_heading_2
[registering custom transform]
standardHeadingTransformer for DN_heading_3
[registering custom transform]
standardColumnTransformer for column
[registering custom transform]
standardColumnListTransformer for column_list
[registering custom transform]
DownloadImagesToRepo for image
[registering custom transform]
standardCalloutTransformer for callout
[registering custom transform]
standardTableTransformer for table
[registering custom transform]
standardNumberedListTransformer for numbered_list_item
[markdown before link fixes]
[object Object]
[doTransformsOnMarkdown]
body after regex: [object Object]
writing ./docs/notion/test.md
Finished processing 4 pages
{"output_normally":3,"skipped_because_empty":0,"skipped_because_status":1,"skipped_because_level_cannot_have_content":0}

Stage 3: clean up old files & images...

docu-notion Finished.

How do I update the custom.css?

Describe the bug
After editing the custom.css directly on Github the release fails as the branch is out of date.
So how to I update the css from Notion?

Reproduction Steps

  1. Edit the custom.css on GitHub and commit.
  2. Edit the Notion file
  3. Go to GitHub and run the release workflow
  4. Release fails with the following message:
    Your branch and 'origin/main' have diverged, and have 61 and 1 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
    See release #102
    (https://github.com/sillsdev/paratext-manual/actions/runs/5724610706/job/15511446077)

Additional context
I was trying to resolve several problems. So you will also see warnings about video links. I will write another issue about that.

Title in front matter not exported - uses filename instead

Describe the bug
Docu-notion doesn't output all the front matter to MD. The top of page heading "Notion title" is used as the filename and title. The front matter has a separate title field but the export replaces whatever is in that field with the top of page heading. My goal is a short filename (for URL) with a longer title (for sidebar).

Reproduction Steps

URL of a source Notion page that, when docu-notion accesses or converts it, shows the problem:
https://jennibeadle.notion.site/0-0-3-4eed40af381f4fb8b455246b3bae0c7c

At least one of these:

  1. URL of a docusuarus site showing the resulting page
    Desired result: https://manual.paratext.org/Video-summaries/Introduction/0.2.Navigation/0.0.3
    Notion result: https://sillsdev.github.io/paratext-manual/4eed40af-381f-4fb8-b455-246b3bae0c7c/
    (note title displayed was copied to the document for later editing)

Expected behavior
The text in the title field of Notion document front matter, will replace the Notion document "title".

Screenshots
If applicable, add screenshots to help explain your problem.
Desired result
image

In Notion (showing front matter)
image

Docu-Notion website (showing short title not title from frontmatter)
(Note the ---title ... was copied to add after next process)
image

Additional context
Unfortunately, the Actions don't give me a file that I can tweak.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.