Long text + Prompt + Variables

I am currently trying to figure out how to insert variables from prompt into long text. Inserting one or two sentences with a “+” is easy enough. But what is the best way to work with lots of text. I know there is the combination of prompt and insert text but the problem with this approach is too many prompts rather than a single prompt with multiple areas to enter data.

Maybe it is better to use Parse text action from the community repository?

Example:

Prompt looks like this:

//Set-up a basic prompt
let prClient = Prompt.create();
prClient.title = "Client Data";
prClient.addButton("OK");
//Client Info
prClient.addSelect("clinic", "Clinic", ["Allied Med", "Advanced Healthcare"]);
prClient.addTextField("name", "Full Name", "");
prClient.addTextField("DOB", "Date of Birth", "");
prClient.addTextField("DOL", "Date of Loss", "");
prClient.addTextField("DOA", "Date of Assessment", "");
prClient.addSelect("txNum", "Treatment Plan Number", ["First", "Second"], ["First"], true);

Pasted text looks like this:

Clinic: Clinic A
Name: Mr. John Smith
Date of Birth: July 13, 2020
Date of Loss: July 13, 1987
Treatment Plan: One

Paragraph one (lots of text).

Paragraph two with (lots of text) the name of the client.

Maybe template literals is what you’re seeking?

Awesome. This may do the trick.

Thank you.

As an Alternative to Prompt and Paste, I am trying Paste and Parse.

How can I combine create new Draft with content and then parse it as the next action? I tried adding Parse Content as “Include Action” in Actions menu but I get an error message

Script Error: SyntaxError: Can’t create duplicate variable: ‘d’
Line number: undefined, Column undefined

If I add One script and then another, it does not work either. What is the best way to combine them?

Action 1 - New Draft with Content to be Parsed

let d = Draft.create();
d.content = `Name: [[FirstName]] [[LastName]]
Date of Birth: [[DOB]]`;
d.addTag("prescreen");
d.update();
editor.load(d);

Action 2 - Parse and Update Take from Email Parsed Template

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _templateTagParser = __webpack_require__(1);

var parser = new _templateTagParser.TemplateTagParser();

if (parser.ask()) {
  var parts = [{
    name: 'draft',
    value: draft.content
  }, {
    name: 'title',
    value: draft.title
  }, {
    name: 'body',
    value: draft.content.split('\n').slice(1).join('\n')
  }, {
    name: 'selection',
    value: editor.getSelectedText()
  }, {
    name: 'clipboard',
    value: app.getClipboard()
  }];
  parts.forEach(function (part) {
    var parsed = parser.parse(part.value);
    draft.setTemplateTag("parsed_".concat(part.name), parsed.text);
    draft.setTemplateTag("parsed_".concat(part.name, "_html"), parsed.html);
  });
} else {
  context.cancel();
}

/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TemplateTagParser = void 0;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var TemplateTagParser =
/*#__PURE__*/
function () {
  function TemplateTagParser() {
    var template = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : draft.content;

    _classCallCheck(this, TemplateTagParser);

    this.template = template;
  }

  _createClass(TemplateTagParser, [{
    key: "ask",
    value: function ask() {
      var tags = this.tags;
      if (tags.length == 0) return true;
      var prompt = Prompt.create();
      prompt.title = 'Progress Report - Client Data';
      tags.forEach(function (tag) {
        return prompt.addTextField(tag, tag, '');
      });
      prompt.addButton('Okay');
      if (!prompt.show()) return false;
      tags.forEach(function (tag) {
        draft.setTemplateTag(tag, prompt.fieldValues[tag]);
        console.log("Setting ".concat(tag, " to ").concat(prompt.fieldValues[tag]));
      });
      return true;
    }
  }, {
    key: "parse",
    value: function parse(str) {
      var text = draft.processTemplate(str);
      var html = MultiMarkdown.create().render(text);
      return {
        text: text,
        html: html
      };
    }
  }, {
    key: "tags",
    get: function get() {
      var reservedTags = ['body', 'clipboard', 'created_latitude', 'created_longitude', 'created', 'date', 'draft_open_url', 'draft', 'latitude', 'longitude', 'modified_latitude', 'modified_longitude', 'modified', 'selection_length', 'selection_start', 'selection', 'time', 'title', 'uuid'];
      var pattern = /\[\[([\w ]+)\]\]/g;
      var tags = new Set();
      var match;

      while (match = pattern.exec(this.template)) {
        tags.add(match[1]);
      }

      return Array.from(tags).filter(function (tag) {
        return !reservedTags.includes(tag);
      });
    }
  }]);

  return TemplateTagParser;
}();

exports.TemplateTagParser = TemplateTagParser;

/***/ })
/******/ ]);

// Update content
//draft.content = draft.processTemplate("[[parsed_draft]]");
//draft.update("[[parsed_draft]]");
//
// Create a new draft from existing

var d = Draft.create();
d.content = draft.processTemplate("[[parsed_draft]]");
d.update();
editor.load(d);
draft = d;

That error message tells you that you are trying to re-define a variable, d.

I’m going to take a guess from how you have described some of the above that what you have marked as actions are what you have added as steps to a single action, so I’ll refer to them as steps instead, otherwise it could get very confusing.

In step 1 you define d like this.

let d = Draft.create();

In step 2, the definitions from step 1 still apply. Think of the action as being a single session. In step 2 this line defines d again.

var d = Draft.create();

It was originally defined with a let so that isn’t allowed.

Now I’m not clear on why you would be creating a new draft twice with differing content, so it could well be that I’ve misinterpreted thing and that they really are separate actions, in which case the error presumably belongs to action 2; and therefore I’m a bit lost as to how action 1 is relevant as the content looks substantially different.

But if you do have a variable conflict that would then come from one of the imports.

To avoid name conflicts define variable names uniquely. To be honest, d may be quick to type and fine for short scripts, but it isn’t very descriptive.

As to how to combine multiple actions, well you can carefully merge the steps and deal with any conflicts such as this, or you could also look at queueAction(). Each approach has its own pros and cons.

Hope that helps.

Thank you for the explanation of the error message.

How would you make this workflow work?

  1. Create a new draft with predefined text and tag. The text contains multiple [[fill-in-fileds]] like name, date of birth, phone…

  2. Run Parse Draft action that scans the draft for [[text]] and brings up a Prompt to fill in the information. After pressing ok, the draft content is updated with values from the prompt.

From my understanding, I can create one Action and have two scripts in it. Script 1 one pastes text and Script 2 parses content. The problem that I have is that running one action that has

Here is what I got so far but I can’t seem to figure out why the Parse action creates a new Draft after the text was pasted instead of updating the existing draft.

Action: https://actions.getdrafts.com/a/1aS

let d = Draft.create(); in step 1 creates a new Draft.

// Update content
draft.content = draft.processTemplate("[[parsed_draft]]");
draft.update("[[parsed_draft]]");

This references draft which is the draft you had loaded when the action was first run. Try changing those references to your new draft d.

I changed it to

// Update content
draft.content = draft.processTemplate(d);
draft.update(d);

As a result, I get a propound then two notes. One is the inserted text (not parsed) and the other one contains this as content

[object ActionKit.ScriptObjectDraft]

There are a lot of instances where draft was being used rather than d.

I had a quick run through and I think this is probably the combination you were attempting. Note it can be added to an action as a single Script step.

let d = Draft.create();
d.content = `Name: [[FirstName]] [[LastName]]
Date of Birth: [[DOB]]`;
d.addTag("prescreen");
d.update();
editor.load(d);

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _templateTagParser = __webpack_require__(1);

var parser = new _templateTagParser.TemplateTagParser();

if (parser.ask()) {
  var parts = [{
    name: 'draft',
    value: d.content
  }, {
    name: 'title',
    value: d.title
  }, {
    name: 'body',
    value: d.content.split('\n').slice(1).join('\n')
  }, {
    name: 'selection',
    value: editor.getSelectedText()
  }, {
    name: 'clipboard',
    value: app.getClipboard()
  }];
  parts.forEach(function (part) {
    var parsed = parser.parse(part.value);
    d.setTemplateTag("parsed_".concat(part.name), parsed.text);
    d.setTemplateTag("parsed_".concat(part.name, "_html"), parsed.html);
  });
} else {
  context.cancel();
}

/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TemplateTagParser = void 0;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var TemplateTagParser =
/*#__PURE__*/
function () {
  function TemplateTagParser() {
    var template = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : d.content;

    _classCallCheck(this, TemplateTagParser);

    this.template = template;
  }

  _createClass(TemplateTagParser, [{
    key: "ask",
    value: function ask() {
      var tags = this.tags;
      if (tags.length == 0) return true;
      var prompt = Prompt.create();
      prompt.title = 'Progress Report - Client Data';
      tags.forEach(function (tag) {
        return prompt.addTextField(tag, tag, '');
      });
      prompt.addButton('Okay');
      if (!prompt.show()) return false;
      tags.forEach(function (tag) {
        d.setTemplateTag(tag, prompt.fieldValues[tag]);
        console.log("Setting ".concat(tag, " to ").concat(prompt.fieldValues[tag]));
      });
      return true;
    }
  }, {
    key: "parse",
    value: function parse(str) {
      var text = d.processTemplate(str);
      var html = MultiMarkdown.create().render(text);
      return {
        text: text,
        html: html
      };
    }
  }, {
    key: "tags",
    get: function get() {
      var reservedTags = ['body', 'clipboard', 'created_latitude', 'created_longitude', 'created', 'date', 'draft_open_url', 'draft', 'latitude', 'longitude', 'modified_latitude', 'modified_longitude', 'modified', 'selection_length', 'selection_start', 'selection', 'time', 'title', 'uuid'];
      var pattern = /\[\[([\w ]+)\]\]/g;
      var tags = new Set();
      var match;

      while (match = pattern.exec(this.template)) {
        tags.add(match[1]);
      }

      return Array.from(tags).filter(function (tag) {
        return !reservedTags.includes(tag);
      });
    }
  }]);

  return TemplateTagParser;
}();

exports.TemplateTagParser = TemplateTagParser;

/***/ })
/******/ ]);


d.content = d.processTemplate("[[parsed_draft]]");
d.update();
editor.load(d);

This gives me two lines with a name and DoB placeholder in a (single) new draft. It throws up a prompt for entering the first name, last name and DoB. After entering those, it substitutes in the values from the prompt for the values in the draft.

Thank you. I guess this is the way to go.

I was initially trying to separate the steps within the Action so that Insert Tex is a separate action. The reason for this is to quickly access it and edit if needed.

You could still break that up, my point was that it was unnecessary for the two actions setup that you described in the first post. But remember if you are using the Insert Text step, that will almost certainly get lost as you are switching drafts around in the editor and updating.

The best option there would probably just to be to include any insert text sort of content in that initial setting of d.content. After all, that is effectively what it is doing; inserting test, just into a new drafts is all.