diff --git a/doc/getting-started.md b/doc/getting-started.md index 9e2b6b6aa..cb86c1e31 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -2,7 +2,7 @@ # Getting started -**remark** transforms Markdown. +**remark** transforms markdown. It’s an ecosystem of [plugins][]. If you get stuck, [issues][] and [Discussions][] are good places to get help. @@ -17,7 +17,7 @@ It’s built on [unified][], make sure to read it and its [website][] too. ## Intro -Out of the box, **remark** transforms Markdown: Markdown is given, reformatted, +Out of the box, **remark** transforms markdown: markdown is given, reformatted, and written: ```md @@ -40,7 +40,7 @@ But, much more can be done, [through plugins][plugins]. ## Command line -**remark**’s CLI is a simple way to process Markdown files from the +**remark**’s CLI is a simple way to process markdown files from the command line. Its interface is provided by [**unified-args**][unified-args]. Install [`remark-cli`][cli] and dependencies (in this case a [linting @@ -74,9 +74,9 @@ readme.md.md ## Using remark in a project -In the previous example, `remark-cli` was installed globally. That’s -generally a bad idea. Here we’re going to use the CLI to lint -an npm package. +In the previous example, `remark-cli` was installed globally. +That’s generally a bad idea. +Here we’re going to use the CLI to lint an npm package. Say we have the following `package.json`: @@ -84,6 +84,7 @@ Say we have the following `package.json`: { "name": "my-package", "version": "1.0.0", + "type": "module", "scripts": { "test": "node test.js" } @@ -103,10 +104,11 @@ The `--save-dev` option stores the dependencies in our `package.json`: { "name": "my-package", "version": "1.0.0", + "type": "module", + "devDependencies": { -+ "remark-cli": "^9.0.0", -+ "remark-html": "^13.0.0", -+ "remark-preset-lint-markdown-style-guide": "^4.0.0" ++ "remark-cli": "^10.0.0", ++ "remark-html": "^14.0.0", ++ "remark-preset-lint-markdown-style-guide": "^5.0.0" + }, "scripts": { "test": "node test.js" @@ -121,10 +123,11 @@ configuration: { "name": "my-package", "version": "1.0.0", + "type": "module", "devDependencies": { - "remark-cli": "^9.0.0", - "remark-html": "^13.0.0", - "remark-preset-lint-markdown-style-guide": "^4.0.0" + "remark-cli": "^10.0.0", + "remark-html": "^14.0.0", + "remark-preset-lint-markdown-style-guide": "^5.0.0" }, "scripts": { - "test": "node test.js" @@ -145,15 +148,16 @@ Now from the command line we can run: npm test ``` -This will lint all Markdown files when we test the project. +This will lint all markdown files when we test the project. [`--frail`][frail] ensures the command fails if a code-style violation is found, and [`--quiet`][quiet] hides successful files from the report. ## Programmatic usage The programmatic interface of **remark** is provided by -[**unified**][unified]. In fact, [`remark`][api] is two plugins: -[`remark-parse`][parse] and [`remark-stringify`][stringify]. +[**unified**][unified]. +In fact, [`remark`][api] is two plugins: [`remark-parse`][parse] and +[`remark-stringify`][stringify]. Install [`remark`][api] and dependencies with [npm][]: @@ -164,16 +168,17 @@ npm install vfile-reporter remark remark-html remark-preset-lint-markdown-style- `index.js` contains: ```js -var remark = require('remark') -var styleGuide = require('remark-preset-lint-markdown-style-guide') -var html = require('remark-html') -var report = require('vfile-reporter') +import {reporter} from 'vfile-reporter' +import {remark} from 'remark' +import remarkPresetLintMarkdownStyleGuide from 'remark-preset-lint-markdown-style-guide' +import remarkHtml from 'remark-html' remark() - .use(styleGuide) - .use(html) - .process('_Hello_.', function (err, file) { - console.error(report(err || file)) + .use(remarkPresetLintMarkdownStyleGuide) + .use(remarkHtml) + .process('_Hello_.') + .then((file) => { + console.error(reporter(file)) console.log(String(file)) }) ``` diff --git a/doc/plugins.md b/doc/plugins.md index ff953d8e6..6ebf601ad 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -2,7 +2,7 @@ # Plugins -**remark** is a Markdown processor powered by plugins part of the [unified][] +**remark** is a markdown processor powered by plugins part of the [unified][] [collective][]. ## Contents @@ -43,7 +43,7 @@ The list of plugins: — new syntax to align text or blocks (new node types, rehype compatible) * ⚠️ [`remark-attr`](https://github.com/arobase-che/remark-attr) - — new syntax to add attributes to Markdown + — new syntax to add attributes to markdown * 🟢 [`remark-autolink-headings`](https://github.com/remarkjs/remark-autolink-headings) — add GitHub-style links to headings * 🟢 [`remark-behead`](https://github.com/mrzmmr/remark-behead) @@ -130,7 +130,7 @@ The list of plugins: * 🟢 [`remark-hint`](https://github.com/sergioramos/remark-hint) — add hints/tips/warnings to markdown * 🟢 [`remark-html`](https://github.com/remarkjs/remark-html) - — serialize Markdown as HTML + — serialize markdown as HTML * 🟢 [`remark-html-katex`](https://github.com/remarkjs/remark-math/tree/HEAD/packages/remark-html-katex#readme) — change inline and block math to equations w/ [KaTeX](https://github.com/Khan/KaTeX) * ⚠️ [`remark-iframes`](https://github.com/zestedesavoir/zmarkdown/tree/HEAD/packages/remark-iframes#readme) @@ -155,11 +155,11 @@ The list of plugins: * 🟢 [`remark-linkify-regex`](https://gitlab.com/staltz/remark-linkify-regex) — change text matching a regex to links * 🟢 [`remark-lint`](https://github.com/remarkjs/remark-lint) - — check Markdown code style + — check markdown code style * 🟢 [`remark-macro`](https://github.com/dimerapp/remark-macro) — support for block macros (new node types, rehype compatible) * 🟢 [`remark-man`](https://github.com/remarkjs/remark-man) - — serialize Markdown as man pages (roff) + — serialize markdown as man pages (roff) * 🟢 [`remark-math`](https://github.com/remarkjs/remark-math) — new syntax for math (new node types, rehype compatible) * 🟢 [`remark-message-control`](https://github.com/remarkjs/remark-message-control) @@ -187,13 +187,13 @@ The list of plugins: — highlight code blocks w/ [Prism](https://prismjs.com/) (supporting most Prism plugins) * 🟢 [`remark-react`](https://github.com/remarkjs/remark-react) - — compile Markdown to [React](https://github.com/facebook/react) + — compile markdown to [React](https://github.com/facebook/react) * 🟢 [`remark-react-codemirror`](https://github.com/craftzdog/remark-react-codemirror) — highlight code blocks for `remark-react` w/ [CodeMirror](https://codemirror.net) * ⚠️ [`remark-redact`](https://github.com/seafoam6/remark-redact) — new syntax to conceal text matching a regex * 🟢 [`remark-redactable`](https://github.com/code-dot-org/remark-redactable) - — write plugins to redact content from a Markdown document, + — write plugins to redact content from a markdown document, then restore it later * 🟢 [`remark-reference-links`](https://github.com/remarkjs/remark-reference-links) — transform links and images into references and definitions @@ -216,7 +216,7 @@ The list of plugins: * 🟢 [`remark-simple-plantuml`](https://github.com/akebifiky/remark-simple-plantuml) — turn PlantUML code blocks to images * 🟢 [`remark-slate`](https://github.com/hanford/remark-slate) - — compile Markdown to [Slate nodes](https://docs.slatejs.org/concepts/02-nodes) + — compile markdown to [Slate nodes](https://docs.slatejs.org/concepts/02-nodes) * 🟢 [`remark-slate-transformer`](https://github.com/inokawa/remark-slate-transformer) — compile markdown to [Slate nodes](https://docs.slatejs.org/concepts/02-nodes) and Slate nodes to markdown @@ -246,7 +246,7 @@ The list of plugins: * 🟢 [`remark-toc`](https://github.com/remarkjs/remark-toc) — add a table of contents * 🟢 [`remark-tree-sitter`](https://github.com/samlanning/remark-tree-sitter) - — highlight code blocks in Markdown files using + — highlight code blocks in markdown files using [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) (rehype compatible) * 🟢 [`remark-truncate-links`](https://github.com/GaiAma/Coding4GaiAma/tree/HEAD/packages/remark-truncate-links) @@ -254,7 +254,7 @@ The list of plugins: * 🟢 [`remark-twemoji`](https://github.com/madiodio/remark-twemoji) — turn emoji into [Twemoji](https://github.com/twitter/twemoji) * 🟢 [`remark-typedoc-symbol-links`](https://github.com/kamranayub/remark-typedoc-symbol-links) - — turn Typedoc symbol link expressions into Markdown links + — turn Typedoc symbol link expressions into markdown links * 🟢 [`remark-typescript`](https://github.com/trevorblades/remark-typescript) — turn TypeScript code to JavaScript * 🟢 [`remark-typograf`](https://github.com/mavrin/remark-typograf) @@ -272,7 +272,7 @@ The list of plugins: * ⚠️ [`remark-variables`](https://github.com/mrzmmr/remark-variables) — new syntax for variables * 🟢 [`remark-vdom`](https://github.com/remarkjs/remark-vdom) - — compile Markdown to [VDOM](https://github.com/Matt-Esch/virtual-dom/) + — compile markdown to [VDOM](https://github.com/Matt-Esch/virtual-dom/) * 🟢 [`remark-wiki-link`](https://github.com/landakram/remark-wiki-link) — new syntax for wiki links (rehype compatible) * 🟢 [`remark-yaml-config`](https://github.com/remarkjs/remark-yaml-config) diff --git a/packages/remark-cli/package.json b/packages/remark-cli/package.json index ca5c3e72f..7558dde93 100644 --- a/packages/remark-cli/package.json +++ b/packages/remark-cli/package.json @@ -1,7 +1,7 @@ { "name": "remark-cli", "version": "9.0.0", - "description": "CLI to process Markdown with remark", + "description": "CLI to process markdown with remark", "license": "MIT", "keywords": [ "unified", diff --git a/packages/remark-cli/readme.md b/packages/remark-cli/readme.md index 6119228e3..aa0472618 100644 --- a/packages/remark-cli/readme.md +++ b/packages/remark-cli/readme.md @@ -11,7 +11,7 @@ Command line interface for [**remark**][remark]. * Interface by [`unified-args`][unified-args] * Loads [`remark-` plugins][plugins] -* Searches for [Markdown extensions][markdown-extensions] +* Searches for [markdown extensions][markdown-extensions] * Ignores paths found in [`.remarkignore` files][ignore-file] * Loads configuration from [`.remarkrc`, `.remarkrc.js` files][config-file] * Uses configuration from [`remarkConfig` fields in `package.json` @@ -31,8 +31,8 @@ npm install remark-cli # Add a table of contents to `readme.md` $ remark readme.md --use toc --output -# Lint Markdown files in the current directory -# according to the Markdown style guide. +# Lint markdown files in the current directory +# according to the markdown style guide. $ remark . --use preset-lint-markdown-style-guide ``` @@ -44,7 +44,7 @@ info on all available options. ```txt Usage: remark [options] [path | glob ...] - CLI to process Markdown with remark + CLI to process markdown with remark Options: @@ -88,7 +88,7 @@ Examples: ## Security -As Markdown is sometimes used for HTML, and improper use of HTML can open you up +As markdown is sometimes used for HTML, and improper use of HTML can open you up to a [cross-site scripting (XSS)][xss] attack, use of remark can also be unsafe. When going to HTML, use remark in combination with the [**rehype**][rehype] ecosystem, and use [`rehype-sanitize`][sanitize] to make the tree safe. diff --git a/packages/remark-cli/test.js b/packages/remark-cli/test.js index a7464346c..a11a8ac99 100644 --- a/packages/remark-cli/test.js +++ b/packages/remark-cli/test.js @@ -16,7 +16,7 @@ test('remark-cli', (t) => { [ 'Usage: remark [options] [path | glob ...]', '', - ' CLI to process Markdown with remark', + ' CLI to process markdown with remark', '', 'Options:', '', diff --git a/packages/remark-parse/package.json b/packages/remark-parse/package.json index 79fd827b2..2e33f938d 100644 --- a/packages/remark-parse/package.json +++ b/packages/remark-parse/package.json @@ -1,7 +1,7 @@ { "name": "remark-parse", "version": "9.0.0", - "description": "remark plugin to parse Markdown", + "description": "remark plugin to parse markdown", "license": "MIT", "keywords": [ "unified", diff --git a/packages/remark-parse/readme.md b/packages/remark-parse/readme.md index fd32f524d..2f17387df 100644 --- a/packages/remark-parse/readme.md +++ b/packages/remark-parse/readme.md @@ -9,14 +9,17 @@ [![Chat][chat-badge]][chat] [Parser][] for [**unified**][unified]. -Parses Markdown to [**mdast**][mdast] syntax trees. +Parses markdown to [**mdast**][mdast] syntax trees. Built on [`micromark`][micromark] and [`mdast-util-from-markdown`][from-markdown]. Used in the [**remark** processor][remark] but can be used on its own as well. -Can be [extended][extend] to change how Markdown is parsed. +Can be [extended][extend] to change how markdown is parsed. ## Install +This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): +Node 12+ is needed to use it and it must be `import`ed instead of `require`d. + [npm][]: ```sh @@ -26,15 +29,28 @@ npm install remark-parse ## Use ```js -var unified = require('unified') -var createStream = require('unified-stream') -var markdown = require('remark-parse') -var remark2rehype = require('remark-rehype') -var html = require('rehype-stringify') +import {unified} from 'unified' +import remarkParse from 'remark-parse' +import remarkGfm from 'remark-gfm' +import remarkRehype from 'remark-rehype' +import rehypeStringify from 'rehype-stringify' + +unified() + .use(remarkParse) + .use(remarkGfm) + .use(remarkRehype) + .use(rehypeStringify) + .process('# Hi\n\n*Hello*, world!') + .then((file) => { + console.log(String(file)) + }) +``` -var processor = unified().use(markdown).use(remark2rehype).use(html) +Yields: -process.stdin.pipe(createStream(processor)).pipe(process.stdout) +```html +

Hi

+

Hello, world!

``` [See **unified** for more examples »][unified] @@ -43,9 +59,12 @@ process.stdin.pipe(createStream(processor)).pipe(process.stdout) [See **unified** for API docs »][unified] -### `processor().use(parse)` +This package exports no identifiers. +The default export is `remarkParse`. + +### `unified().use(remarkParse)` -Configure the `processor` to read Markdown as input and process +Configure the `processor` to read markdown as input and process [**mdast**][mdast] syntax trees. ## Extending the parser @@ -55,7 +74,7 @@ Then create a wrapper plugin such as [`remark-gfm`][gfm]. ## Security -As Markdown is sometimes used for HTML, and improper use of HTML can open you up +As markdown is sometimes used for HTML, and improper use of HTML can open you up to a [cross-site scripting (XSS)][xss] attack, use of remark can also be unsafe. When going to HTML, use remark in combination with the [**rehype**][rehype] ecosystem, and use [`rehype-sanitize`][sanitize] to make the tree safe. diff --git a/packages/remark-stringify/package.json b/packages/remark-stringify/package.json index fcb3b18a9..c7d0a8f57 100644 --- a/packages/remark-stringify/package.json +++ b/packages/remark-stringify/package.json @@ -1,7 +1,7 @@ { "name": "remark-stringify", "version": "9.0.1", - "description": "remark plugin to compile Markdown", + "description": "remark plugin to compile markdown", "license": "MIT", "keywords": [ "unified", diff --git a/packages/remark-stringify/readme.md b/packages/remark-stringify/readme.md index b7a158187..5a31b2773 100644 --- a/packages/remark-stringify/readme.md +++ b/packages/remark-stringify/readme.md @@ -9,12 +9,15 @@ [![Backers][backers-badge]][collective] [Compiler][] for [**unified**][unified]. -Serializes [**mdast**][mdast] syntax trees to Markdown. +Serializes [**mdast**][mdast] syntax trees to markdown. Used in the [**remark** processor][remark] but can be used on its own as well. -Can be [extended][extend] to change how Markdown is serialized. +Can be [extended][extend] to change how markdown is serialized. ## Install +This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): +Node 12+ is needed to use it and it must be `import`ed instead of `require`d. + [npm][]: ```sh @@ -24,20 +27,30 @@ npm install remark-stringify ## Use ```js -var unified = require('unified') -var createStream = require('unified-stream') -var html = require('rehype-parse') -var rehype2remark = require('rehype-remark') -var stringify = require('remark-stringify') - -var processor = unified().use(html).use(rehype2remark).use(stringify, { - bullet: '*', - fence: '~', - fences: true, - incrementListMarker: false -}) - -process.stdin.pipe(createStream(processor)).pipe(process.stdout) +import {unified} from 'unified' +import rehypeParse from 'rehype-parse' +import rehypeRemark from 'rehype-remark' +import remarkStringify from 'remark-stringify' + +unified() + .use(rehypeParse) + .use(rehypeRemark) + .use(remarkStringify, { + bullet: '*', + fence: '~', + fences: true, + incrementListMarker: false + }) + .process('

Hello, world!

') + .then((file) => { + console.log(String(file)) + }) +``` + +Yields: + +```markdown +# Hello, world! ``` [See **unified** for more examples »][unified] @@ -46,14 +59,17 @@ process.stdin.pipe(createStream(processor)).pipe(process.stdout) [See **unified** for API docs »][unified] -### `processor().use(stringify[, options])` +This package exports no identifiers. +The default export is `remarkStringify`. + +### `unified().use(remarkStringify[, options])` Configure the `processor` to serialize [**mdast**][mdast] syntax trees to -Markdown. +markdown. ###### `options` -Options can be passed directly, or passed later through +Options can be passed directly or passed later through [`processor.data()`][data]. All the formatting options of [`mdast-util-to-markdown`][to-markdown-options] @@ -71,10 +87,10 @@ tree, but there are several cases where that is impossible. It’ll do its best, but complete roundtripping is impossible given that any value could be injected into the tree. -As Markdown is sometimes used for HTML, and improper use of HTML can open you up +As markdown is sometimes used for HTML, and improper use of HTML can open you up to a [cross-site scripting (XSS)][xss] attack, use of `remark-stringify` and parsing it again later can potentially be unsafe. -When parsing Markdown afterwards, use remark in combination with the +When parsing markdown afterwards, use remark in combination with the [**rehype**][rehype] ecosystem, and use [`rehype-sanitize`][sanitize] to make the tree safe. diff --git a/packages/remark/readme.md b/packages/remark/readme.md index 726fc6f07..ede5c929a 100644 --- a/packages/remark/readme.md +++ b/packages/remark/readme.md @@ -8,16 +8,16 @@ [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat] -[**unified**][unified] processor to parse and serialize Markdown. +[**unified**][unified] processor to parse and serialize markdown. Built on [micromark][]. Powered by [plugins][]. Part of the [unified][] collective. * API by [**unified**][unified] -* Parses Markdown to a syntax tree with [`remark-parse`][parse] +* Parses markdown to a syntax tree with [`remark-parse`][parse] * [**mdast**][mdast] syntax tree * [Plugins][] transform the tree -* Serializes syntax trees to Markdown with [`remark-stringify`][stringify] +* Serializes syntax trees to markdown with [`remark-stringify`][stringify] Don’t need the parser? Or compiler? @@ -25,6 +25,9 @@ Or compiler? ## Install +This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): +Node 12+ is needed to use it and it must be `import`ed instead of `require`d. + [npm][]: ```sh @@ -37,19 +40,20 @@ npm install remark ###### Common example -This example lints Markdown and turns it into HTML. +This example lints markdown and turns it into HTML. ```js -var remark = require('remark') -var recommended = require('remark-preset-lint-recommended') -var html = require('remark-html') -var report = require('vfile-reporter') +import {reporter} from 'vfile-reporter' +import {remark} from 'remark' +import remarkPresetLintRecommended from 'remark-preset-lint-recommended' +import remarkHtml from 'remark-html' remark() - .use(recommended) - .use(html) - .process('## Hello world!', function (err, file) { - console.error(report(err || file)) + .use(remarkPresetLintRecommended) + .use(remarkHtml) + .process('## Hello world!') + .then((file) => { + console.error(reporter(file)) console.log(String(file)) }) ``` @@ -57,7 +61,7 @@ remark() Yields: ```txt -1:1 warning Missing newline character at end of file final-newline remark-lint + 1:1 warning Missing newline character at end of file final-newline remark-lint ⚠ 1 warning ``` @@ -68,16 +72,16 @@ Yields: ###### Settings through data -This example prettifies Markdown and configures [`remark-stringify`][stringify] +This example prettifies markdown and configures [`remark-stringify`][stringify] through [data][]. ```js -var remark = require('remark') +import {remark} from 'remark' remark() .data('settings', {emphasis: '*', strong: '*'}) - .process('_Emphasis_ and __importance__', function (err, file) { - if (err) throw err + .process('_Emphasis_ and __importance__') + .then((file) => { console.log(String(file)) }) ``` @@ -90,16 +94,16 @@ Yields: ###### Settings through a preset -This example prettifies Markdown and configures [`remark-parse`][parse] and +This example prettifies markdown and configures [`remark-parse`][parse] and [`remark-stringify`][stringify] through a [preset][]. ```js -var remark = require('remark') +import {remark} from 'remark' remark() .use({settings: {emphasis: '*', strong: '*'}}) - .process('_Emphasis_ and __importance__', function (err, file) { - if (err) throw err + .process('_Emphasis_ and __importance__') + .then((file) => { console.log(String(file)) }) ``` @@ -114,9 +118,12 @@ Yields: [See **unified** for API docs »][unified] +This package exports the following identifier: `remark`. +There is no default export. + ## Security -As Markdown is sometimes used for HTML, and improper use of HTML can open you up +As markdown is sometimes used for HTML, and improper use of HTML can open you up to a [cross-site scripting (XSS)][xss] attack, use of remark can also be unsafe. When going to HTML, use remark in combination with the [**rehype**][rehype] ecosystem, and use [`rehype-sanitize`][sanitize] to make the tree safe. diff --git a/readme.md b/readme.md index 0a66ea516..8b0457906 100644 --- a/readme.md +++ b/readme.md @@ -8,23 +8,23 @@ [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat] -**remark** is a Markdown processor built on [micromark][] powered by +**remark** is a markdown processor built on [micromark][] powered by [plugins][] part of the [unified][] collective. ## Intro -**remark** is [the world’s most popular Markdown parser][popular]! +**remark** is [the world’s most popular markdown parser][popular]! And it does so much more than parse: it inspects (check, lint) and transforms -(generate, compile) Markdown too! +(generate, compile) markdown too! -Everything is possible with plugins, such as [checking Markdown code +Everything is possible with plugins, such as [checking markdown code style (`remark-lint`)][remark-lint], [transforming safely to React (`remark-react`)][remark-react], [adding a table of contents (`remark-toc`)][remark-toc], or [compiling to man pages (`remark-man`)][remark-man]. Internally, remark now uses [micromark][], a new, fast, and tiny CommonMark -compliant Markdown tokenizer. +compliant markdown tokenizer. It can be GFM compliant with [`remark-gfm`][remark-gfm]. Finally, remark is part of the [unified][website] [collective][governance]. @@ -41,14 +41,14 @@ Learn more about us: This repository contains the following packages: -* [`remark-parse`][parse] — Parse Markdown to syntax trees -* [`remark-stringify`][stringify] — Serialize syntax trees to Markdown +* [`remark-parse`][parse] — Parse markdown to syntax trees +* [`remark-stringify`][stringify] — Serialize syntax trees to markdown * [`remark`][api] — Programmatic interface with both `remark-parse` and `remark-stringify` * [`remark-cli`][cli] — Command line interface wrapping `remark` ## Security -As Markdown is sometimes used for HTML, and improper use of HTML can open you up +As markdown is sometimes used for HTML, and improper use of HTML can open you up to a [cross-site scripting (XSS)][xss] attack, use of remark can also be unsafe. When going to HTML, use remark in combination with the [**rehype**][rehype] ecosystem, and use [`rehype-sanitize`][sanitize] to make the tree safe.