From a974aa4e6573c8becf93f78610406747fec14c1c Mon Sep 17 00:00:00 2001
From: bobzel
Date: Tue, 19 Mar 2024 17:08:46 -0400
Subject: cleaned up user templates to not get changed on reload. made setting
a template add it to the template tools list and as a tools button. fixed
linking to parts of a template. fixed disappearing templates caused by
stacking view set a field with an empty key. updated field assignment
syntax in trees, dash field views, and key value box to all use :,:=,=,=:=
syntax. added text elide button. added @(title) syntax for hyperlinking.
made using a template both inherit from the template to get default values
and use the template to render. fixed submenu placement of context menu.
updated RTF markdown doc.
---
src/client/util/RTFMarkup.tsx | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)
(limited to 'src/client/util/RTFMarkup.tsx')
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index f96d8a5df..315daad42 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -3,18 +3,12 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { MainViewModal } from '../views/MainViewModal';
import { SettingsManager } from './SettingsManager';
-import { Doc } from '../../fields/Doc';
-import { StrCast } from '../../fields/Types';
@observer
export class RTFMarkup extends React.Component<{}> {
static Instance: RTFMarkup;
@observable private isOpen = false; // whether the SharingManager modal is open or not
- // private get linkVisible() {
- // return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
- // }
-
@action
public open = () => (this.isOpen = true);
@@ -39,6 +33,10 @@ export class RTFMarkup extends React.Component<{}> {
{`wiki:phrase`}
{` display wikipedia page for entered text (terminate with carriage return)`}
+
+ {`(( any text ))`}
+ {` submit text to Chat GPT to have results appended afterward`}
+
{`#tag `}
{` add hashtag metadata to document. e.g, #idea`}
@@ -47,10 +45,6 @@ export class RTFMarkup extends React.Component<{}> {
{`#, ## ... ###### `}
{` set heading style based on number of '#'s between 1 and 6`}
-
- {`#tag `}
- {` add hashtag metadata to document. e.g, #idea`}
-
{`>> `}
{` add a sidebar text document inline`}
@@ -61,7 +55,7 @@ export class RTFMarkup extends React.Component<{}> {
{`cmd-f `}
- {` collapse to an inline footnote)`}
+ {` collapse to an inline footnote`}
{`cmd-e `}
@@ -116,20 +110,20 @@ export class RTFMarkup extends React.Component<{}> {
{` start a block of text that begins with a hanging indent`}
- {`[:doctitle]] `}
+ {`@(doctitle) `}
{` hyperlink to document specified by it’s title`}
- {`[[fieldname]] `}
- {` display value of fieldname`}
+ {`[@(doctitle.)fieldname] `}
+ {` display value of fieldname of text document (unless (doctitle.) is used to indicate another document by it's title)`}
- {`[[fieldname=value]] `}
- {` assign value to fieldname of document and display it`}
+ {`[@fieldname:value] `}
+ {` assign value to fieldname to data document and display it (if '=' is used instead of ':' the value is set on the layout Doc. if value is wrapped in (()) then it will be sent to ChatGPT and the response will replace the value)`}
- {`[[fieldname:doctitle]] `}
- {` show value of fieldname from doc specified by it’s title`}
+ {`[@fieldname:=expression] `}
+ {` assign a computed expression to fieldname to data document and display it (if '=:=' is used instead of ':=' the expression is set on the layout Doc. if value is wrapped in (()) then it will be sent to ChatGPT and the prompt/response will replace the value)`}
);
--
cgit v1.2.3-70-g09d2
From 1d47f6cc8be84ab368ad91f287909ee162d1f2e2 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Wed, 27 Mar 2024 15:42:12 -0400
Subject: fixed toggling footnotes. fixed error in bullet hit test. fixed
problems with backspace and enter in prosemirror transfer. fixed display of
markdown options to start at top.
---
src/client/util/RTFMarkup.tsx | 2 +-
.../views/nodes/formattedText/FootnoteView.tsx | 4 ++-
.../views/nodes/formattedText/FormattedTextBox.tsx | 3 +-
.../formattedText/ProsemirrorExampleTransfer.ts | 41 ++++++++++++++--------
4 files changed, 32 insertions(+), 18 deletions(-)
(limited to 'src/client/util/RTFMarkup.tsx')
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index 315daad42..57485d893 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -132,7 +132,7 @@ export class RTFMarkup extends React.Component<{}> {
render() {
return (
e.stopPropagation(), true);
// These are used when the footnote is selected
this.innerView = null;
}
@@ -82,9 +83,10 @@ export class FootnoteView {
document.removeEventListener('pointerup', this.ignore, true);
};
- toggle = () => {
+ toggle = (e: PointerEvent) => {
if (this.innerView) this.close();
else this.open();
+ e.stopPropagation();
};
close() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 729c4d534..9882a9be9 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1685,7 +1685,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent>(schema: S, props: any, mapKey
});
// backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
- const backspace = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView) => {
+ const backspace = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView, once = true) => {
if (props.onKey?.(event, props)) return true;
if (!canEdit(state)) return true;
@@ -267,7 +267,7 @@ export function buildKeymap>(schema: S, props: any, mapKey
if (
!joinBackward(state, (tx: Transaction) => {
dispatch(updateBullets(tx, schema));
- if (!view.state.selection.$from.node().content.size) backspace(view.state, view.dispatch, view);
+ if (once && view.state.selection.$from.depth > 1 && view.state.selection.$from.node(view.state.selection.$from.depth - 1).type === view.state.schema.nodes.list_item) backspace(view.state, view.dispatch, view, false);
})
) {
if (
@@ -286,26 +286,26 @@ export function buildKeymap>(schema: S, props: any, mapKey
//newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock
//command to break line
- const enter = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView) => {
+ const enter = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView, once = true) => {
if (props.onKey?.(event, props)) return true;
if (!canEdit(state)) return true;
const trange = state.selection.$from.blockRange(state.selection.$to);
- const path = (state.selection.$from as any).path;
- const depth = trange ? liftTarget(trange) : undefined;
- const split = path.length > 5 && !path[path.length - 3].textContent && path[path.length - 6].type !== schema.nodes.list_item;
- if (split && trange && depth !== undefined && depth !== null) {
+ const depth = trange ? liftTarget(trange) : null;
+ if (
+ depth !== null &&
+ state.selection.$from.node(state.selection.$from.depth - 1)?.type === state.schema.nodes.blockquote && //
+ !state.selection.$from.node().content.size &&
+ trange
+ ) {
dispatch(state.tr.lift(trange, depth) as any);
return true;
}
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- const cr = state.selection.$from.node().textContent.endsWith('\n');
- if (/*cr ||*/ !newlineInCode(state, dispatch as any)) {
- if (!view.state.selection.$from.nodeBefore && !view.state.selection.$from.nodeBefore) {
- do {
- liftListItem(schema.nodes.list_item)(view.state, view.dispatch);
- } while (view.state.selection.$from.depth > 1);
+ if (!newlineInCode(state, dispatch as any)) {
+ if (once && view.state.selection.$from.depth > 1 && !view.state.selection.$from.nodeBefore && !view.state.selection.$from.nodeBefore) {
+ for (let i = 0; i < 10 && view.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++);
} else if (
!splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => {
const tx3 = updateBullets(tx2, schema);
@@ -321,8 +321,19 @@ export function buildKeymap>(schema: S, props: any, mapKey
if (tx3.selection.to && tx3.doc.nodeAt(tx3.selection.to - 1)) {
const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks);
dispatch(tx4);
- if (!view.state.selection.$from.node().content.size) liftListItem(schema.nodes.list_item)(view.state, view.dispatch);
- else enter(view.state, view.dispatch, view); // view.dispatch(view.state.tr.insertText('\r\n'));
+ if (
+ view.state.selection.$from.parentOffset && //
+ !view.state.selection.$from.node().content.size
+ )
+ liftListItem(schema.nodes.list_item)(view.state, view.dispatch);
+ else if (
+ once &&
+ view.state.selection.$from.parentOffset &&
+ view.state.selection.$from.depth > 1 && //
+ view.state.selection.$from.node(view.state.selection.$from.depth - 1).type === schema.nodes.list_item
+ )
+ enter(view.state, view.dispatch, view, false);
+ else if (once && depth && !view.state.selection.$from.parentOffset) backspace(view.state, view.dispatch, view, false);
} else dispatch(tx3.insertText('\r\n'));
})
) {
--
cgit v1.2.3-70-g09d2
From aeeebf6d83868d4a5040e9632503511617242c55 Mon Sep 17 00:00:00 2001
From: bobzel
Date: Sat, 30 Mar 2024 16:13:31 -0400
Subject: updated and fixed wiki link to use @(wiki:...) and fixed linkManager
from infinite looping on relatedlinker(). fixed clicking in text exxeptions.
---
src/client/util/RTFMarkup.tsx | 2 +-
src/client/views/nodes/LinkBox.tsx | 4 ++--
src/client/views/nodes/LinkDocPreview.tsx | 5 +++--
src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 +-
src/client/views/nodes/formattedText/RichTextRules.ts | 12 ++++++------
5 files changed, 13 insertions(+), 12 deletions(-)
(limited to 'src/client/util/RTFMarkup.tsx')
diff --git a/src/client/util/RTFMarkup.tsx b/src/client/util/RTFMarkup.tsx
index 57485d893..35b1579df 100644
--- a/src/client/util/RTFMarkup.tsx
+++ b/src/client/util/RTFMarkup.tsx
@@ -30,7 +30,7 @@ export class RTFMarkup extends React.Component<{}> {
return (
- {`wiki:phrase`}
+ {`(@wiki:phrase)`}
{` display wikipedia page for entered text (terminate with carriage return)`}
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 36bd037ca..3a2509c3d 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -48,9 +48,9 @@ export class LinkBox extends ViewBoxBaseComponent() {
componentDidMount() {
this._props.setContentViewBox?.(this);
this._disposers.deleting = reaction(
- () => (!this.anchor1 || !this.anchor2) && this.DocumentView?.() && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView!())),
+ () => !this.anchor1 && !this.anchor2 && this.DocumentView?.() && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView!())),
empty => empty && ((this._hackToSeeIfDeleted = setTimeout(() =>
- (!this.anchor1 || !this.anchor2) && this._props.removeDocument?.(this.Document)
+ (!this.anchor1 && !this.anchor2) && this._props.removeDocument?.(this.Document)
)), 1000) // prettier-ignore
);
this._disposers.dragging = reaction(
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 4b6ee7d72..c9c8f9260 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -185,8 +185,9 @@ export class LinkDocPreview extends ObservableReactComponent doc.type === DocumentType.WEB)
+ .lastElement() ?? Docs.Create.WebDocument(this._props.hrefs[0], { title: this._props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true });
DocumentManager.Instance.showDocument(webDoc, {
openLocation: OpenWhere.lightbox,
willPan: true,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 5c779734d..66df1eaf2 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1607,7 +1607,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent node that wraps the hyerlink
while (target && !target.dataset?.targethrefs) target = target.parentElement;
FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true');
- } else {
+ } else if (node) {
try {
editor.dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(xpos))));
} catch (e) {
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 483035e86..5e53a019e 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -295,7 +295,7 @@ export class RichTextRules {
// create a hyperlink to a titled document
// @()
- new InputRule(new RegExp(/(^|\s)@\(([a-zA-Z_@:\.\? \-0-9]+)\)/), (state, match, start, end) => {
+ new InputRule(new RegExp(/(^|\s)@\(([a-zA-Z_@\.\? \-0-9]+)\)/), (state, match, start, end) => {
const docTitle = match[2];
const prefixLength = '@('.length;
if (docTitle) {
@@ -380,17 +380,17 @@ export class RichTextRules {
}),
// create a text display of a metadata field on this or another document, or create a hyperlink portal to another document
- // wiki:title
- new InputRule(new RegExp(/wiki:([a-zA-Z_@:\.\?\-0-9]+ )$/), (state, match, start, end) => {
- const title = match[1];
+ // @(wiki:title)
+ new InputRule(new RegExp(/@\(wiki:([a-zA-Z_@:\.\?\-0-9 ]+)\)$/), (state, match, start, end) => {
+ const title = match[1].trim().replace(/ /g, '_');
this.TextBox.EditorView?.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))));
this.TextBox.makeLinkAnchor(undefined, 'add:right', `https://en.wikipedia.org/wiki/${title.trim()}`, 'wikipedia reference');
const fstate = this.TextBox.EditorView?.state;
if (fstate) {
- const tr = fstate?.tr.deleteRange(start, start + 5);
- return tr.setSelection(new TextSelection(tr.doc.resolve(end - 5))).insertText(' ');
+ const tr = fstate?.tr.deleteRange(start, start + '@(wiki:'.length);
+ return tr.setSelection(new TextSelection(tr.doc.resolve(end - '@(wiki:'.length))).insertText(' ');
}
return state.tr;
}),
--
cgit v1.2.3-70-g09d2