diff --git a/src/EditorApp/DispatchContext.js b/src/EditorApp/ContextDispatch.js
similarity index 100%
rename from src/EditorApp/DispatchContext.js
rename to src/EditorApp/ContextDispatch.js
diff --git a/src/EditorApp/PrefsDispatchContext.js b/src/EditorApp/ContextPrefsDispatch.js
similarity index 100%
rename from src/EditorApp/PrefsDispatchContext.js
rename to src/EditorApp/ContextPrefsDispatch.js
diff --git a/src/EditorApp/EditorApp.js b/src/EditorApp/EditorApp.js
index ad0991e..f879e30 100644
--- a/src/EditorApp/EditorApp.js
+++ b/src/EditorApp/EditorApp.js
@@ -1,9 +1,9 @@
+import ContextDispatch from "./ContextDispatch"
+import ContextPrefsDispatch from "./ContextPrefsDispatch"
import ctrlOrCmd from "lib/Client/ctrlOrCmd"
-import DispatchContext from "./DispatchContext"
import keyCodeFor from "lib/Client/keyCodeFor"
import MemoFixedBottomWYSIWYGMenu from "./MemoFixedBottomWYSIWYGMenu"
import MemoFixedTopPreferences from "./MemoFixedTopPreferences"
-import PrefsDispatchContext from "./PrefsDispatchContext"
import React from "react"
import useKeydown from "lib/x/handlers/useKeydown"
import usePreferences from "./usePreferences"
@@ -83,8 +83,8 @@ const App = () => {
})
return (
-
-
+
+
@@ -134,8 +134,8 @@ const App = () => {
-
-
+
+
)
}
diff --git a/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js b/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js
index 6714aba..933223d 100644
--- a/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js
+++ b/src/EditorApp/MemoFixedBottomWYSIWYGMenu/WYSIWYGMenu.js
@@ -1,10 +1,10 @@
-import DispatchContext from "../DispatchContext"
+import ContextDispatch from "../ContextDispatch"
import React from "react"
import userAgent from "lib/Client/userAgent"
import { TopTooltip as Tooltip } from "../Tooltips"
const WYSIWYGMenu = ({ rangeTypes }) => {
- const dispatch = React.useContext(DispatchContext)
+ const dispatch = React.useContext(ContextDispatch)
const [tooltip, setTooltip] = React.useState("")
diff --git a/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js b/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js
index 346b26d..0028264 100644
--- a/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js
+++ b/src/EditorApp/MemoFixedTopPreferences/MemoFixedTopPreferences.js
@@ -1,5 +1,5 @@
+import ContextPrefsDispatch from "../ContextPrefsDispatch"
import MemoHighlight from "lib/PrismJS/MemoHighlight"
-import PrefsDispatchContext from "../PrefsDispatchContext"
import React from "react"
import Releases from "./Releases"
import tabSize from "lib/x/tabSize"
@@ -11,7 +11,7 @@ import {
} from "../Tooltips"
const MemoFixedTopPreferences = React.memo(({ prefs }) => {
- const dispatch = React.useContext(PrefsDispatchContext)
+ const dispatch = React.useContext(ContextPrefsDispatch)
const [tooltip, setTooltip] = React.useState("")
diff --git a/src/EditorApp/resolvers.js b/src/EditorApp/resolvers.js
deleted file mode 100644
index e4dd745..0000000
--- a/src/EditorApp/resolvers.js
+++ /dev/null
@@ -1,105 +0,0 @@
-import escape from "lodash/escape"
-import toArray from "lib/x/toArray"
-import toTree from "Editor/components/toReactTree/toTree"
-
-// Mocks the browser API; reads text content from tree-
-// shaped children.
-function treeTextContent(children) {
- let str = ""
- for (const each of toArray(children)) {
- if (typeof each === "string") {
- str += each
- continue
- }
- str += treeTextContent(each.props.children)
- }
- return str
-}
-
-// TODO: Add support for alternate syntax?
-const gfm = {
- em: el => `_${resolveTreeChildren(el.props.children, gfm)}_`,
- strong: el => `**${resolveTreeChildren(el.props.children, gfm)}**`,
- code: el => `\`${treeTextContent(el.props.children)}\``,
- strike: el => `~~${resolveTreeChildren(el.props.children, gfm)}~~`,
-
- // !el.props.href ? `[${resolveTreeChildren(el.props.children, gfm)}](${el.props.href})` : el.props.children,
- a: el => `[${resolveTreeChildren(el.props.children, gfm)}](${el.props.href || "TODO"})`,
-
- "h1": el => `# ${resolveChildren(el.props.children, gfm)}`,
- "h2": el => `## ${resolveChildren(el.props.children, gfm)}`,
- "h3": el => `### ${resolveChildren(el.props.children, gfm)}`,
- "h4": el => `#### ${resolveChildren(el.props.children, gfm)}`,
- "h5": el => `##### ${resolveChildren(el.props.children, gfm)}`,
- "h6": el => `###### ${resolveChildren(el.props.children, gfm)}`,
- "p": el => resolveChildren(el.props.children, gfm),
-}
-
-// TODO: Add support for options; show ID, show wrapped URL,
-// etc.
-const html = {
- em: el => `${resolveTreeChildren(el.props.children, html)}`,
- strong: el => `${resolveTreeChildren(el.props.children, html)}`,
- code: el => `${resolveTreeChildren(el.props.children, html)}
`,
- strike: el => `${resolveTreeChildren(el.props.children, html)}`,
-
- // target="_blank" rel="noopener noreferrer"
- a: el => `${resolveTreeChildren(el.props.children, html)}`,
-
- "h1": el => `
\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
- "h2": el => `\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
- "h3": el => `\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
- "h4": el => `\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
- "h5": el => `\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
- "h6": el => `\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
- "p": el => `\n\t${resolveChildren(el.props.children, html) || "
"}\n
`,
-}
-
-// if (children === null || typeof children === "string") {
-// if (resolver === cmapText) {
-// return children || ""
-// }
-// // Return an escaped string or a break:
-// return (resolver !== cmapReact_js ? escape(children) : reactEscape(children)) ||
-// (resolver !== cmapReact_js ? "
" : "
")
-// }
-
-// Resolves tree-shaped children to a resolver-type.
-function resolveTreeChildren(children, resolver) {
- let str = ""
- for (const each of toArray(children)) {
- if (typeof each === "string") {
- str += resolver !== html ? each : escape(each)
- continue
- }
- str += resolver[each.type](each)
- }
- return str
-}
-
-// Resolves children to a resolver-type.
-function resolveChildren(children, resolver) {
- return resolveTreeChildren(toTree(children), resolver)
-}
-
-// Resolves elements to a resolver-type.
-function resolveElements(elements, resolver) {
- let str = ""
- for (const each of elements) {
- str += resolver[each.type](each)
- if (each !== elements[elements.length - 1]) {
- str += "\n"
- }
- }
- return str
-}
-
-// Converts an array of elements to GFM.
-export function toGFM(elements) {
- return resolveElements(elements, gfm)
-}
-
-// Converts an array of elements to HTML.
-export function toHTML(elements) {
- return resolveElements(elements, html)
-}
diff --git a/src/EditorApp/usePreferences/index.js b/src/EditorApp/usePreferences/index.js
new file mode 100644
index 0000000..7f888e3
--- /dev/null
+++ b/src/EditorApp/usePreferences/index.js
@@ -0,0 +1 @@
+export { default } from "./usePreferences"
diff --git a/src/EditorApp/usePreferences/resolvers.js b/src/EditorApp/usePreferences/resolvers.js
new file mode 100644
index 0000000..b2548f9
--- /dev/null
+++ b/src/EditorApp/usePreferences/resolvers.js
@@ -0,0 +1,86 @@
+import escape from "lodash/escape"
+import toArray from "lib/x/toArray"
+import toTree from "Editor/components/toReactTree/toTree"
+
+const markdown = {
+ em: element => `_${toText(element.props.children, markdown)}_`,
+ strong: element => `**${toText(element.props.children, markdown)}**`,
+ code: element => `\`${text(element.props.children)}\``,
+ strike: element => `~~${toText(element.props.children, markdown)}~~`,
+ a: element => `[${toText(element.props.children, markdown)}](${element.props.href || "TODO"})`,
+ "h1": element => `# ${toText(toTree(element.props.children, markdown))}`,
+ "h2": element => `## ${toText(toTree(element.props.children, markdown))}`,
+ "h3": element => `### ${toText(toTree(element.props.children, markdown))}`,
+ "h4": element => `#### ${toText(toTree(element.props.children, markdown))}`,
+ "h5": element => `##### ${toText(toTree(element.props.children, markdown))}`,
+ "h6": element => `###### ${toText(toTree(element.props.children, markdown))}`,
+ "p": element => toText(toTree(element.props.children), markdown),
+}
+
+const markup = {
+ em: element => `${toText(element.props.children, markup)}`,
+ strong: element => `${toText(element.props.children, markup)}`,
+ code: element => `${toText(element.props.children, markup)}
`,
+ strike: element => `${toText(element.props.children, markup)}`,
+ a: element => `${toText(element.props.children, markup)}`,
+ "h1": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+ "h2": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+ "h3": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+ "h4": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+ "h5": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+ "h6": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+ "p": element => `\n\t${toText(toTree(element.props.children), markup) || "
"}\n
`,
+}
+
+// Reads text from tree-shaped text nodes. Does not use a
+// resolver-type.
+function text(treeTextNodes) {
+ let str = ""
+ for (const each of toArray(treeTextNodes)) {
+ if (typeof each === "string") {
+ str += each
+ continue
+ }
+ str += each.props.children &&
+ text(each.props.children)
+ }
+ return str
+}
+
+// Reads text from non-tree-shaped text nodes and a
+// resolver-type.
+function toText(children, resolver) {
+ let str = ""
+ for (const each of toArray(children)) {
+ if (typeof each === "string") {
+ str += resolver !== markup ? each : escape(each)
+ continue
+ }
+ str += resolver[each.type](each)
+ }
+ return str
+}
+
+// Converts to GFM.
+export function toMarkdown(elements) {
+ let str = ""
+ for (const each of elements) {
+ str += markdown[each.type](each)
+ if (each !== elements[elements.length - 1]) {
+ str += "\n"
+ }
+ }
+ return str
+}
+
+// Converts to HTML.
+export function toMarkup(elements) {
+ let str = ""
+ for (const each of elements) {
+ str += markup[each.type](each)
+ if (each !== elements[elements.length - 1]) {
+ str += "\n"
+ }
+ }
+ return str
+}
diff --git a/src/EditorApp/usePreferences/resolvers.test.js b/src/EditorApp/usePreferences/resolvers.test.js
new file mode 100644
index 0000000..70b786d
--- /dev/null
+++ b/src/EditorApp/usePreferences/resolvers.test.js
@@ -0,0 +1 @@
+// TODO
diff --git a/src/EditorApp/usePreferences.js b/src/EditorApp/usePreferences/usePreferences.js
similarity index 95%
rename from src/EditorApp/usePreferences.js
rename to src/EditorApp/usePreferences/usePreferences.js
index 2b537a8..24ff44b 100644
--- a/src/EditorApp/usePreferences.js
+++ b/src/EditorApp/usePreferences/usePreferences.js
@@ -1,8 +1,8 @@
import { useImmerReducer } from "use-immer"
-import { // Unsorted
- toGFM as toMarkdown, // TODO
- toHTML as toMarkup, // TODO
+import {
+ toMarkdown,
+ toMarkup,
} from "./resolvers"
const init = elements => ({