• Stars
    star
    192
  • Rank 202,019 (Top 4 %)
  • Language
    Python
  • Created about 11 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

QuoteFix for Apple Mail —

QuoteFix for Mac

Important notice

I decided to not accept requests for new features for the time being, primarily due to lack of time. Any feature requests will be closed (but tagged so if things quiet down, I can reopen them).

However, do keep submitting bug reports. I'll try and fix them as fast as I can.

Latest releases

The latest release can always be found here.

FAQ

See the wiki.

What is it?

QuoteFix is a plug-in for Mail.app which fixes some issues with replying to e-mail:

  • it tries to remove the signature from the original message;
  • it removes certain unnecessary empty lines;
  • it positions the cursor below the original message, instead of above it (in other words, bottom-posting instead of top-posting);
  • it can (optionally) prune nested quotes from a specific level and above;

It also provides customized attributions for replies and forwards.

Installation

Before installing the plug-in, you'll need to make sure that Mail.app's plug-in support is turned on. For this, execute the following two commands in Terminal.app:

defaults write ~/Library/Containers/com.apple.mail/Data/Library/Preferences/com.apple.mail.plist EnableBundles -bool true
defaults write ~/Library/Containers/com.apple.mail/Data/Library/Preferences/com.apple.mail.plist BundleCompatibilityVersion 4

Next, perform the following steps:

  • Download the plugin if you haven't done so already
  • Navigate in Finder to ~/Library/Mail/ (where ~ means: your home directory)
  • If a Bundles folder doesn't yet exist, create an empty one
  • Extract the downloaded ZIP file and copy QuoteFix.mailbundle into the Bundles folder
  • Lastly, quit Mail.app if it's running, and start it up again.

In case you run into any problems, or want to uninstall QuoteFix, just remove QuoteFix.mailbundle from the bundle-folder and restart Mail.app.

Usage

After installation, QuoteFix is enabled. It will perform its magic automatically when you reply to, or forward, messages.

The behaviour of the plug-in is customizable via its preferences. QuoteFix has it's own preference pane in the preferences window of Mail.app. Most preferences speak for themselves, or have a useful tooltip which pops up when you hover the cursor above it.

If you temporarily want to turn off QuoteFix, but don't want to uninstall it, check off the QuoteFix is enabled checkbox. As of version 2.3.1, (de)activating QuoteFix can be done from a menu item in the Mail menu. You could use the standard way of assigning a keyboard shortcut to a menu item in Mac OS X to enable or disable QuoteFix with a keyboard shortcut.

Customized Attributions

QuoteFix also provides the ability to define your own attribution lines (the first line of a reply/forward, usually looking something like On SOME DATE, at SOME TIME, SOMEONE wrote:).

Customized attributions work by way of templates: you define a template in the preferences, and parts of the template will – at the time of replying or forwarding – be replaced by values reflecting parts of the message you are replying to or forwarding.

Templating works by replacing template variables with values. A template variable looks like this: ${VARIABLE}. It will be replaced with a value depending on what VARIABLE contains.

A (non-exhaustive) list of variables you can use:

${message.from} Name and e-mail address of sender of message:
Your Friend <[email protected]>
${message.from.name} Name of sender of message:
Your Friend
${message.from.email} E-mail address of sender of message:
[email protected]
${message.to} Your e-mail address (this is the address that was used for the message to reach you). This is more like the Delivered-To header than the To header (for that, see ${message.recipients})
${message.recipients} A list of all the recipients of the message, as mentioned in both the To and Cc headers.
${message.recipients.to} A list of the recipients of the message mentioned in the To header.
${message.recipients.cc} A list of the recipients of the message mentioned in the Cc header.
${message.subject} The subject of the message.
${message.sent}
${message.received}
Sent/received timestamps. If you want more finegrained control over formatting timestamps, these variables split into separate fields: year, month, day, hour, hour12, ampm, minute, second, weeknumber, monthshort, monthlong, dayshort, daylong, date, time.
Use these like so: ${message.sent.year}.

See below for more advanced date/time formatting options.

If you want even more freedom in formatting attribution lines, there's an experimental feature (which can be enabled in the Advanced preferences) which enables conditional statements, string/date formatting, and much more. This is based on a modified version of the pyratemp templating library for Python written by Roland Koebler.

A small example of what's possible:

From: ${message.from}
{% if message.recipients.to %}
 To: ${message.recipients.to.join("; ", "name")}
{% end %}
{% if message.recipients.cc %}
 Cc: ${message.recipients.cc.join("; ", "name")}
{% end %}
Subject: ${message.subject.lower()}
Sent-Date: ${message.sent.strftime("%d-%m-%Y")}

You can also enable HTML-formatting for your custom attributions. For this to work, the (outgoing) message format should be Rich Text. You can have QuoteFix automatically convert a message to Rich Text if your attribution should be interpreted in HTML. Otherwise, QuoteFix will issue a warning.

If you want to mimic the attribution generated by Outlook, try this (with HTML-formatting enabled):

<b>From:</b> ${message.from}
<b>Date:</b> ${message.received}
<b>To:</b> ${message.to}
<b>Subject:</b> ${message.subject}

When you're editing your customized attribution, QuoteFix will generate an approximate preview as tooltip of the text field you're entering the attribution in.

Advanced date/time formatting

If you want even more finegrained control over the formatting of dates and times, you can enable "advanced templating" in the Advanced preferences, after which date/time variables like message.sent and message.received will have .format() and .strftime() methods with which you can format the output of the objects.

Functionally, these two methods perform the same operation – namely formatting date/time objects – the difference is in the formatting strings used:

An example:

${message.sent.format("EEE MMM dd yyyy HH:mm:ss")}

This will output: Sun Nov 06 2011 10:19:34

Similarly, with .strftime():

${message.sent.strftime("%a %b %d %Y %H:%M:%S")}

However: the output will be generated in the current locale, which means that it will be formatted according to your local language settings.

To change this, both methods accept a second argument: a locale identifier. You can use it to convert the output to a certain locale, instead of the default locale (which can be changed in the System Preferences of Mac OS X: Language & Text > Formats).

The same example as above, but with a different locale:

${message.sent.format("EEE MMM dd yyyy HH:mm:ss", 'fr_FR')}

The output: dim. nov. 06 2011 10:19:34

If you want the default format, just in a different locale, use the .locale() method:

${message.sent.locale('fr_FR')}

Enabling/disabling the plug-in

QuoteFix has various ways of turning off its behaviour, short of uninstalling it:

  • You can turn QuoteFix off from its preferences; this will disable the plug-in until you enable it again;
  • You can quickly turn the plug-in on/off from the Mail menu. If you want, you can even assign a keyboard shortcut to this menu item from System Preferences;
  • You can toggle the enable (or disable) status of QuoteFix for a single message by pressing down Option whilst initiating a Reply/Forward action. That is:
    • When QuoteFix is disabled, pressing Option will enable QuoteFix for that particular message only;
    • Likewise: when QuoteFix is enabled, pressing Option will disable QuoteFix for that particular message only;

Building the plug-in

If you want to build the plug-in yourself, ideally you need to use a non-system Python interpreter (although not strictly necessary if you want to use the plug-in on your system only).

I use Python 2.7.5 as installed by Homebrew. I also use virtualenv to create a clean environment in which to build the plug-in.

Make sure the following requirements are installed:

pip install pyobjc # might take some time
pip install py2app

Next, clone the repository:

git clone https://github.com/robertklep/quotefixformac.git

And build the plug-in:

cd quotefixformac
python setup.py py2app

This will build the plug-in, which can be located in dist/.

Licence & copyright

This plugin is written by Robert Klep and is provided "as-is", without any warranties whatsoever.

QuoteFix source, downloads and support is hosted by GitHub at https://github.com/robertklep/quotefixformac

QuoteFix uses the Sparkle framework from Andy Matuschak to provide software updates, which comes with the following permission notice:

Copyright (c) 2006 Andy Matuschak Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

See also http://sparkle.andymatuschak.org/.

Like Quotefix?

Consider making a donation:

ETH: 0x93eaE7ad708EF996bdd2d03d42D10dB278E29172

More Repositories

1

dsm7-usb-serial-drivers

Synology DSM 7 USB serial drivers
C
372
star
2

top-level-await

Use `await` at your Node.js code's top level!
JavaScript
126
star
3

node-mbox

mbox file parser for Node.js
JavaScript
68
star
4

ToggleProxy

Mac OS X menu item for quickly enabling/disabling proxies.
Python
42
star
5

bosch-xmpp

Protocol implementation for Bosch XMPP protocols
JavaScript
38
star
6

nefit-easy-http-server

HTTP server to access Nefit/Bosch XMPP backend over HTTP
JavaScript
38
star
7

node-instapaper

Instapaper API client for Node.js
JavaScript
34
star
8

node-benchr

Node.js benchmark runner
JavaScript
27
star
9

node-metrohash

Node.js bindings for MetroHash
C++
25
star
10

node-monkeypatch

Slightly easier monkeypatching
JavaScript
22
star
11

node-trakt-api

Trakt API v2 client for Node.js
JavaScript
21
star
12

nefit-easy-core

Core functionality to implementation communications with Nefit/Bosch backend.
JavaScript
20
star
13

nefit-easy-client

Nefit Easy™ client for Node.js
JavaScript
15
star
14

nefit-easy-commands

High-level command implementation for Nefit Easy™ clients.
JavaScript
14
star
15

homebridge-klikaanklikuit

Homebridge plugin for KlikAanKlikUit outlets
JavaScript
14
star
16

homebridge-nefit-easy

Homebridge plugin for Nefit Easy™
JavaScript
14
star
17

nefit-easy-cli

Command line interface for communications with Nefit/Bosch backend.
JavaScript
14
star
18

buffered-ext-list-sencha-touch-2

Buffered Ext.List for Sencha Touch 2
JavaScript
13
star
19

name.klep.homekitty

HomeyKit 3.0
JavaScript
13
star
20

node-port-mux

TCP port multiplexer: run multiple services through the same port
JavaScript
13
star
21

node-sabnzbd

Node interface for SABnzbd
JavaScript
11
star
22

qbittorrent

Node.js qBittorrent API client
TypeScript
11
star
23

name.klep.homekit-controller

HomeKit Controller — Allow Homey to control HomeKit-enabled devices
JavaScript
9
star
24

react-boilerplate

React.js (+ Express + Browserify) boilerplate
JavaScript
9
star
25

name.klep.sonoff

Homey driver for Sonoff devices
HTML
7
star
26

homey-mocks

Mock objects for Homey pairing/setting pages
JavaScript
7
star
27

node-kaku-rpi

Node.js KlikAanKlikUit (KaKu) driver for Raspberry Pi
JavaScript
7
star
28

homey-app-upload

Homey App Upload
JavaScript
4
star
29

name.klep.transitions

Homey app — Flexible Time Transitions
JavaScript
4
star
30

node-dsmr-parser

Dutch Smart Meter Requirements protocol parser
JavaScript
4
star
31

supergenpass-cli

CLI wrapper around supergenpass-lib
JavaScript
4
star
32

socks-proxy

SOCKS5 proxy with whitelisting and built-in admin
JavaScript
3
star
33

node-rewriting-proxy

A Node.js-based request/response rewriting HTTP proxy
JavaScript
3
star
34

node-filtering-proxy

Standalone Node.js based HTTP/HTTPS proxy with request/response modification
JavaScript
2
star
35

ancs2mqtt

Use an ESP32 to relay iOS notifications to MQTT
C++
2
star
36

name.klep.flow-event-bus

Homey app to implement a flow event bus
JavaScript
2
star
37

css-tabs

Dirt-simple CSS tabs
2
star
38

NPMJSSearch

Makes searching search.npmjs.org from Chrome easier.
JavaScript
2
star
39

homey-log-to-file

Capture stdout/stderr of Homey app to a logfile
JavaScript
2
star
40

node-nzb-name-parser

NZB filename parser for Node
CoffeeScript
1
star
41

name.klep.homekit.presence

HomeKit occupancy accessory to provide presence status for Homey users
JavaScript
1
star
42

node-nzb-cleanup

Clean up NZB file names
JavaScript
1
star
43

blurizr

Make a Hip Blurry Background™ from any photo, directly in your browser!
1
star
44

package-bundler

Bundle a Node.js package into a single file.
JavaScript
1
star
45

FeedbackSlider

Sencha Touch 2 implementations of Ext.slider.Slider and Ext.field.Slider with textual feedback.
JavaScript
1
star
46

bas64r

Client side data-URL generator using HTML5 API's
1
star