A simple program for sending markdown formatted emails quickly. It also allows for sending attachments to the emails. It can expand macros defined using Handlebars. It also has notes, scripts to act on the text, and Handlebar templates. You can set default data to be used in the expansions. I'm still actively developing this program, but the basics are functional. I've only built it as a macOS M1 build. I'll be adding other builds in the future. Right now, I just have a Macbook Pro M1 system to develop on. This program is built with Wails and Svelte.
If you want to compile it yourself, it is really easy to do. Just follow the directions under How to Build.
It also has a easy to use TUI for sending emails from the command line. By using flags to fill in the address for sending, subject line, and body, you can quickly send an email. It will then open in a TUI or you can have it send it directly. This is what the TUI looks like:
The email that was sent by this recording is shown here in my Gmail account:
Along with all of this, it has a command prompt that is easily set to follow your directory changes in the terminal for allowing you to run scripts on files or simply launch files with your editor or whatever program is set on your system. I call it ScriptLine since it's main purpose is for running scripts.
If you have questions, you can ask them in the Discussions. If you have a bug, please create an Issue for it. Thanks.
In order to build the program, you have to have node and npm, go and Wails 2 installed on your system.
For the first time, you need to download the libraries used by:
cd frontend
npm install
npm run build
To build the program and package it properly, you run:
wails build
or, if you want to build the macOS universal application, you run:
wails build --platform "darwin/universal"
If you want to develop the program, you can run developer mode with:
wails dev
The maskfile supplied will compile the universal build on macOS. You can invoke it with:
mask build
You can look at the maskfile.md file to see what the build command does if you don't want to use mask itself.
I develop on a MacBook Pro M1 system. Therefore, all features do work on a similar system. I'm trying to test and use it on Linux and Windows, but I don't currently have a Windows system to work with.
EmailIt came about when my favorite email sending program went vaporware on me (The Let.ter application for macOS). I still needed a way to send markdown based emails to people quickly. I then merged in the functionality of ScriptPad program I created to have multiple notes, text altering scripts, and templates. I often need to reference or copy something from a note to an email. I also have many email templates that I use in the Template interface.
I use this program everyday and is very helpful to my workflow. I hope you enjoy it as well.
I have yet to figure out how to make EmailIt a normal mailto protocal handler, but you can do it with the help of LinCastor. When you download the program and create a mailto protocal handler, add this script:
#!/bin/zsh
# the script will execute with following environmental variables defined:
# URL => my-http://myhost.domain.com:8080/mysite/a.html?search=blah#myanchor
# URL_SCHEME => my-http
# URL_HOST => myhost.domain.com
# URL_PORT => 8080
# URL_QUERY => ?search=blah
# URL_PATH => /mysite/a.html
# URL_PATH_EXT => html
# URL_PATH_NAME => a.html
# URL_FRAGMENT => #myanchor
# URL_VALUE => everything that comes after the 'scheme:'
# URL_B64VALUE => the same as URL_VALUE but decoded using based64
#
# NOTE: The system env variable (e.g. PATH) may have different values
# then what you would get if you would run the script in the terminal.
#
# if you are mapping a file extension, use URL_PATH to pass the file path
#
# ---
#
# If you intended to trigger this handler from a bookmarket,
# you can 'print out' valid javascript code to be execute in the browser when this scripts returns.
# Unless you execute the command asynchronosly in the Terminal.
#
# ---
#
# you should exit with 0, this means the handler has finished succesfully
# non-zero value indicates an error
/Applications/EmailIt.app/Contents/macOS/EmailIt $URL
And then click the 'Save and Activate' button in the lower right corner.
Once done, anytime you click on a mailto link, it will open in EmailIt for your additions before sending.
When you launch the program, the EmailIt main screen is shown:
Here, you can easily type in an email address, a subject line, and the text body. The text body is assumed to be markdown format. It will be sent to the Handlebars macro expander and then converted to HTML and plain text email. The buttons along the bottom show the different functions that can be accessed at this screen. Any email address used is saved into the Address Book. When you enter the To
field, a list of addresses from the Address Book will be displayed. As you type, the list will contract to the ones that match what you are typing.
Before you can send an email, the email SMPT servers need to be setup. When you first run the program without any server, the button that says CustomCT
will say Create a New Account
. When you click it, you will be shown the accounts dialog.
:
I have several accounts setup, but for your first time, it will only have the buttons on the bottom. When you click on of the account buttons, that account is set to the Current Account
. If you click Cancel
, the current account will go back to the one when you first entered this dialog. If you click Delete
, the Current Account
will be deleted and changed to the topmost account in the list. If you click Save
, you will go to the main screen with the account button showing the name of the account you selected. If you click New
, the New Account dialog will be shown.
The Default
checkbox will make the new account the default account. All the other fields are fairly self explanitory. They are the different information needed to connect to most SMPT servers.
When you scroll down the new accounts dialog, the bottom fields are seen. The Signiture
field is added to the end of all your emails. This should be in HTML format. The Header HTML
and Footer HTML
will be placed at the top and bottom of your email. This is where you can customise the look of your email with font size, color changes, etc. You would put an opening <div>
with your custom styling in the header HTML and the footer HTML would close it out.
When you are done, simply click Save
or Cancel
if you don't want to save it. Either one will take you back to the main screen.
Once your message is typed, addressed, and has a subject, you can click the Preview
button to see what it will look like:
If you like what you see, you can click Send
. Since my configuration doesn't setup any background or foreground colors, you see the default for the EmailIt program (or if you change the theme, whatever the new theme uses). The person that receives it will see the colors their email program uses (usually white background with black type). If you click Edit
, you will go back to the main screen with the information you typed in still there. If you press Clear
, you are sent to the main screen without any information. Back to the beginning to start over.
When you click Address Book
on the main window, you will get the Address Book dialog.
Here, you can edit an address by clicking the pencil, delete an address by clicking the X
, and create a new address by clicking New
button. These addresses are collected when you write an email or when you add them in this dialog.
When you click Notes
button on the main screen, you will see the notes you are keeping in the program.
The ten color circles to the right select the different notes. I use one as a scratch pad for running text altering scripts. The buttons on the bottom go to different parts of the program.
In the EmailIt editor or the Notes editor, you can click the Scripts
button or <ctrl>-m
to toggle the scripts menu.
The input at the top allows you to search the list by removing all items that don't match the letters you type. When you select a script and have text selected, it will process that text with the script and replace it with the results. If you don't select text, it will process the entire note.
You can create or edit your scripts when you press the Edit Scripts
button.
The script editor is where you can create or edit your different scripts. System scripts or External scripts can't be edited here. When you type the Name
field, it will show scripts similar to what you type. If you select one of them, you can edit that script. If you give a unique name, you can create that script.
The Insert?
checkbox is for telling the editor to insert the output of the script.
The Terminal Script
tells the program that the script is for the Script Terminal and the output is a JSON structure for displaying information that can be acted upon. This is described more in the Script Terminal section.
The Description
field is for a brief description of what the script does. For a Terminal Script, it is displayed in the help
command.
The text editor area is for writing your JavaScript routine. The SP
object is how you get information and run different functions.
The variable SP.text
contains either all the text in the note if there wasn't a selection, or just the selected text. You read this variable to get the text to process and write into the variable what you want to replace either the selection or all the text in the notepad.
There are some predefined libraries in variables for your scripts to use. You can make use of the following:
SP.mathjs | Math.js library |
SP.mathParser | The Math.js parser used to process text |
SP.DateTime | luxon library |
SP.Handlebars | Handlebars library |
The are some predefined function available as well:
SP.insertCharacters(<num> ,<char> ) |
This function makes a string of <num> <char> . |
SP.returnNote(<id> ) |
This function returns the note with the <id> . |
SP.runScript(<scrpt> ,<text> ) |
This function runs the <scrpt> as a string on the <text> text. |
SP.ProcessMathSelection(<text> ) |
Runs the given text through the Math.js parser. |
SP.ProcessMathNote(<id> ) |
Run the given note id through the Math.js parser. |
These functions will not be usable for external scripts. They are for internal JavaScript scripts and internal Scriptline commands.
When creating terminal commands for Scriptline, the SP
structure will have these added data points:
SP.data.previousLines | This will contain the previously ran command. |
SP.data.registers | This is an array of text registers that can hold information from one chained command to the next. |
SP.data.line | This is the command line for the currently executing command. |
SP.data.result | This is the previous commands result. |
This structure can change over time. I'm still experimenting with many ideas for it. I have plans for creating more functions to be used with this scheme. Stay tuned!
You can create script in one note and use a different note for the input. For example, in a note, place the following code:
try {
var lines = SP.text.split('\n');
SP.text = '';
for(var i = 0; i < lines.length ; i++) {
var match = lines[i].trim().match(/^\d+\. (.*)$/);
if (match != null)
SP.text += match[1] + '\n';
}
} catch (e) {
SP.text += "\n\n" + e.toString()
}
Then go to a different note and place several lines of text. Run the
script Bullet lines with Numbers
. Every line will have the proper number at the front of it. Now, run the script Evaluate Note # as Script
with #
the number of the note where you put the script. The numbers at the beginning will now be removed! You can use the script editor to save this script and use it from the script menu.
There are scripts for processing math: the 'Basic Math' and 'Evaluate Page for Math' scripts. The 'Basic Math' script is for processing arbitrary pieces of math in a selection. The 'Evaluate Page for Math' script is for processing the entire note with a nice running result along the right. The 'Basic Math' script doesn't reset the state of the math library (ie: variable definitions and functions), but the 'Evaluate Page for Math' does each time invoked so as to not create multiple copies of function and variables.
Copy the following note to a notepad:
# Using the ‘Evaluate Page for Math’ script
Your notes can have any text you need. But when a line starts with a ‘>’, t
hat whole line is processed for math. The line is processed and the answer pushed
to the right with a ‘|’ symbol.
> 6 * 95
> x=6*8-10
> x
Text in the middle doesn’t clear out the variable or function assignments before it.
> f(x)=x^2-5*x+12
> f(60)
> f(x)
The length of the note isn’t a concern either.
> f(100)
> bank=34675
> check=5067
> balance = bank - check
> sin(45)
The math package used doesn’t do conversions or symbols inside of the mat
h expressions. The math library used is [mathjs 4.0](http://mathjs.org/).
Then press <ctrl>-m
and select the 'Evaluate Page for Math' script. Each line with the '>' as the front character now has the results to the right. When you change the text lines and re-run the script, the math lines are all updated. All other lines are not effected by the script. You can change any equation or variable and it's effects will trickle down the page.
In the EmailIt editor or the Notes editor, you can click the Templates
button or <ctrl>-t
to toggle the template menu.
The input at the top will filter the list according to the letters typed. When you select a template, it is placed at the cursor point in the note.
You can create/delete/edit templates in the Template Editor. You access the Template Editor by the Edit Template
button at the bottom of the Note Editor.
When you type in the Name
field, a list of templates that match the text is given. Selecting one of the templates allow you to edit that template. By typing a new name, you can create a new template.
The Description
field is for giving a short description.
To save the new or edited template, you press the Save
button at the bottom. To delete the current template in the editor, press the Delete
button at the bottom of the editor.
The text editor is where you create your template. Templates are processed using Handlebars parser. Handlebars allows you to have a text file with anything in it along with some macros. Some macros need auguments and some do not. The macros are expanded and placed into the text. Macros with arguments are called helpers. Along with the standard Handlebar helpers, several others have been added as well. The following is an explanation of the additional helpers:
{{date <format>}} |
This will format the current date and time as per the format string given. See the help document that is loaded upon initialization. |
{{cdate <date/time> <format>}} |
This takes the date/time string and formats it according to the format given. See the help document that is loaded upon initialization. |
{{last <weeks> <dow> <format>}} |
This will print the date <weeks> ago in the <format> format for the <dow> day of week. |
{{next <weeks> <dow> <format>}} |
This will print the date <weeks> in the future using the <format> format for the <dow> day of week. |
The following data expansions are defined as well:
{{cDateMDY}} |
gives the current date in Month Day, 4-digit year format |
{{cDateDMY}} |
gives the current date in Day Month 4-digit Year format |
{{cDateDOWDMY}} |
gives the current date in Day of Week, Day Month 4-digit year format |
{{cDateDOWMDY}} |
gives the current date in Day of Week Month Day, 4-digit year format |
{{cDay}} |
gives the current date in Day format |
{{cMonth}} |
gives the current date in Month format |
{{cYear}} |
gives the current date in 4-digit year format |
{{cMonthShort}} |
gives the current date in Short Month name format |
{{cYearShort}} |
gives the current date in 2-digit year format |
{{cDOW}} |
gives the current date in Day of Week format |
{{cMDthYShort}} |
gives the current date in Month day 2-digit year format |
{{cMDthY}} |
gives the current date in Month Day 4-digit year format |
{{cHMSampm}} |
gives the current date in h:mm:ss a format |
{{cHMampm}} |
gives the current date in h:mm a format |
{{cHMS24}} |
gives the current date in H:mm:ss 24 hour format |
{{cHM24}} |
gives the current date in H:mm 24 hour format |
I'm working on a way to have user defined Handlebar helpers and macros.
The Scriptline is a terminal that runs scripts in the EmailIt program on text given or on files given. You access the Scriptline from any other screen by pressing <ctrl>-s
. It can also be opened from a command sent to the internal server.
The list under the output list is traversable using the j
and k
or the up arrow
or the down arrow
keys. When you press Enter
, it will execute the command for that line. The list can be filtered by pressing the /
key and typing a string in the search box on the lower right of the list. You can use the <ctrl>-j
and <ctrol>-k
keys to move the selection up and down while the filter box is visible. Pressing Enter
key will close the filter box and return the list to normal with the selection still highlighted as when filtering.
By typing help, you will see all script commands and scripts. The current list of builtin commands are:
help | Show the help command in the terminal. |
ls | List the items in the specified directory. |
cd | A terminal script for changing directories. |
open | Open the file given. |
runscript | Run a script on a file or text string. |
edit | Edit the given file. |
alias | The alais command allows you to substitute a single command for a list of commands. |
hist | The hist command lists the previous command lines that worked. You can activate one to rerun the command. |
rm | The rm command will delete the given file or directory. If nothing is given, it will list the current directory and an item can be delete using the command mode and r. |
mkdir | The mkdir command makes the given directory if it doesn't already exist. |
mkfile | The mkfile command makes the given file if it doesn't already exist. |
rmalias | This command removes the given alias. |
notes | This command will go to the notes. |
scripteditor | This command will go to the Script Editor. |
emailit | This command will go to the EmailIt. |
quit | This command will quit the EmailIt program. |
This is in no way a full terminal emulator. It is a simple line based command runner. No pipes, redirections, flow control, etc using glyphs, but Scriptline commands can use some flow control by taking advantage of the data given. I mostly use this to run scripts on text files. You can run several commands at once by separating them with a ;
or by using functional programming style of function chaining. When you have a series of commands, each command can access what the previous command was and it's output in the SP
data structure. Even external commands can get this information. Only the last command ran can be used for showing results. The command chaining can be used in the commands for the Command state or tcommand
fields in the terminal script JSON output.
All scripts for use in the Scriptline have to take in a JSON structure called SP
(same structure described in the scripts section but with some added fields) and output a JSON structure that tells the script terminal what to do. The JSON output structure is:
{
tcommand: <terminal command to run>
lines: [{
text: <text to display>,
color: <color to show>,
command: <command line string to run when selected>
}, {
<next line structure>
}, ...]
}
The tcommand
is a builtin command that is ran directly when the command is ran.
The lines
structure is an array of objects containing a text
field with the text to be printed to the terminal, color
field is the color to print the output in, and a command
field to be executed when the Enter
key is pressed on the line.
The valid colors are: red, black, green, orange, blue, magenta, cyan, gray, and default. These colors are controlled by the current theme for EmailIt. The default color is the text color.
If you add the following to your .zshrc
file (for the zsh shell. You will have to adapt it for your particular shell.):
function changewd() {
wget -O /dev/null -q -nv --method=PUT --body-data="{\"wd\": \"$1\"}" --header='Content-Type:application/json' 'http://localhost:9978/api/wd' 2>&1 > /dev/null
}
function cd() { builtin cd "$@" && changewd "$(pwd)"; }
This will use the server API endpoint for changing Scriptline current directory each time you use the cd
command. You have to have the wget
command line tool installed as well. This is easily installed with Homebrew with this command:
brew install wget
You can enter act with EmailIt from the command line. It has some TUI programs that make using the overall program from the command line easy. The command line for EmailIt has flags and commands. In order to use the program from the command line, you need to make an alias to the programs executable file for the macOS:
alias em=/Applications/EmailIt.app/Contents/MacOS/EmailIt
With the above line in your .bashrc
or .zshrc
file (you will have to make a similar line for other shells), you can run the EmailIt program from any directory. The different command line options are shown with the basic -h
or --help
flag or the help
or h
command:
> em help
NAME:
EmailIt - A program for sending emails, working with text, and scripts.
USAGE:
EmailIt [global options] command [command options] [arguments...]
VERSION:
v2.1.0
AUTHOR:
Richard Guay <[email protected]>
COMMANDS:
mkemail, me Create an email using a TUI
notes, n Open the notes.
emailit, e Open the EmailIt email sending application.
scriptline, sl Open the ScriptLine application.
sendemail, se Send the email directly. No GUI or TUI.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
-a value Address to send an email
-s value Subject for the email
-b value Body of the email
--help, -h show help
--version, -v print the version
COPYRIGHT:
(c) 2022 Richard Guay
The -a
flag will take the value
and put it for the address to which to email. The -s
flage will take the value
and place it in the Subject
field of the email. The -b
flag will take the value
and place it in the body of the email. The mkemail
or me
command will then open the TUI for creating the email. The sendemail
or se
command will take the command line information and send the email directly without using the TUI. The notes
or n
command will open EmailIt to the notes screen. The scriptline
or 'sl' command will open the Scriptline screen. The emailit
or em
command will open the EmailIt screen.
The TUI looks like this:
The preferences can be reached by pressing <ctrl>-p
or <cmd>-,
anywhere in the program. There are four sections currently: General, Theme, Node-Red, External Scripts, Environments, and GitHub.
The general section currently is empty. I'm adding functionality to install workflows for Alfred, Launchpad, Keyboard Meastro, etc.
The Theme preference is where you can create and change your theme. By selecting new
in the theme selector, you can create a new theme based on the current theme. The circle colors are for the Notes editor note selector on the right. The Update Theme
button will save your changes. The Delete Theme
button will delete the currently selected theme and set the default theme. You can change the color by clicking on the color circle.
You can adjust the color by selecting an area in the color wheel. When you get the color you like, press the Select
button. Pressing the Cancel
button will go back to the original color.
You can use external scripts to process text and for use in the Scripts Terminal. To setup a external script for using in EmailIt, simply go to the External Scripts Preferences.
The main screen shows the currently created external scripts. Clicking on a script name will open it in the External Script Editor. Clicking the New
button will open the External Script Editor in a blank script.
Here you setup the different setting for the external script.
The Name
field is the name used in the Scripts Menu and for the SPRunScript
Node-Red node. It doesn't have to anything to do with the actual name of the script file.
The Description
field is used to describe the action the script will perform. For Terminal Scripts, it will be shown in the general help builtin command.
The Help
field is displayed for terminal commands when you add the script name to the help
builtin command.
The What's the name of the Script File?
is where you put the real name of the script. This should be the main file for running the script. It should be executable and have the proper #!
(shebang) as the first line of the script.
The What's the directory of the script?
field is the full path to the directory that contains the script.
The What is the environment for the script?
is a drop-down selector for selecting the environment to use for running the script.
The Terminal Script?
checkbox is for specifying if this is a terminal script.
All external scripts are ran using an environment. The environment describes the environment variables that are set before running the script. This is very useful for setting up a path for a particular version of a program. Scripts are always ran in the directory of the script.
The main screen shows the different environments defined already. If there isn't a Default
environment, then a button is shown to create it. Clicking on an environment name opens it in the environment editor.
The environment editor has the name at the top just like in the Theme Editor. Changing the name allows you to create a new environment based on the currently selected one. You can delete rows by clinking the X
or edit the row by clicking the pencil. The Delete
button will delete the currently displayed environment. The Return
button will save all changes and go back to the environment list.
The GitHub importing screen allows you go import external scripts and themes that are stored on GitHub. To install the script or theme, click the install
button. Themes then have an extra button to load
the theme downloaded.
In order for this importer to find the script and themes, your script or theme has to have the emailit
topic. A script will need the script
topic as well, while a theme will need the theme
topic included.
When a script or theme is downloaded, a delete
button will be shown. You can remove the script or theme by pressing the delete
button.
In order to load the script properly, the package.json
file in the script's repository has to have these added fields:
"script": {
"name": <name of the script>,
"description": <a short description of what the script does>,
"help": <help text for the script>,
"termscript": <boolean flag for a Script Terminal script (true if it is a script terminal script. Otherwise, false.)>,
"script": <the scripts full name in the repository including extension>,
}
In order to load the theme properly, the package.json
file for the theme's repository has to have these added fields:
"theme": {
"name": <name of the theme>,
"description": <description of the theme>,
"main": <the json file for the theme>,
}
EmailIt has a web based API for interfacing with other applications,
command line tools, or whatever else would help. The base address for the APIs is http://localhost:9978/api
. Every endpoint in this table builds on this base. These endpoints only allow access from requests on the same machine.
Endpoint | Description |
---|---|
/api/note/:noteid/:type | For a PUT method, if the type is a , the given text in the body JSON structure with the index note is appended to the note noteid . If the type is w , it will overright. For a GET method, it will return the note in question. |
/api/wd | This is a PUT endpoint with a directory path given in the JSON body with the index Wd . Scriptline will then be at that directory. |
/api/script/env/list | This is a GET endpoint that returns a list of environments. |
/api/scripts/list | This is a GET endpoint that returns a list of scripts. |
/api/script/run | This PUT endpoint that will run the given script. |
/api/template/list | This is a GET endpoint that returns a list of scripts. |
/api/template/run | This is a PUT endpoint that will run the given template. |
/api/emailit/mailto | This is a GET endpoint that will set the To , Subject , and Body field of an email and open the EmailIt screen. |
/api/emailit/send | This is a PUT endpoint that will send and email. |
/api/emailit/open | This is a GET endpoint that will open the EmailIt screen. |
/api/notes/open | This is a GET endpoint that will open the notes screen. |
/api/scriptline/open | This is a GET endpoint that will open the Scriptline screen. |
All the endpoints are used to make the plugins for Alfred, Keyboard Maestro, Dropzone, PopClip, and Launchpad. Also, the ScriptBar program uses these endpoints as well. I'm planning to add serving pages on the user's computer and other functionality as well. I have lots of ideas.
Terminal Script
checkbox.Moving the whole project to Tauri and CodeMirror 6 along with an email utility. I'm renaming it all to EmailIt. Notes, running scripts, displaying the log, and the EmailIt parts are working.
Insert
labelEmailIt