I’ve updated my Markdown to Sendy script with the ability to use “sliced” images with separate links, the ability to upload assets to a CDN automatically, and a “test email” mode that will actually send a test email to you without going through Sendy.
If you haven’t heard of mdtosendy before, it’s a Ruby script that converts Markdown files into email-ready HTML with automatic inline styling for maximum email client compatibility. While it can generate emails for any newsletter or email platform, it integrates best with Sendy, automatically creating and scheduling campaigns. You write your emails in Markdown, maintain your styles in CSS files, and mdtosendy handles all the messy email HTML details. And it can handle multiple templates, so you can have different styles for the same newsletter, and/or configure multiple instances with different styles/settings.
The latest version adds some powerful new features that make it even more useful for email workflows.
Test Email Sending
The HTML preview mode is useful, but nothing beats being able to actually view the email in an email app so you can see exactly how it will render. Now you can send test emails directly without going through Sendy. The new --test-send option does exactly that:
mdtosendy --test-send your-email@example.com your-email.md
This sends a test email directly via SMTP, bypassing Sendy entirely. Perfect for quick previews or testing your email design before creating a campaign. You’ll need to configure SMTP settings in your config.yml:
smtp:
host: "smtp.gmail.com"
port: 587
domain: "gmail.com"
user: "me@example.com"
password: "your-app-password-here"
auth: "plain"
starttls: true
For Gmail, you’ll need to generate an App Password (not your regular password) at https://myaccount.google.com/apppasswords. Most other SMTP providers follow a similar pattern.
CDN Image Upload with Overwrite Control
The CDN image upload feature is a significant enhancement. You can add a cdn section to config (which can be inherited from the main config, or set per template), and when mdtosendy detects a local file path, it will be uploaded to the CDN and the url in the output HTML will be updated accordingly.
CDN uploads work with S3, SCP, or SFTP. See the example config in the repo for details.
You can configure how mdtosendy handles existing files on your CDN with the overwrite option:
cdn:
url: "https://cdn.example.com"
type: "s3"
username: "your-access-key-id"
password: "your-secret-access-key"
path: "your-bucket-name"
overwrite: ask # Options: true, false, or ask/prompt
By default, mdtosendy uses original filenames (no timestamps) and prompts you when a file already exists. The prompt defaults to “Yes”, so you can just press Enter or type y to overwrite, or n to skip. If you choose not to overwrite, a timestamp will be added to the filename to avoid conflicts.
The overwrite setting supports three modes:
true - Always overwrite without prompting
false - Never overwrite, automatically add timestamps when files exist
ask or prompt - Prompt for confirmation (default behavior)
This works with all three CDN types: S3, SCP, and SFTP. The file existence checking is smart enough to detect existing files before uploading.
Image Stack Tag
The new {% stack %} tag is perfect for creating multi-part images that need to be displayed as a seamless vertical stack. This is especially useful for sliced images or creating visual sections in your emails.
You can use it with markdown image syntax:
{% stack %}
[](https://example.com/link1)
[](https://example.com/link2)
[](https://example.com/link3)
{% endstack %}
Or with YAML for more structured definitions:
{% stack type="yaml" %}
images:
- path: /images/image1.png
url: https://example.com/link1
- path: /images/image2.png
url: https://example.com/link2
- path: /images/image3.png
{% endstack %}
The stack tag creates a vertical stack of images with zero spacing between them, all full width of the content area. Each image can optionally have a link. Local images in stacks are automatically uploaded to your CDN if you have it configured, and the tag uses a table-based layout for maximum email client compatibility.
Demo Please!
Here’s an email generated from the demo.md file in the repository,
using my own marked template, which uploads to my cdn.marked2app.com
bucket on S3. The demo shows a single image uploaded to the CDN from a
local file path, as well as 3 separate images combined into one stack,
with 3 separate links.
Demo email
Getting Started
If you’re new to mdtosendy, installation is a one-liner:
curl -s https://github.com/ttscoff/mdtosendy/raw/main/bootstrap.sh | bash
For more details on all the features, configuration options, and examples, check out the mdtosendy repository on GitHub.