diff --git a/website/docs/usage/facts-figures.md b/website/docs/usage/facts-figures.md
index 82db59a2e..36f86dd51 100644
--- a/website/docs/usage/facts-figures.md
+++ b/website/docs/usage/facts-figures.md
@@ -12,16 +12,32 @@ menu:
### When should I use spaCy? {#comparison-usage}
-
-
-| Use Cases |
-| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| ✅ **I'm a beginner and just getting started with NLP.**
spaCy makes it easy to get started and comes with extensive documentation, including a beginner-friendly [101 guide](/usage/spacy-101) and a free interactive [online course](https://course.spacy.io). |
-| ✅ **I want to build an end-to-end production application.** |
-| ✅ **I want my application to be efficient on CPU.**
While spaCy lets you train modern NLP models that are best run on GPU, it also offers CPU-optimized pipelines, which may be less accurate but much cheaper to run. |
-| ✅ **I want to try out different neural network architectures for NLP.** |
-| ❌ **I want to build a language generation application.**
spaCy's focus is natural language _processing_ and extracting information from large volumes of text. While you can use it to help you re-write existing text, it doesn't include any specific functionality for language generation tasks. |
-| ❌ **I want to research machine learning algorithms.** |
+- ✅ **I'm a beginner and just getting started with NLP.** – spaCy makes it easy
+ to get started and comes with extensive documentation, including a
+ beginner-friendly [101 guide](/usage/spacy-101), a free interactive
+ [online course](https://course.spacy.io) and a range of
+ [video tutorials](https://www.youtube.com/c/ExplosionAI).
+- ✅ **I want to build an end-to-end production application.** – spaCy is
+ specifically designed for production use and lets you build and train powerful
+ NLP pipelines and package them for easy deployment.
+- ✅ **I want my application to be efficient on GPU _and_ CPU.** – While spaCy
+ lets you train modern NLP models that are best run on GPU, it also offers
+ CPU-optimized pipelines, which are less accurate but much cheaper to run.
+- ✅ **I want to try out different neural network architectures for NLP.** –
+ spaCy lets you customize and swap out the model architectures powering its
+ components, and implement your own using a framework like PyTorch or
+ TensorFlow. The declarative configuration system makes it easy to mix and
+ match functions and keep track of your hyperparameters to make sure your
+ experiments are reproducible.
+- ❌ **I want to build a language generation application.** – spaCy's focus is
+ natural language _processing_ and extracting information from large volumes of
+ text. While you can use it to help you re-write existing text, it doesn't
+ include any specific functionality for language generation tasks.
+- ❌ **I want to research machine learning algorithms.** spaCy is built on the
+ latest research, but it's not a research library. If your goal is to write
+ papers and run benchmarks, spaCy is probably not a good choice. However, you
+ can use it to make the results of your research easily available for others to
+ use, e.g. via a custom spaCy component.
## Benchmarks {#benchmarks}
@@ -45,7 +61,7 @@ import Benchmarks from 'usage/\_benchmarks-models.md'
-
+
+
diff --git a/website/docs/usage/spacy-101.md b/website/docs/usage/spacy-101.md
index 8a98f8a1b..cd1b2cb0c 100644
--- a/website/docs/usage/spacy-101.md
+++ b/website/docs/usage/spacy-101.md
@@ -84,15 +84,13 @@ systems, or to pre-process text for **deep learning**.
### What spaCy isn't {#what-spacy-isnt}
-- **spaCy is not a platform or "an API"**. Unlike a platform, spaCy does not
+- ❌ **spaCy is not a platform or "an API"**. Unlike a platform, spaCy does not
provide a software as a service, or a web application. It's an open-source
library designed to help you build NLP applications, not a consumable service.
-
-- **spaCy is not an out-of-the-box chat bot engine**. While spaCy can be used to
- power conversational applications, it's not designed specifically for chat
+- ❌ **spaCy is not an out-of-the-box chat bot engine**. While spaCy can be used
+ to power conversational applications, it's not designed specifically for chat
bots, and only provides the underlying text processing capabilities.
-
-- **spaCy is not research software**. It's built on the latest research, but
+- ❌**spaCy is not research software**. It's built on the latest research, but
it's designed to get things done. This leads to fairly different design
decisions than [NLTK](https://github.com/nltk/nltk) or
[CoreNLP](https://stanfordnlp.github.io/CoreNLP/), which were created as
@@ -101,8 +99,7 @@ systems, or to pre-process text for **deep learning**.
between multiple algorithms that deliver equivalent functionality. Keeping the
menu small lets spaCy deliver generally better performance and developer
experience.
-
-- **spaCy is not a company**. It's an open-source library. Our company
+- ❌ **spaCy is not a company**. It's an open-source library. Our company
publishing spaCy and other software is called
[Explosion](https://explosion.ai).
diff --git a/website/src/components/icon.js b/website/src/components/icon.js
index 8dfba7426..0bde50789 100644
--- a/website/src/components/icon.js
+++ b/website/src/components/icon.js
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
@@ -25,6 +25,7 @@ import { ReactComponent as NetworkIcon } from '../images/icons/network.svg'
import { ReactComponent as DownloadIcon } from '../images/icons/download.svg'
import { ReactComponent as PackageIcon } from '../images/icons/package.svg'
+import { isString } from './util'
import classes from '../styles/icon.module.sass'
const icons = {
@@ -88,3 +89,41 @@ Icon.propTypes = {
variant: PropTypes.oneOf(['success', 'error', 'subtle']),
className: PropTypes.string,
}
+
+export function replaceEmoji(cellChildren) {
+ const icons = {
+ '✅': { name: 'yes', variant: 'success', 'aria-label': 'positive' },
+ '❌': { name: 'no', variant: 'error', 'aria-label': 'negative' },
+ }
+ const iconRe = new RegExp(`^(${Object.keys(icons).join('|')})`, 'g')
+ let children = isString(cellChildren) ? [cellChildren] : cellChildren
+ let hasIcon = false
+ if (Array.isArray(children)) {
+ children = children.map((child, i) => {
+ if (isString(child)) {
+ const icon = icons[child.trim()]
+ const props = {
+ inline: i < children.length,
+ 'aria-hidden': undefined,
+ }
+ if (icon) {
+ hasIcon = true
+ return
+ } else if (iconRe.test(child)) {
+ hasIcon = true
+ const [, iconName, text] = child.split(iconRe)
+ return (
+
+
+ {text.trim()}
+
+ )
+ }
+ // Work around prettier auto-escape
+ if (child.startsWith('\\')) return child.slice(1)
+ }
+ return child
+ })
+ }
+ return { content: children, hasIcon }
+}
diff --git a/website/src/components/list.js b/website/src/components/list.js
index 863eaddca..e0a3d9b64 100644
--- a/website/src/components/list.js
+++ b/website/src/components/list.js
@@ -1,7 +1,17 @@
import React from 'react'
+import classNames from 'classnames'
import classes from '../styles/list.module.sass'
+import { replaceEmoji } from './icon'
export const Ol = props =>
export const Ul = props =>
-export const Li = props =>
+export const Li = ({ children, ...props }) => {
+ const { hasIcon, content } = replaceEmoji(children)
+ const liClassNames = classNames(classes.li, { [classes.liIcon]: hasIcon })
+ return (
+
+ {content}
+
+ )
+}
diff --git a/website/src/components/table.js b/website/src/components/table.js
index 3f1edbe5d..88ca86888 100644
--- a/website/src/components/table.js
+++ b/website/src/components/table.js
@@ -1,8 +1,7 @@
import React, { Fragment } from 'react'
import classNames from 'classnames'
-import Icon from './icon'
-import { Help } from './typography'
+import { replaceEmoji } from './icon'
import { isString } from './util'
import classes from '../styles/table.module.sass'
@@ -12,41 +11,6 @@ function isNum(children) {
return isString(children) && /^\d+[.,]?[\dx]+?(|x|ms|mb|gb|k|m)?$/i.test(children)
}
-function getCellContent(cellChildren) {
- const icons = {
- '✅': { name: 'yes', variant: 'success', 'aria-label': 'positive' },
- '❌': { name: 'no', variant: 'error', 'aria-label': 'negative' },
- }
- const iconRe = new RegExp(`^(${Object.keys(icons).join('|')})`, 'g')
- let children = isString(cellChildren) ? [cellChildren] : cellChildren
- if (Array.isArray(children)) {
- return children.map((child, i) => {
- if (isString(child)) {
- const icon = icons[child.trim()]
- const props = {
- inline: i < children.length,
- 'aria-hidden': undefined,
- }
- if (icon) {
- return
- } else if (iconRe.test(child)) {
- const [, iconName, text] = child.split(iconRe)
- return (
-
-
- {text.trim()}
-
- )
- }
- // Work around prettier auto-escape
- if (child.startsWith('\\')) return child.slice(1)
- }
- return child
- })
- }
- return children
-}
-
function isDividerRow(children) {
if (children.length && children[0].props && children[0].props.name == 'td') {
const tdChildren = children[0].props.children
@@ -114,7 +78,7 @@ export const Tr = ({ evenodd = true, children, ...props }) => {
}
export const Td = ({ num, nowrap, className, children, ...props }) => {
- const content = getCellContent(children)
+ const { content } = replaceEmoji(children)
const tdClassNames = classNames(classes.td, className, {
[classes.num]: num || isNum(children),
[classes.nowrap]: nowrap,
diff --git a/website/src/styles/list.module.sass b/website/src/styles/list.module.sass
index f0fb0dd5f..aec20da1c 100644
--- a/website/src/styles/list.module.sass
+++ b/website/src/styles/list.module.sass
@@ -35,3 +35,9 @@
counter-increment: li
box-sizing: content-box
vertical-align: top
+
+.li-icon
+ text-indent: calc(-20px - 0.55em)
+
+ &:before
+ content: ""