diff --git a/README.md b/README.md index 756c437018a401deac2ced661cd6e4066a5b0ecb..a982f19f8b0758edd911aa1c09f4b3a865628019 100644 --- a/README.md +++ b/README.md @@ -6,18 +6,67 @@ When evaluating it, please keep in mind that it is a prototype and that almost a The prototype can handle two types of content: articles and videos. All content should be stored as markdown files in the `docs/article` or `docs/video` folder. # How to integrate images into content -Save image files to the `images` folder and then link to them in the markdown file, starting the path from the root of the project. +Save image files to the `images` folder and then add links to them in the body of markdown files, starting the path from the root of the project. Example: `` (I believe the alt text block can be empty: ``). _(See `docs/article/select-a-species.md` for the reference)_. # How to integrate videos into content + +## Option 1: Add a related video file - Add a markdown file in the `docs/video` folder. - Format it similarly to other files in this folder. +- add `related-video` metadata field in the frontmatter yaml of appropriate markdown files (see `docs/article/select-a-species.md` for the reference). **Important** Please note that the video appearing on Ensembl website will be embedded in an iframe. Youtube is very particular about its links — urls for videos embedded in iframes should end in `/embed/:id` rather than in `/watch?v=:id`. To get the correct url from youtube, click on `Share`, then `Embed`. What you want, is just the content of the `src` attribute of the code for the iframe. +**Note:** We are currently supporting only one video per article using this approach. This is a limitation that we probably should address. + +## Option 2: Simply add iframe html code in the markdown file +This is an example of using an escape hatch when authoring markdown files. If you do not need to associate any metadata with a video, but simply want to add it inside your article, you can do so by adding raw `iframe` html element inside the body of your article. For example: + +``` +Here is my first paragraph, right before the video. + +<iframe width="560" height="315" src="https://www.youtube.com/embed/C2g37X_uMok" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> + +Here is my second paragraph, right after the video. +``` + +For more details about this approach, see the **Escape hatch** section below. + +# Escape hatch: writing HTML inside markdown +Markdown is a great writing tool, but it may be somewhat missing in the formatting department. If you really need to add some extra html markup or CSS styling to specific parts of your articles, you can do so by switching to raw html. Here is an example: + +``` +<style> +.scary > blockquote { + background-color: rgba(237, 51, 21, 0.2); + border-left-color: #ed3315; +} +</style> + +<div class="scary"> + +>Caution: +> +>This page describes **experimental features that are [not yet available](/docs/concurrent-mode-adoption.html) in a stable release**. Don't rely on experimental builds of React in production apps. These features may change significantly and without a warning before they become a part of React. +> +>This documentation is aimed at early adopters and people who are curious. **If you're new to React, don't worry about these features** -- you don't need to learn them right now. + +</div> + +<iframe width="560" height="315" src="https://www.youtube.com/embed/C2g37X_uMok" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> + +This page provides a theoretical overview of Concurrent Mode. +``` + +Notice how: +- the Caution block is written in Markdown (and formatted as a blockquote) and is placed inside a `div` that has a specific CSS class +- there is an empty line between the `div` and the Caution block (this is required if you want to continue writing Markdown inside html) +- there is an iframe code linking to a youtube video + # How to publish content Push committed changes to this repository. A build script will run automatically, and a bot will post a comment to your commit, notifying you whether your changes have been deployed successfully. In case of a successful deployment, it will also provide links to where the code has been deployed. @@ -42,7 +91,7 @@ At the moment, you can only see changes in the popup on the species selector pag - visit the page built according to the following pattern: `https://zeit-serverless-exercise.now.sh/api/article?file=<name_of_your_file>` (example: https://zeit-serverless-exercise.now.sh/api/article?file=ensembl-select) - verify that you see the changes -## How to add new articles +# How to add new articles Ah, here’s the rub: in order for the new help content to appear on the new Ensembl web site, you'll have to ask the web team to add an identifier, which would be the name of your new documentation file, to the specific element on the specific page that you are documenting. But that's unavoidable in the case of contextual help. It will be different for full documentation pages, which will be generated automatically without any involvement of the web team. diff --git a/docs/article/ensembl-select.md b/docs/article/ensembl-select.md index 30a80db1c346bde29b77e2304b5cadcf0635a2ee..ab52bcc722ca619ace807b19aeb02bca0c2286de 100644 --- a/docs/article/ensembl-select.md +++ b/docs/article/ensembl-select.md @@ -25,6 +25,8 @@ status: published </div> +<iframe width="560" height="315" src="https://www.youtube.com/embed/C2g37X_uMok" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> + This page provides a theoretical overview of Concurrent Mode. **For a more practical introduction, you might want to check out the next sections:** * [Suspense for Data Fetching](/docs/concurrent-mode-suspense.html) describes a new mechanism for fetching data in React components. diff --git a/package-lock.json b/package-lock.json index 7483a239800b2d7c937cf1a665cfdaaa30630993..00fc612a1e719dca9559ebf9caf5ec84b3b66c10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -506,11 +506,63 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "hast-to-hyperscript": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-7.0.4.tgz", + "integrity": "sha512-vmwriQ2H0RPS9ho4Kkbf3n3lY436QKLq6VaGA1pzBh36hBi3tm1DO9bR+kaJIbpT10UqaANDkMjxvjVfr+cnOA==", + "requires": { + "comma-separated-tokens": "^1.0.0", + "property-information": "^5.3.0", + "space-separated-tokens": "^1.0.0", + "style-to-object": "^0.2.1", + "unist-util-is": "^3.0.0", + "web-namespaces": "^1.1.2" + }, + "dependencies": { + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" + } + } + }, + "hast-util-from-parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz", + "integrity": "sha512-gOc8UB99F6eWVWFtM9jUikjN7QkWxB3nY0df5Z0Zq1/Nkwl5V4hAAsl0tmwlgWl/1shlTF8DnNYLO8X6wRV9pA==", + "requires": { + "ccount": "^1.0.3", + "hastscript": "^5.0.0", + "property-information": "^5.0.0", + "web-namespaces": "^1.1.2", + "xtend": "^4.0.1" + } + }, "hast-util-is-element": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.4.tgz", "integrity": "sha512-NFR6ljJRvDcyPP5SbV7MyPBgF47X3BsskLnmw1U34yL+X6YC0MoBx9EyMg8Jtx4FzGH95jw8+c1VPLHaRA0wDQ==" }, + "hast-util-parse-selector": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz", + "integrity": "sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA==" + }, + "hast-util-raw": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-5.0.2.tgz", + "integrity": "sha512-3ReYQcIHmzSgMq8UrDZHFL0oGlbuVGdLKs8s/Fe8BfHFAyZDrdv1fy/AGn+Fim8ZuvAHcJ61NQhVMtyfHviT/g==", + "requires": { + "hast-util-from-parse5": "^5.0.0", + "hast-util-to-parse5": "^5.0.0", + "html-void-elements": "^1.0.0", + "parse5": "^5.0.0", + "unist-util-position": "^3.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.0", + "zwitch": "^1.0.0" + } + }, "hast-util-to-html": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-7.1.0.tgz", @@ -528,11 +580,34 @@ "xtend": "^4.0.0" } }, + "hast-util-to-parse5": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-5.1.2.tgz", + "integrity": "sha512-ZgYLJu9lYknMfsBY0rBV4TJn2xiwF1fXFFjbP6EE7S0s5mS8LIKBVWzhA1MeIs1SWW6GnnE4In6c3kPb+CWhog==", + "requires": { + "hast-to-hyperscript": "^7.0.0", + "property-information": "^5.0.0", + "web-namespaces": "^1.0.0", + "xtend": "^4.0.0", + "zwitch": "^1.0.0" + } + }, "hast-util-whitespace": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz", "integrity": "sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A==" }, + "hastscript": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-5.1.2.tgz", + "integrity": "sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ==", + "requires": { + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + } + }, "html-void-elements": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", @@ -602,6 +677,11 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -1006,6 +1086,11 @@ "is-hexadecimal": "^1.0.0" } }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1109,6 +1194,14 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", "integrity": "sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==" }, + "rehype-raw": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-4.0.2.tgz", + "integrity": "sha512-xQt94oXfDaO7sK9mJBtsZXkjW/jm6kArCoYN+HqKZ51O19AFHlp3Xa5UfZZ2tJkbpAZzKtgVUYvnconk9IsFuA==", + "requires": { + "hast-util-raw": "^5.0.0" + } + }, "rehype-stringify": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-7.0.0.tgz", @@ -1405,6 +1498,14 @@ "resolved": "https://registry.npmjs.org/strip-markdown/-/strip-markdown-3.1.2.tgz", "integrity": "sha512-NjwW6CEefesmHQPs7lof/lgnSriqUnRNOWpnrNPq9A7/yOCdnhaB7DcxlhYuN7WiiRUe349aitAsTQ/ajM9Dmw==" }, + "style-to-object": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.2.3.tgz", + "integrity": "sha512-1d/k4EY2N7jVLOqf2j04dTc37TPOv/hHxZmvpg8Pdh8UYydxeu/C1W1U4vD8alzf5V2Gt7rLsmkr4dxAlDm9ng==", + "requires": { + "inline-style-parser": "0.1.1" + } + }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", @@ -1640,6 +1741,11 @@ "unist-util-stringify-position": "^2.0.0" } }, + "web-namespaces": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", + "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==" + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -1670,6 +1776,11 @@ "requires": { "@babel/runtime": "^7.8.7" } + }, + "zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" } } } diff --git a/package.json b/package.json index 1a6b0e52f7fa5dc4d4f07ccf8e252257a5ae2c61..764eb54ddbaf16f9ddfec7337a0f5ce206be51e3 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "express": "4.17.1", "lunr": "2.3.8", "mkdirp": "1.0.4", + "rehype-raw": "4.0.2", "rehype-stringify": "7.0.0", "remark-extract-frontmatter": "2.0.2", "remark-frontmatter": "2.0.0", diff --git a/scripts/build-database/parseMarkdown.js b/scripts/build-database/parseMarkdown.js index 548e7d52a143d9c9edef711f9a1f56b088e2bb9a..738db864c44e914016bfc7f5ffb18e7e10845c93 100644 --- a/scripts/build-database/parseMarkdown.js +++ b/scripts/build-database/parseMarkdown.js @@ -3,6 +3,7 @@ const vfile = require('to-vfile'); const unified = require('unified'); const parse = require('remark-parse'); const remark2rehype = require('remark-rehype'); +const raw = require('rehype-raw'); const extract = require('remark-extract-frontmatter'); const html = require('rehype-stringify'); const frontmatter = require('remark-frontmatter'); @@ -17,7 +18,8 @@ const parseMarkdown = async (pathToFile) => { .use(frontmatter, ['yaml', 'toml']) .use(extract, { yaml: yaml }) .use(imagePlugin) - .use(remark2rehype) + .use(remark2rehype, {allowDangerousHTML: true}) + .use(raw) .use(html) .process(vfile.readSync(pathToFile), function(err, file) { if (err) {