Compare commits

...

206 Commits

Author SHA1 Message Date
dependabot[bot] fa285fc598
Bump copy-props from 2.0.4 to 2.0.5 (#103)
Bumps [copy-props](https://github.com/gulpjs/copy-props) from 2.0.4 to 2.0.5.
- [Release notes](https://github.com/gulpjs/copy-props/releases)
- [Changelog](https://github.com/gulpjs/copy-props/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/copy-props/compare/2.0.4...2.0.5)

---
updated-dependencies:
- dependency-name: copy-props
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-23 11:36:19 +01:00
dependabot[bot] 8fb1037afa
Bump is-my-json-valid from 2.15.0 to 2.20.6 (#104)
Bumps [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid) from 2.15.0 to 2.20.6.
- [Release notes](https://github.com/mafintosh/is-my-json-valid/releases)
- [Commits](https://github.com/mafintosh/is-my-json-valid/compare/v2.15.0...v2.20.6)

---
updated-dependencies:
- dependency-name: is-my-json-valid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-11 10:10:29 +01:00
dependabot[bot] 8b371bb49c
Bump trim-off-newlines from 1.0.1 to 1.0.3 (#102)
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-11 10:10:00 +01:00
dependabot[bot] e721efe2ca
Bump node-sass from 4.14.1 to 7.0.0 (#101)
Bumps [node-sass](https://github.com/sass/node-sass) from 4.14.1 to 7.0.0.
- [Release notes](https://github.com/sass/node-sass/releases)
- [Changelog](https://github.com/sass/node-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/node-sass/compare/v4.14.1...v7.0.0)

---
updated-dependencies:
- dependency-name: node-sass
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-10 08:39:21 +01:00
Dan Mindru 96e868bdf2 Bump version 2021-09-04 09:39:10 +02:00
Anuj Punjani d7baeec5ab
Added custom inline-image plugin & modified build.js (#100)
* Modified build.js to use custom inline-image plugin
* Added inlineRemoteUrl property for inline image processing

Co-authored-by: Dan Mindru <nadurdnim@icloud.com>
2021-09-04 09:36:47 +02:00
Dan Mindru 0c1ff6d3dc
Build on PR 2021-09-01 21:18:08 +02:00
dependabot[bot] 6bc6ab5c9d
Bump postcss from 7.0.2 to 7.0.36 (#96)
Bumps [postcss](https://github.com/postcss/postcss) from 7.0.2 to 7.0.36.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/7.0.2...7.0.36)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-16 14:39:12 +02:00
dependabot[bot] b9ef0953de
Bump normalize-url from 4.5.0 to 4.5.1 (#95)
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-10 12:51:54 +02:00
dependabot[bot] 5f68bf303a
Bump browserslist from 4.8.7 to 4.16.6 (#94)
Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.8.7 to 4.16.6.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/browserslist/browserslist/compare/4.8.7...4.16.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-25 16:31:55 +02:00
dependabot[bot] 5b2710d3c2
Bump lodash from 4.17.15 to 4.17.21 (#93)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-05-07 09:14:24 +02:00
dependabot[bot] deb81dd037
Bump y18n from 3.2.1 to 3.2.2 (#92)
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-03-30 13:12:37 +02:00
dependabot[bot] f57fd62ce9
Bump ini from 1.3.4 to 1.3.7 (#91)
Bumps [ini](https://github.com/isaacs/ini) from 1.3.4 to 1.3.7.
- [Release notes](https://github.com/isaacs/ini/releases)
- [Commits](https://github.com/isaacs/ini/compare/v1.3.4...v1.3.7)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-18 15:00:51 +01:00
Ben Mares 1c27a30ab4
Fix typo which prevents clearing cached config (#90)
Closes #84
2020-10-30 08:33:35 +01:00
Dan Mindru 83c3389945 Merge branch 'master' of github.com:fadeit/responsive-html-email-signature 2020-09-21 22:38:21 +02:00
Dan Mindru aeaadaae53 Bump version 2020-09-21 22:37:49 +02:00
Dan Mindru 51857f1129
Add support for node 12 (#88)
* Add support for node 12

* Remove deps task completely
2020-09-21 22:35:10 +02:00
Dan Mindru ba355c2c78
Rework npm commands to increase windows compat (#82)
* Rework npm commands to increase windows compat

* Test up to node 12
2020-06-10 11:33:50 +02:00
dependabot[bot] 6da4298b1f
Bump acorn from 7.1.0 to 7.1.1 (#78)
Bumps [acorn](https://github.com/acornjs/acorn) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/7.1.0...7.1.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-03-16 11:31:49 +01:00
Dan Mindru 054c18687e Add TODO 2020-02-23 23:04:52 +01:00
Dan Mindru 6955a0b796 Fix checks 2020-02-23 23:02:27 +01:00
Dan Mindru a0c8b69119 Remove windiws checks, won't fix 2020-02-23 23:02:27 +01:00
Dan Mindru c0c64b3449 Remove husky 2020-02-23 23:02:27 +01:00
Dan Mindru 12ea9b461c Add open collective post install to fix failing buil 2020-02-23 23:02:27 +01:00
Dan Mindru 468418fb17 Update husky 2020-02-23 23:02:27 +01:00
Dan Mindru 3f3e92fe29 Fix tests 2020-02-23 23:02:27 +01:00
Dan Mindru 12facfd8c2 Add prettier config 2020-02-23 23:02:27 +01:00
Dan Mindru 6113d1b575 Move css link tag generation to util 2020-02-23 23:02:27 +01:00
Dan Mindru 9610d244dd Finish unused config (barely) 2020-02-23 23:02:27 +01:00
Dan Mindru f298f8bd85 Refactor for tests 2020-02-23 23:02:27 +01:00
Dan Mindru b3e0c77988 Add empty tests 2020-02-23 23:02:27 +01:00
Dan Mindru 1ad1ef9106 Update pre-push to run e2e test 2020-02-23 23:02:27 +01:00
Dan Mindru d55786f744 Check for unused initial (untested) implementation 2020-02-23 23:02:27 +01:00
Dan Mindru e599bef72e Remove unused package 2020-02-23 23:02:27 +01:00
Dan Mindru 8ba0323aaa Fix readme text 2020-02-23 23:02:27 +01:00
Dan Mindru 86944f3cee Fix tests 2020-02-23 23:02:27 +01:00
Dan Mindru e44a52c89f Re-format tests 2020-02-23 23:02:27 +01:00
Dan Mindru 8bcabaa10f Increase version (to not forget) 2020-02-23 23:02:27 +01:00
Dan Mindru d45a069c89 Sketch look for unused task 2020-02-23 23:02:27 +01:00
Dan Mindru ab54d1e3e6 Update prettier conf 2020-02-23 23:02:27 +01:00
Dan Mindru a04d8a225a Remove todos from html templates 2020-02-23 23:02:27 +01:00
Dan Mindru 7cd7e53300 Refactor build to split up reading and gettings configs into utils 2020-02-23 23:02:27 +01:00
Dan Mindru 6ab7b8d962 Format all source files 2020-02-23 23:02:27 +01:00
Dan Mindru d950d1d265 Add constants file 2020-02-23 23:02:27 +01:00
Dan Mindru 4adabe4ecd Rollback husky 2020-02-23 22:28:18 +01:00
Dan Mindru 77953b721a Nuke package lock 2020-02-23 22:22:51 +01:00
Dan Mindru f68b5104ce Drop v9 2020-02-23 22:17:52 +01:00
Dan Mindru 3c22a3921c Last chance for windows 2020-02-23 22:13:08 +01:00
Dan Mindru fedff3d67c Include node v13 2020-02-23 22:11:09 +01:00
Dan Mindru abecdb6371 Remove windows from tests 2020-02-23 22:09:06 +01:00
Dan Mindru 31f824b664 Tweaks scripts 2020-02-23 22:08:24 +01:00
Dan Mindru 6f05af60ad Update node-sass 2020-02-23 21:59:11 +01:00
Dan Mindru 0150856d77 Try to install on win using unsafe perm 2020-02-23 21:55:15 +01:00
Dan Mindru 1c6ff143b1 Test on node 9-12 2020-02-23 21:50:02 +01:00
Dan Mindru 5fcbf1ca19 Downgrade node-sass 2020-02-23 21:47:10 +01:00
Dan Mindru 6ecb318ca6 Fix action node version 2020-02-23 21:41:03 +01:00
Dan Mindru 455999b910 Test on LTS node only 2020-02-23 21:37:33 +01:00
Dan Mindru 4618b491d7 Rollback gulp-rename 2020-02-23 21:32:50 +01:00
Dan Mindru d1d656d375 Roll back ava to prevent broken tests on windows 2020-02-23 21:25:37 +01:00
Dan Mindru be239820d1 Include cli as dep 2020-02-23 21:19:03 +01:00
Dan Mindru 46011d12ea Update dark test fixutre 2020-02-23 21:18:44 +01:00
Dan Mindru 0edb498614 Include semis 2020-02-23 21:18:34 +01:00
Dan Mindru 51702a2c0f Include node 13 in test matrix 2020-02-23 21:11:02 +01:00
Dan Mindru 2a43f4309d Remove newline eof 2020-02-23 21:09:56 +01:00
Dan Mindru 9e1780eb08 Update dependencies 2020-02-23 21:03:37 +01:00
Dan Mindru 8ecbee58c0
Add cname (#75) 2019-09-08 21:50:04 +02:00
Dan Mindru 54ba657926
Setup eslint, prettier & husky (#72) 2019-09-03 21:20:18 +02:00
Dan Mindru 9c2e12104c
Set linguist-vendored to true 2019-09-03 13:33:23 +02:00
Dan Mindru 0b869c8359 Merge branch 'master' of github.com:danmindru/responsive-html-email-signature 2019-09-03 12:48:25 +02:00
Dan Mindru 3f6dc14c78 Fix typo 2019-09-03 12:48:11 +02:00
Dan Mindru c177e1f24f
Fix other node-version to node_version typo 2019-09-03 11:47:54 +02:00
Dan Mindru 265f955af5 Merge branch 'master' of github.com:danmindru/responsive-html-email-signature 2019-09-03 11:37:05 +02:00
Dan Mindru 5bac55caac Don't use spread to increase backwards compat 2019-09-03 11:36:49 +02:00
Dan Mindru 1dece49925
Fix typo: node-version to node_version 2019-09-03 11:23:41 +02:00
Dan Mindru 1d00da17ff
Add action badge 2019-09-03 11:21:23 +02:00
Dan Mindru 356ddd41cb Merge branch 'master' of github.com:danmindru/responsive-html-email-signature 2019-09-03 11:16:06 +02:00
Dan Mindru f8687ca6d9 Update documentation 2019-09-03 11:13:33 +02:00
Dan Mindru 80160e8135
Use node number syntax as opposed to x.x 2019-09-03 11:00:55 +02:00
Dan Mindru b316aa6caa
Run tests on windows, mac & ubuntu 2019-09-03 10:49:22 +02:00
Dan Mindru 558ccc2a9e
Rename test action 2019-09-03 10:46:53 +02:00
Dan Mindru 2970388579 Bump version 2019-09-03 10:44:06 +02:00
Dan Mindru 53226eec93 Update readme 2019-09-03 10:43:42 +02:00
Dan Mindru 06f7ac73fe Resolve paths in test 2019-09-03 10:43:33 +02:00
Dan Mindru ead960958b Create a gulp task to run pipeline once 2019-09-03 10:43:11 +02:00
Dan Mindru 41f6dced8f Refactor build to use native promises 2019-09-03 10:42:46 +02:00
Dan Mindru d8baffdca4
Set linguist-vendored to false 2019-09-02 17:05:31 +02:00
Dan Mindru d9d966c1f7
Add wildcard to vendored paths 2019-09-02 17:02:22 +02:00
Dan Mindru dd9f8ef381
Add sample data as vendor code 2019-09-02 17:01:36 +02:00
Dan Mindru ad525373b7
Create test workflow for github actions 2019-08-31 17:42:55 +02:00
Dan Mindru 284d97efa5 Bump version 2019-08-31 17:30:04 +02:00
Dan Mindru bbd274c7f7 Update packages 2019-08-31 17:29:39 +02:00
Dan Mindru 238daab855 refactor gulpfile to work with gulp v4 2019-08-31 16:55:15 +02:00
Dan Mindru 29354f0920 Update postcss task 2019-08-31 16:55:01 +02:00
Dan Mindru 268cbed282 Update lint task 2019-08-31 16:54:51 +02:00
Dan Mindru 3c47d1f4bc Update sass task 2019-08-31 16:54:40 +02:00
Dan Mindru bfb19dec08 Update less task 2019-08-31 16:54:26 +02:00
Dan Mindru 5e10fab4c7 Update dupe task 2019-08-31 16:54:12 +02:00
Dan Mindru 4c10c45222 Update check deps task 2019-08-31 16:54:02 +02:00
Dan Mindru 6c30066e4d Update build task 2019-08-31 16:53:34 +02:00
Dan Mindru 2f56f93d79 Delete watch task 2019-08-31 16:53:26 +02:00
Dan Mindru fad368ecb2 Update to gulp 4 2019-08-31 16:53:12 +02:00
Dan Mindru b969802d87 Bump node version 2019-08-31 16:53:01 +02:00
Dan Mindru 1f24c76467 Add some basic tests 2019-08-31 16:52:41 +02:00
dependabot[bot] 06badf0964 Bump mixin-deep from 1.3.1 to 1.3.2 (#64)
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-29 13:37:51 +02:00
dependabot[bot] e42f190e40 Bump lodash.mergewith from 4.6.1 to 4.6.2 (#63)
Bumps [lodash.mergewith](https://github.com/lodash/lodash) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2019-07-11 11:47:07 +02:00
dependabot[bot] 07e8fb7952 Bump lodash.merge from 4.6.1 to 4.6.2 (#62)
Bumps [lodash.merge](https://github.com/lodash/lodash) from 4.6.1 to 4.6.2.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2019-07-11 11:45:54 +02:00
dependabot[bot] 1bd69ddb88 Bump tar from 2.2.1 to 2.2.2 (#59)
Bumps [tar](https://github.com/npm/node-tar) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Commits](https://github.com/npm/node-tar/compare/v2.2.1...v2.2.2)
2019-06-06 00:54:49 +03:00
dependabot[bot] f2e268bd9c Bump fstream from 1.0.10 to 1.0.12 (#60)
Bumps [fstream](https://github.com/npm/fstream) from 1.0.10 to 1.0.12.
- [Release notes](https://github.com/npm/fstream/releases)
- [Commits](https://github.com/npm/fstream/compare/v1.0.10...v1.0.12)
2019-06-06 00:54:25 +03:00
dependabot[bot] d6300db1e6 Bump js-yaml from 3.12.0 to 3.13.1 (#61)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.0 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.0...3.13.1)
2019-06-06 00:54:01 +03:00
Dan Mindru a5f0b3e83f
Bugfix/build failing on node10 (#58)
* Update dependencies
* Add note about create command and fix outdated docs
2019-04-24 22:03:21 +02:00
Dan Mindru d567e67d7e
Update documentation with some notes on email clients (#54) 2018-11-16 22:16:07 +01:00
Dan Mindru ecaf31b42d
Merge pull request #51 from danmindru/develop
Install newer lodash
2018-11-03 18:36:10 +01:00
Dan Mindru dbf0951627 Install newer lodash 2018-11-03 18:34:11 +01:00
Dan Mindru af88ce036c
Merge pull request #49 from gstevenson/patch-1
Fix a couple of README typos
2018-09-25 11:07:57 +02:00
Greg Stevenson 3699600c47
Fix a couple of README typos 2018-09-24 20:27:31 +01:00
Dan Mindru 823a7be173 Update deps 2018-09-03 22:12:00 +02:00
Dan Mindru bae078590a Update docs 2018-09-03 21:56:50 +02:00
Dan Mindru 207737f437 Bump version 2017-11-24 15:07:03 +01:00
Dan Mindru 23ae549b64 Remove console log 2017-11-24 15:06:18 +01:00
Dan Mindru bcb013e39d Swap html image inline plugin 2017-11-23 10:52:38 +01:00
Dan Mindru f2aa0c2366 Update example config to match v4 #35 2017-10-06 11:27:02 +02:00
Dan Mindru f921b882a0 Merge pull request #34 from seanlane/patch-1
Fix minor typo
2017-09-19 12:23:20 +02:00
Sean Lane 95460a4e0c Fix minor typo
Just saw a minor error. Thanks for making this, looks great!
2017-09-18 17:32:59 -06:00
Dan Mindru 160263f899 Fix /pulls URL 2017-07-14 15:15:27 +02:00
Dan Mindru 201737e166 Update deps, bump version 2017-07-14 15:04:48 +02:00
Dan Mindru e9dbb5b37e Add badges, closes #14 2017-07-14 15:04:29 +02:00
Dan Mindru a6c2561d1e Split some main gulpfile calls for better readability 2017-07-14 14:11:31 +02:00
Dan Mindru 9f22e6d4f4 Fix some typos in README 2017-07-14 14:08:02 +02:00
Sander Sink fe82f7ab16 HTTPS clone instead of ssh 2017-07-12 13:40:15 +03:00
Sander Sink fa45c63ce8 Made readme a bit readable 2017-07-12 13:38:32 +03:00
Dan Mindru e479d03613 Note on node version, bump npm version 2017-05-18 12:28:48 +02:00
Dan Mindru 108747ee1d Fix footer underline 2017-05-17 14:57:20 +02:00
Dan Mindru aba228edbe Merge pull request #31 from bryant1410/master
Fix broken headings in Markdown files
2017-04-18 11:35:09 +02:00
Santiago Castro cf2f38358f Fix broken Markdown headings 2017-04-16 17:01:25 -03:00
Dan Mindru 1fe90ee748 Fix README credits 2017-03-23 20:07:16 +01:00
Dan Mindru 9dcf115781 Fix i18n readme markdown 2017-03-14 22:22:20 +01:00
Dan Mindru a33140224b Merge pull request #29 from nenebale/master
File extension in watchTask now matches conf.json
2017-03-11 15:20:11 +01:00
Lionel Voser 2bd5f576ee File extension in watchTask matches conf.json 2017-03-09 16:59:50 +01:00
Dan Mindru 9b2d698c33 Fix some readme typos 2017-03-06 15:08:32 +01:00
Dan Mindru 27af00d9fe Bump version 2017-02-08 18:19:28 +01:00
Dan Mindru 12bffe8169 #26 Use path.win32.basename to resolve stylesheet paths and be consistent on WIN & UNIX 2017-02-08 16:26:05 +01:00
Dan Mindru 5b907d3bf9 Fix syntax highlighting in README 2017-02-08 00:45:07 +01:00
Dan Mindru 03ab7366de Update demo 2017-02-08 00:41:10 +01:00
Dan Mindru 59804bd735 Update deploy command 2017-02-07 23:50:46 +01:00
Dan Mindru cfbfd696f1 Docs 2017-02-07 23:45:19 +01:00
Dan Mindru 16f00eb247 Upgrade node 2017-02-07 23:45:12 +01:00
Dan Mindru 090b3f03ed Remove examples 2017-02-07 23:45:02 +01:00
Dan Mindru 3348ad9dc1 Rename src ➡️ templates 2017-02-07 23:44:47 +01:00
Dan Mindru cbb3743613 Setup demo 2017-02-07 23:44:25 +01:00
Dan Mindru 18606cff77 Improve build 2017-02-07 23:44:17 +01:00
Dan Mindru f4d1bc65db Merge master into 100 2017-01-03 11:57:50 +02:00
Dan Mindru b3528c9aff Merge branch 'master' of github.com:fadeit/responsive-html-email-signature 2017-01-03 11:56:56 +02:00
Dan Mindru 64371a56af Add .nvmrc with node ~v4 2017-01-03 11:56:37 +02:00
Dan Mindru 514ad88dad Update ISSUE_TEMPLATE.md 2016-11-11 17:53:24 +01:00
Dan Mindru c9a6096d10 Create ISSUE_TEMPLATE.md 2016-10-25 21:14:27 +02:00
Dan Mindru e5cd2fd649 Allow single conf objects too 2016-08-19 22:47:53 +02:00
Dan Mindru 1bdbed78c9 #18 convert conf files to JSON & lint 2016-08-19 21:04:02 +02:00
Dan Mindru 6816ef605f #12 Update docs 2016-08-19 19:46:15 +02:00
Dan Mindru c2bad1843c #12 Get rid of wrench in favor of fs & fs-extra 2016-08-19 19:42:23 +02:00
Dan Mindru 05c40b8083 Doc checklist changes 2016-08-19 19:39:02 +02:00
Dan Mindru 4317d545f4 #12 Move translation to own dir 2016-08-19 18:32:33 +02:00
Dan Mindru 0efa1f986b #9 Ignore dist & real people confs 2016-08-19 18:20:10 +02:00
Dan Mindru 8ddeded1e1 HTTP => HTTPS 2016-06-22 21:46:14 +02:00
Dan Mindru 5563ba89f6 📜 WIP doc with release todos 2016-05-25 22:49:06 +02:00
Dan Mindru e88d40536c Bump version 2016-05-25 22:40:10 +02:00
Dan Mindru 55b41e2a54 Use options.src instead of gulp.src for proper plumbing 2016-05-25 22:37:41 +02:00
Dan Mindru 68643a7b93 🖌 SCSS ready to go, closes #11 2016-05-25 22:30:33 +02:00
Dan Mindru 4186ff05c8 LESS support 2016-05-25 20:45:08 +02:00
Dan Mindru 88f945925f 🕶 automagically include styles in <head> #11 #12 2016-05-25 20:33:28 +02:00
Dan Mindru 8b921e98e9 Simplify postcss task #12, #11 2016-05-25 19:19:55 +02:00
Dan Mindru 293ed731ae 😋 Rework build & add postcss #12, #11 2016-05-24 22:03:03 +02:00
Dan Mindru b3aa899ffa ✏️ Sketch out css preprocessing 2016-05-19 15:29:06 +02:00
Dan Mindru b7ee4747f5 ⬇️ Decrease margin of mobile hr 2016-05-19 14:35:38 +02:00
Dan Mindru 26e4f61a73 Wrap address to prevent iOS / OS X from making it a beautiful blue 🔵 2016-05-19 14:21:37 +02:00
Dan Mindru 1618ed1dce Nicer responsive full mail (only light theme) 2016-05-19 14:17:51 +02:00
Dan Mindru 3e1016ac45 Remove dark hr style 2016-05-19 14:15:10 +02:00
Dan Mindru 0111aebe8a 🐞 Fix Tutanota footer spacing #16 #fixed 2016-05-19 14:00:51 +02:00
Dan Mindru c8e7624c39 🐞 Fix header(s) markup 2016-05-19 02:20:24 +02:00
Dan Mindru 276b9b30f6 📜 Docs ref to inline-css mappings 2016-05-18 12:56:53 +02:00
Dan Mindru 955240ae80 Update CSS & HTML to newer inline-css (more table attrs. are automatically inlined now), dark theme #4 2016-05-15 15:29:06 +02:00
Dan Mindru 331746d1ea Update CSS & HTML to newer inline-css (more table attrs. are automatically inlined now), light theme #4 2016-05-15 14:50:27 +02:00
Dan Mindru 9bd227283f 📜 Structure docs for both light & dark #12 2016-05-12 21:25:40 +02:00
Dan Mindru c09a5a82d3 More generic dark & light themes #12 2016-05-12 21:25:21 +02:00
Dan Mindru 27d060fd5f Made /examples dir, switched to generic templates in /src #12 2016-05-12 19:46:27 +02:00
Dan Mindru a1d9820db3 📜 Docs: default template structure and overview 2016-05-12 19:38:47 +02:00
Dan Mindru 930276d0be Bump deps 2016-05-12 19:07:07 +02:00
Dan Mindru 57b3e9524b Use gulp-david to check deps 2016-05-12 19:02:27 +02:00
Dan Mindru d1ccb12079 📜 Docs for gulp tasks #12 2016-05-12 19:01:07 +02:00
Dan Mindru 5379298baf 📜 Update docs 2016-05-12 18:24:32 +02:00
Dan Mindru 13626765a1 Add license file. MIT FTW 💃 2016-05-11 11:04:34 +02:00
Dan Mindru ab9f68c7f1 Update todo 🛠 2016-04-19 14:33:27 +02:00
Dan Mindru 641d29eb9e Strict mode in gulpfile 2016-04-19 14:31:08 +02:00
Dan Mindru fd579f6448 Readme update (add link to Korean) 📚 2016-04-19 14:28:24 +02:00
Dan Mindru 32bb8cb843 Add Outlook instructions & Korean readme [#8 from dusskapark/master
Master
2016-04-19 14:23:43 +02:00
Jude Park 39c84d57bf Added Korean character issues 2016-04-17 23:23:57 +09:00
Jude Park ab4f78b4da #7 Added README files
Added new usage case for Outlook 2010 for windows 7 users
2016-04-17 23:17:39 +09:00
Jude Park 0e8d28f46f update README files 2016-04-17 19:12:20 +09:00
Jude Park 235ea51fc4 ONE스토어 명함 규격 업데이트 2016-04-14 13:56:11 +09:00
Jude Park 5ffb911328 ONE스토어 템플릿 추가 2016-04-13 18:30:16 +09:00
Jude Park 3b353daa10 ONEstore 메일 템플릿 추가 2016-04-12 12:33:04 +09:00
Dan Mindru 9d7c9c8521 Update TODO 🐰 2016-03-30 12:28:32 +02:00
Dan Mindru 0ee89a861e README dust-up 📃 2016-03-30 12:27:33 +02:00
Dan Mindru 4847c91079 Bump dep versions 2016-01-08 14:23:16 +01:00
Dan Mindru 4fbc4757ef Add overview section 2015-10-21 01:32:30 +02:00
Dan Mindru 6621681238 Updated Mac instructions (lock file) 2015-10-20 21:58:59 +02:00
Dan Mindru 4b0638a245 Updated Apple Mail command 2015-10-20 15:53:36 +02:00
97 changed files with 31465 additions and 177 deletions

18
.eslintrc.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
env: {
browser: true,
commonjs: true,
es6: true
},
extends: ['standard', 'prettier'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly'
},
parserOptions: {
ecmaVersion: 2018
},
rules: {
semi: 0
}
};

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
demo/* linguist-vendored
tests/sample/* linguist-vendored

29
.github/workflows/nodejs.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: Test template output
on: [push, pull_request]
jobs:
test:
name: Test on node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
node_version: [10, 11, 12, 13, 14]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node_version }}
- name: npm install & test
run: |
npm -v
node -v
npm install
npm run test
env:
CI: true

6
.gitignore vendored
View File

@ -1,5 +1,7 @@
/vendor/
/node_modules/
/build/
/application/
/tmp/
.DS_Store
/dist
IDEAS.md
npm_debug.log

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
v12

5
.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"semi": true,
"singleQuote": true,
"printWidth": 120
}

1
CNAME Normal file
View File

@ -0,0 +1 @@
responsive-html-email-signature-generator.com

7
ISSUE_TEMPLATE.md Normal file
View File

@ -0,0 +1,7 @@
Hi there, please provide some info about your enviornment before submiting this issue:
- device :
- OS :
- email client :
- node version :
- npm version :
- error message :

8
LICENSE Normal file
View File

@ -0,0 +1,8 @@
The MIT License (MIT)
Copyright © 2016 fadeit ApS
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.

282
README.md
View File

@ -1,86 +1,284 @@
# Responsive HTML mail signatures
Responsive templates for mail signatures. <br/>
# Responsive HTML email signature(s)
When you need some basic signatures that work on mobile.<br/>
[![npm](https://img.shields.io/npm/v/responsive-html-email-signature.svg)](https://www.npmjs.com/package/responsive-html-email-signature)
[![license](https://img.shields.io/github/license/danmindru/responsive-html-email-signature.svg)](/LICENSE)
[![test action status](https://github.com/danmindru/responsive-html-email-signature/workflows/Test%20template%20output/badge.svg)](https://github.com/danmindru/responsive-html-email-signature/actions)
### Let's punch email clients in the stomach 👊
When you need some basic responsive email signatures that work on mobile.<br/>
...and your colleagues need them too.<br/>
...but you don't want to deal with tables and inline styles.
[Read the docs in other languages](/i18n) ↗️
## Preview
Here's how the samples look:
Here are some examples:
![responsive emails-01](https://cloud.githubusercontent.com/assets/1515742/10591900/13889d32-76b9-11e5-8dc0-b89d80189e93.png)
![responsive emails-02](https://cloud.githubusercontent.com/assets/1515742/10591901/139c4954-76b9-11e5-80f7-5b0ccaf5af81.png)
## What does it do
- [x] config-based template generation
- [x] allows generating multiple templates (for your colleagues too!)
- [x] transforms linked (`<link>`) CSS into inline styles
- [x] embeds local `img[src]` into the template (base64).*
- [x] minifies the template
- [x] media queries for mail clients that support them
- [x] can build templates from multiple sources
- [x] watches HTML/CSS files for changes and re-builds
<small>** *Some mail clients don't support them, so an external URL might be a good idea. **</small>
## Getting started
```
- Clone repo `git clone https://github.com/danmindru/responsive-html-email-signature.git`
- Run `npm install`
- Run `npm start` to generate templates from configuration. This will continue to watch your files and re-make the template until you exit.
### Customizing templates
- Edit files in _/templates_
- Open files from `./dist` in your fav browser to check them out
> When you're done, check out [how to add them to your email client of choice](#usage-with-different-email-clients) if in doubt.
## Motivation
Writing HTML emails & email signatures sucks. Let's make it easier. We can't fix all email clients, but we can surely make our lives easier with some automation. <br/>
## What does this pile of code do
- [x] generates email templates from your config
- [x] allows generating multiple templates at once (for your colleagues too!)
- [x] transforms linked (`<link>`) CSS into inline styles
- [x] embeds local `img[src]` into the template (base64).\*
- [x] minifies the template
- [x] ads some basic media queries for mail clients that support them
- [x] can build templates from multiple sources
- [x] watches HTML / CSS files for changes and re-builds
- [x] supports LESS / SASS / PostCSS
- [x] autoprefixer, so you don't have to worry about your `-moz-`s or `-webkit-`s
- [x] linting, checks for used template config parameters and more!
\*_Some mail clients might have [hard limits](https://support.google.com/a/answer/176652?hl=en) regarding the email size, so don't include large images if possible. If you need to, use a URL instead and host the image somewhere else._
## Docs
### Installing
```bash
$ npm install
$ gulp
$ npm start # By default, templates will be created in `./dist` and HTML & CSS files in './templates' will be watched for changes.
```
Take a look at `src/fadeit/` for an example. Copy / Paste, rename it and change `src/fadeit/conf.js` to suite your needs. Run `gulp` to build the templates (into `/dist`). The gulp task will watch HTML & CSS files by default.
> Note: works well with node v10+. Earlier and later versions might also work.
### Configuring
To make a basic email from existing templates, you only have to edit the `conf.json` file in each template.
For example, the dark template accepts the following:
```json
{
"id": "<will-be-used-for-filename>",
"signature": "<signature-of-choice>",
"name": "<your-name>",
"contactMain": "<phone-or-email-or-html>",
"contactMail": "<email>",
"slogan": "<a-basic-slogan>",
"logoUrl": "</assets/dark.png?>",
"logoAlt": "<text-in-case-logo-is-blocked>",
"website": "<http://dark.dk>"
}
```
### Generating multiple emails from the same config (for your colleagues too!)
To generate multiple templates, use an array instead of an object in `conf.json`, like so:
```json
[{ ...conf1 }, { ...conf2 }]
```
### Using config values in HTML
Config variables are made available in all HTML files. <br/>
Add any variable to the configuration file and use it in HTML like so:
```html
<p><!-- @echo yourCustomVariable --></p>
```
Where the configuration contains:
```json
{
"yourCustomVariable": "Custom!"
}
```
> NB: config variables also accept HTML. That's useful for including links.
### Adding CSS & pre-processing
Any number of CSS, SASS or LESS files in a template directory & they will be automatically processed & inlined into the files outputed in `./dist`.
### Multiple emails in the same template
Templates can contain multiple HTML files from which to build emails. For example, the dark template has `signature.html` and `signature-reply.html`, which is a simpler version.
Each HTML file will be treated as an email template, except for `*.inc.html`. See below ⬇️
### Using partials (\*.inc.html)
By naming files with `*.inc.html`, they become partials. Partials will not be treated as templates (ignored), but they can be included in any HTML template using the `@include` HTML comment.
```html
<section>
<!-- @include footer.inc.html -->
</section
```
Partials are useful if you have bits of HTML that repeat, like headers, footers, etc.
### Advanced templating
Inside HTML files, any [preprocess directive](https://github.com/jsoverson/preprocess#all-directives) is supported, such as `@if`, `@extend`, `@exec`, etc.
## Template structure (examples)
There are no rules regarding how to structure templates, but it's a good idea to create directories for a template group. <br/>
There are 2 examples of template structures, one for the `light` email template and one for the `dark` one.
Here's how the dark one is structured:
```bash
./templates
├── dark
├── assets
├── dark.png # Image to embed as base64
├── conf.json # Template strings, logo, etc.
├── dark.css # Stylesheet.
├── footer.inc.html # Contact info & logo
├── head.inc.html # 'Responsive' CSS goes here
├── signature.html # Full signature (loads head/footer)
├── signature-reply.html # Simplified signature (loads head)
```
Here's how the light one is structured:
```bash
./templates
├── light
├── assets
├── light.png # Image to embed as base64
├── conf.json # Template strings, logo, etc.
├── footer.inc.html # Contact info & logo
├── full-mail.html # Body + signature
├── head.inc.html # 'Responsive' CSS goes here
├── light.css # Stylesheet.
├── signature.html # Full signature (loads head/footer)
├── signature-reply.html # Simplified signature (loads head)
```
There's one convention you have to keep in mind: `all files that you wish to include should follow the *.inc.html format`. The gulp task ignores `*.inc.html` files, but will try to process & create email templates from all `.html` files.
You are of course encouraged to change the default structure for your use case.
## Overview of the build process
The diagram below shows what happens to your email templates.
Each folder in 'templates' is considered a `template group`. A template file will be generated for each of the configuration objects you add have in the template group -> `conf.js`.
![Responsive HTML email template/signatures diagram](https://user-images.githubusercontent.com/1515742/45000195-35268300-afc3-11e8-82b4-7507430c48a0.png)
## CSS Support
Remember, it's HTML mails, so you need to check a big-ass table to find out nothing's gonna work.
See [this](https://www.campaignmonitor.com/css/). To convert CSS files to inline styles [gulp-inline-css](https://www.npmjs.com/package/gulp-inline-css) is being used.
See [this](https://www.campaignmonitor.com/css/) for more info. [Gulp-inline-css](https://www.npmjs.com/package/gulp-inline-css) is being used to convert whatever CSS you throw at it to inline styles, but it probably won't handle everything.
Some bonuses of using `gulp-inline-css`: many css props will be converted to attributes. For example, the 'background-color' prop will be added as 'bgcolor' attribute to table elements.
For more details take a look at the [inline-css mappings](https://github.com/jonkemp/inline-css/blob/master/lib/setTableAttrs.js).
## TODO
- [ ] closing `inline-css` issue [#8](https://github.com/jonkemp/inline-css/issues/8#issuecomment-149025428) would greatly improve this repo
- [ ] preprocessor support (simplifies BEM)
- [ ] use github pages to show live demos
- [ ] fix all mail clients
## Usage with different e-mail clients
## Usage with different email clients
### Thunderbird
There are several Thunderbird plugins which can automatically insert signatures when composing e-mails. We recommend [SmartTemplate4](https://addons.mozilla.org/en-us/thunderbird/addon/smarttemplate4) as one of the options. It can use different templates for new e-mails, replies and forwarded e-mails.
### Gmail
Go to your mailbox settings & paste the generated signature.
> **NB**: Gmail doesn't seem to support inlined (base64) images. You have to use absolute `http(s)//...`.
### Office 365 / outlook.live.com
It's a bit hacky to set up, but possible. See [this issue](https://github.com/danmindru/responsive-html-email-signature/issues/52).
### Apple Mail / OS X (oh boy)
#### Solution 1
- Open Mail.app and go to `Mail` -> `Preferences` -> `Signatures`
- Create a new signature and write some placeholder text (doesn't matter what it is, but you have to identify it later).
- Close Mail.app.
- Open terminal, then open the signature files using TextEdit (might be different for iCloud drive check the article below).
```
$ open -a TextEdit ~/Library/Mobile\ Documents/com~apple~mail/Data/V3/MailData/Signatures/ubiquitous_-mailsignature`
$ open -a TextEdit ~/Library/Mobile\ Documents/com~apple~mail/Data/V3/MailData/Signatures/ubiquitous_*.mailsignature
```
- Keep the file with the placeholder open, close the other ones.
- Replace the `<body>...</body>` and it's contents with the template of your choice. *Don't remove the meta information at the top!*
- Replace the `<body>...</body>` and it's contents with the template of your choice. _Don't remove the meta information at the top!_
- Open Mail.app and compose a new mail. Select the signature from the list to test it out.
**NB**: Images won't appear in the signature preview, but will work fine when you compose a message.
> **NB**: Images won't appear in the signature preview, but will work fine when you compose a message.
#### Solution 2
You can also open the HTML files in `/dist` in a browser, CMD + A, CMD + C and then paste into the signature box. This won't copy the `<html>` part or the `<style>` part that includes media queries. Follow the guide if you want it.
#### Troubleshooting
If you are using iCloud drive or having problems with it, you might also want to check [http://matt.coneybeare.me/how-to-make-an-html-signature-in-apple-mail-for-el-capitan-os-x-10-dot-11/](this article).
If solution #1 doesn't work, you can repeat the steps and lock the signature files before you open Mail.app again.
Lock Files:
```
$ chflags uchg ~/Library/Mail/V3/MailData/Signatures/*.mailsignature
```
===================
<br/>
<a href="http:fadeit.dk"><img src="http://fadeit.dk/src/assets/img/brand/fadeit_logo_full.svg" alt="The fadeit logo" style="width:200px;"/></a><br/><br/>
If you want to do changes later, you have to unlock the files:
####About fadeit
We love and are really good at designing &amp; developing beautiful software, web and mobile applications.
```
$ chflags nouchg ~/Library/Mail/V3/MailData/Signatures/*.mailsignature
```
See more at [fadeit.dk](http://fadeit.dk)
If you are using iCloud drive or having problems with it, you might also want to check [this article](http://matt.coneybeare.me/how-to-make-an-html-signature-in-apple-mail-for-el-capitan-os-x-10-dot-11/).
### Outlook 2010 Client for Windows 7
#### Solution 1
- Open Outlook 2010 and go to `File > Option > Mail > Signature`
- Create new signature (with a placeholder for your convenience)
- Open signature folder using CMD
> As the AppData folder is hidden, I'd recommend you to open it via CMD.
```
cd AppData\Roaming\Microsoft
start Signatures
```
- Within this folder, find a file named with your placeholder then right click this file and select edit.
- Replace it with your HTML and save
- Open Outlook again and check your signature
#### Solution 2
Unfortnately, Outlook 2010 client dosen't support HTML file import features for your email template. But you can add your own signatures by simple Copy and paste like **Solution 2** above.
- Open built html file on `/dist` folder and Ctrl A + C
- Open Outlook 2010 and go to `File > Option > Mail > Signature`
- Create new signature and paste copyed one
> **NB**: base 64 will not be shown on Outlook 2010 client. So, I recommend to use external url if you want to use images.
## Other commands
### `npm run test`
Runs tests once.
### `npm run once`
Creates templates and exits; does not watch files.

6
constants.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
SOURCE_DIR: 'templates',
DIST_DIR: 'dist',
WORKING_DIR: 'tmp',
CONFIGURATION_FILE: 'conf.json'
}

1
demo/dist/dark/signature-dark.html vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><style type="text/css">@media only screen and (max-width:560px){.footer__main__col1,.footer__main__col2{width:100%!important}.footer td{font-size:12px!important}.footer__main__col1__td{text-align:left}.footer__main__col1__td>span{margin-bottom:10px}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style></head><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffff" width="100%"><tr class="sp" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="sp__inner" style="padding: 15px 0;"></td></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer footer--simple" style="border-top: 8px solid #585858; color: #f5f5f5; padding: 20px 30px 0px 30px; padding-bottom: 20px;" bgcolor="#FFFFFF"><table class="rbcc footer__main" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0" width="100%"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Best regards,<br>The dark mail team<br></td></tr></table></td></tr></table></body></html>

1
demo/dist/light/full-mail-light.html vendored Normal file

File diff suppressed because one or more lines are too long

1
demo/dist/light/signature-light.html vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><style type="text/css">@media only screen and (max-width:480px){.footer td{font-size:12px!important}.footer__main__col1,.footer__main__col2{width:100%!important}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}.gray-hr hr{margin-bottom:10px!important;margin-top:10px!important}}@media only screen and (min-width:1025px){.background,.body-with-bg{background-color:#F1F1F1}.body-with-bg .main{border:1px solid #E9E9E9!important;max-width:960px;margin:0 auto}.background{padding:30px}}</style></head><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" style="border: 0; cellpadding: 0; cellspacing: 0; padding-top: 15px;" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffff" width="100%"><tr class="sp" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="sp__inner" style="padding: 15px 0;"></td></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer footer--simple" style="border-top: 8px solid #EAEAEA; color: #888; padding: 20px 30px 0px 30px; padding-bottom: 20px;" bgcolor="#FFFFFF"><table class="rbcc footer__main" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0" width="100%"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Yours truly,<br>The light mail team<br></td></tr></table></td></tr></table></body></html>

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,14 @@
{
"id": "ONEstore",
"name": "0 0 0 매니저",
"team": "스토어 기획팀",
"title": "Dev Relations",
"welcome": "안녕하세요.",
"introParagraph": "Thanks for writing up this email.<br/> We are delighted to reply with a responsive template.",
"contactMain": "<a href='tel:+821012345678'><span>+82-10-1234-5678</span></a> | ",
"contactMail": "devhelper@onestore.co.kr",
"contactSecondary": "성남시 분당구 판교역로 188 SK플래닛 건물 11층",
"logoUrl": "assets/type01.png",
"logoAlt": "Onestore logo",
"website": "http://onesto.re/"
}

View File

@ -0,0 +1,38 @@
<td class="footer" bgcolor="#f5f5f5">
<!-- @todo gulp-inline-css can't use width in percentages -->
<table class="rbcc footer__main" width="100%">
<tr>
<!-- @todo gulp-inline-css doesn't parse align -->
<td class="footer__main__signature" align="left">
<!-- @echo team --> | <!-- @echo title --><br />
<!-- @echo name --><br />
</td>
</tr>
<tr>
<td width="100%">
<hr class="gray-hr"/></td>
</tr>
<tr>
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse align -->
<table class="rbcc footer__main__col1" width="70%" align="left">
<td class="footer__main__col1__td" align="left">
<strong>
<!-- @echo contactMain -->
<a href="mailto:<!-- @echo contactMail -->" target="_blank"><!-- @echo contactMail --></a>
</strong><br />
<!-- @echo contactSecondary -->
</td>
</table>
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse align -->
<table class="rbcc footer__main__col2" width="30%" align="right">
<!-- @todo gulp-inline-css doesn't parse align -->
<td class="footer__main__col2__td" align="right">
<a href="<!-- @echo website -->">
<img src="<!-- @echo logoUrl -->" alt="<!-- @echo logoAlt -->" class="footer__main__col2__td__img"/><br />
</a>
</td>
</table>
</tr>
</table>
</td>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,15 @@
{
"id": "ONEstoreBlack",
"signature": "Best regards,",
"name": "Joo Hyung Park",
"team": "Service Planning Team",
"title": "Dev Relations",
"welcome": "안녕하세요.",
"introParagraph": "Thanks for writing up this email.<br/> We are delighted to reply with a responsive template.",
"contactMain": "Call <a href='tel:+821012345678'><span>+82-10-1234-5678</span></a> or email us at",
"contactMail": "devhelper@onestore.co.kr",
"contactSecondary": "188, Pangyoyeok-ro, Bundang-gu, Seongnam-si, Gyeonggi-do, Korea",
"logoUrl": "assets/type03.png",
"logoAlt": "ONEstore. logo",
"website": "http://onesto.re/"
}

View File

@ -0,0 +1,37 @@
<td class="footer" bgcolor="#303030">
<!-- @todo gulp-inline-css can't use width in percentages -->
<table class="rbcc footer__main" width="100%">
<tr>
<!-- @todo gulp-inline-css doesn't parse align -->
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<strong><!-- @echo name --></strong><br />
<strong><!-- @echo team --></strong> | <!-- @echo title -->
</td>
</tr>
<!-- @todo gulp-inline-css doesn't add height attrs -->
<tr class="spd" height="60px"></tr>
<tr>
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse align -->
<table class="rbcc footer__main__col2" width="30%" align="right">
<!-- @todo gulp-inline-css doesn't parse align -->
<td class="footer__main__col2__td" align="right">
<a href="<!-- @echo website -->">
<img src="<!-- @echo logoUrl -->" alt="<!-- @echo logoAlt -->" class="footer__main__col2__td__img"/>
</a>
</td>
</table>
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse align -->
<table class="rbcc footer__main__col1" width="70%" align="left">
<td class="footer__main__col1__td" align="left">
<!-- @echo contactMain -->
<a href="mailto:<!-- @echo contactMail -->" target="_blank"><!-- @echo contactMail --></a><br/>
address: <a href="http://map.naver.com/?dlevel=11&pinType=site&pinId=35263909&x=127.1100213&y=37.3975215&enc=b64"> <!-- @echo contactSecondary --></a>
</td>
</table>
</tr>
</table>
</td>

View File

@ -0,0 +1,25 @@
<!-- @include head.inc.html -->
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse background-color -> bgcolor -->
<body>
<table class="main rbcc" width="100%" bgcolor="#ffffff";>
<tr class="rbcc">
<td class="main__welcome">
<b><!-- @echo welcome --></b>
</td>
</tr>
<tr class="rbcc">
<td class="main__content">
<!-- @echo introParagraph -->
</td>
</tr>
<!-- @todo gulp-inline-css doesn't add height attrs -->
<tr class="sp" height="30px"></tr>
<tr class="rbcc">
<!-- @todo gulp-inline-css doesn't parse background-color -> bgcolor -->
<!-- @include footer.inc.html -->
</tr>
</table>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,13 @@
{
"id": "fadeit",
"signature": "Yours truly,",
"name": "Jane Whatsmyname",
"welcome": "Hi there,",
"introParagraph": "Thanks for writing up this email.<br/> We are delighted to reply with a responsive template.",
"contactMain": "Call <a href='tel:81100200'><span>81100200</span></a> or email us at",
"contactMail": "info@fadeit.dk",
"contactSecondary": "Anelystparken 31, DK-8381 Tilst, Aarhus",
"logoUrl": "http://fadeit.dk/src/assets/img/brand/fadeit-logo.png",
"logoAlt": "fadeit logo",
"website": "http://fadeit.dk"
}

View File

@ -0,0 +1,160 @@
/* Solving https://github.com/jonkemp/inline-css/issues/8 would make things nicer. */
/*
* =====================================
* 1. Common styles for general table things.
* =====================================
*/
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
tr{
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
box-sizing: border-box;
font-size: 14px;
line-height: 20px;
}
.main{
/* @todo gulp-inline-css can't use width in percentages */
/* This style property fucks up the width on OS X, needs to be *JUST* attribute ->
width:100%; */
/* @todo gulp-inline-css doesn't parse background-color -> bgcolor */
background-color: #ffffff;
}
.rbcc{
/*
* rbcc -> reset - border - cellspacing - cellpading
*
* Resets table attributes.
*/
border:0;
cellpadding:0;
cellspacing:0;
}
.sp{
/* Separator tr */
/* @todo gulp-inline-css doesn't add height attrs */
height: 30px;
}
.gray-hr{
border-bottom:1px solid #E4E4E4;
border-top:none;
margin-bottom:20px;
margin-top:20px;
}
a{
text-decoration: none;
color: #0fade1;
}
/*
* =================
* 2. Content styles.
* ==================
*/
.main__welcome{
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 22px;
}
.main__content{
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
}
/*
* ================
* 3. Footer styles.
* ================
*/
.footer{
/* @todo gulp-inline-css doesn't parse background-color -> bgcolor */
background-color: #f5f5f5;
padding: 20px 30px 0px 30px;
color: #888;
border-top: 8px solid #EAEAEA;
}
.footer a{
color: #888;
}
.footer--simple{
padding-bottom: 20px;
/* @todo gulp-inline-css doesn't parse background-color -> bgcolor */
background-color: #FFFFFF;
}
.footer__main{
/* @todo gulp-inline-css can't use width in percentages */
/* This style property fucks up the width on OS X, needs to be *JUST* attribute ->
width:100%; */
}
.footer__main__signature{
font-size: 14px;
color: #888;
/* @todo gulp-inline-css doesn't parse align */
align:left;
}
.footer__main__col1{
/* @todo gulp-inline-css can't use width in percentages */
width:70%;
margin-bottom:30px;
/* @todo gulp-inline-css doesn't parse align */
align:left;
}
.footer__main__col1__td{
font-size: 14px;
color: #888;
/* @todo gulp-inline-css doesn't parse align */
align:left;
}
.footer__main a > span{
/* Revert apple blue-link style. */
color: #888!important;
text-decoration:none!important;
}
.footer__main__col2{
/* @todo gulp-inline-css can't use width in percentages */
width:30%;
/* @todo gulp-inline-css doesn't parse align */
align:right;
}
.footer__main__col2__td{
font-size: 14px;
color: #888;
/* @todo gulp-inline-css doesn't parse align */
align:right;
}
.footer__main__col2__td__img{
border: 0;
padding-top: 6px;
padding-left:10px;
max-width: 100%;
max-height:38px;
height: auto;
}

View File

@ -0,0 +1,25 @@
<!-- @include head.inc.html -->
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse background-color -> bgcolor -->
<body>
<table class="main rbcc" width="100%" bgcolor="#ffffff";>
<tr class="rbcc">
<td class="main__welcome">
<b><!-- @echo welcome --></b>
</td>
</tr>
<tr class="rbcc">
<td class="main__content">
<!-- @echo introParagraph -->
</td>
</tr>
<!-- @todo gulp-inline-css doesn't add height attrs -->
<tr class="sp" height="30px"></tr>
<tr class="rbcc">
<!-- @todo gulp-inline-css doesn't parse background-color -> bgcolor -->
<!-- @include footer.inc.html -->
</tr>
</table>
</body>

View File

@ -0,0 +1,34 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Solving https://github.com/jonkemp/inline-css/issues/8 would make things nicer. -->
<link rel="stylesheet" href="fadeit.css">
</head>
<style type="text/css">
/* Responsive stuff goes here (inline css doesn't know what to do with it). */
@media only screen and (max-width:480px){
.footer td{
font-size: 12px!important;
}
.footer__main__col1{
width: 100%!important;
}
.footer__main__col2{
width: 100%!important;
}
.footer__main__col2__td{
text-align: left;
padding-bottom:20px;
}
.footer__main__col2__td__img{
padding-left:0!important;
}
}
</style>

View File

@ -0,0 +1,23 @@
<!-- @include head.inc.html -->
<body>
<br/>
<table class="main rbcc" width="100%" bgcolor="#ffffff";>
<tr class="sp" height="30px"></tr>
<tr class="rbcc">
<!-- @todo gulp-inline-css doesn't parse background-color -> bgcolor -->
<td class="footer footer--simple" bgcolor="#ffffff">
<table class="rbcc footer__main" width="100%">
<tr>
<!-- @todo gulp-inline-css doesn't parse align -->
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<!-- @echo name --><br />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>

View File

@ -0,0 +1,14 @@
<!-- @include head.inc.html -->
<body>
<br/> <!-- <br/> Makes it easier to add text when composing -->
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse background-color -> bgcolor -->
<table class="main rbcc" width="100%" bgcolor="#ffffff";>
<tr class="sp" height="30px"></tr>
<tr class="rbcc">
<!-- @todo gulp-inline-css doesn't parse background-color -> bgcolor -->
<!-- @include footer.inc.html -->
</tr>
</table>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,11 @@
{
"id": "play",
"signature": "Best regards,",
"name": "Jane Whatsmyname",
"contactMain": "Call <a href='tel:004581100200'><span>(45) 81100200</span></a> or email us at",
"contactMail": "info@tryplay.dk",
"slogan": "LED Pylon. LED Wall. Digital Signage.",
"logoUrl": "https://informationscreen.com/manage/assets/images/play-logo.png",
"logoAlt": "Play. logo",
"website": "http://tryplay.dk"
}

View File

@ -0,0 +1,42 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Solving https://github.com/jonkemp/inline-css/issues/8 would make things nicer. -->
<link rel="stylesheet" href="play.css">
</head>
<style type="text/css">
/* Responsive stuff goes here (inline css doesn't know what to do with it). */
@media only screen and (max-width:560px){
.footer td{
font-size: 12px!important;
}
.footer__main__col1{
width: 100%!important;
}
.footer__main__col1__td{
text-align: left;
}
.footer__main__col1__td > span{
margin-bottom:10px;
}
.footer__main__col2{
width: 100%!important;
}
.footer__main__col2__td{
text-align: left;
padding-bottom:20px;
}
.footer__main__col2__td__img{
padding-left:0!important;
}
}
</style>

174
demo/examples/play/play.css Normal file
View File

@ -0,0 +1,174 @@
/* Solving https://github.com/jonkemp/inline-css/issues/8 would make things nicer. */
/*
* =====================================
* 1. Common styles for general table things.
* =====================================
*/
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
tr{
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
box-sizing: border-box;
font-size: 14px;
line-height: 22px;
}
.main{
/* @todo gulp-inline-css can't use width in percentages */
/* This style property fucks up the width on OS X, needs to be *JUST* attribute ->
width:100%; */
/* @todo gulp-inline-css doesn't parse background-color -> bgcolor */
background-color: #ffffff;
}
.rbcc{
/*
* rbcc -> reset - border - cellspacing - cellpading
*
* Resets table attributes.
*/
border:0;
cellpadding:0;
cellspacing:0;
}
.sp{
/* sp -> space, Separator tr */
/* @todo gulp-inline-css doesn't add height attrs */
height: 30px;
}
.spd{
/* spd -> space - double, Separator tr */
/* @todo gulp-inline-css doesn't add height attrs */
height: 60px;
}
.gray-hr{
border-bottom:1px solid #E4E4E4;
border-top:none;
margin-bottom:20px;
margin-top:20px;
}
a{
text-decoration: none;
color: #0fade1;
}
/*
* =================
* 2. Content styles.
* ==================
*/
.main__welcome{
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 22px;
}
.main__content{
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
}
/*
* ================
* 3. Footer styles.
* ================
*/
.footer{
/* @todo gulp-inline-css doesn't parse background-color -> bgcolor */
background-color: #303030;
padding: 20px 30px 0px 30px;
color: #f5f5f5;
border-top: 8px solid #585858;
}
.footer a{
color: #f5f5f5;
}
.footer--simple{
padding-bottom: 20px;
/* @todo gulp-inline-css doesn't parse background-color -> bgcolor */
background-color: #FFFFFF;
}
.footer--simple tr td{
color: #888;
}
.footer__main{
/* @todo gulp-inline-css can't use width in percentages */
/* This style property fucks up the width on OS X, needs to be *JUST* attribute ->
width:100%; */
}
.footer__main__signature{
font-size: 14px;
color: #f5f5f5;
/* @todo gulp-inline-css doesn't parse align */
align:left;
}
.footer__main__col1{
/* @todo gulp-inline-css can't use width in percentages */
width:70%;
margin-bottom:40px;
/* @todo gulp-inline-css doesn't parse align */
align:left;
}
.footer__main__col1__td{
color: #9E9E9E;
/* @todo gulp-inline-css doesn't parse align */
align:left;
padding-top: 15px;
}
.footer__main__col1__td > span{
font-size:18px;
margin-bottom:5px;
}
.footer__main a > span{
/* Revert apple blue-link style. */
color: #f5f5f5!important;
text-decoration:none!important;
}
.footer__main__col2{
/* @todo gulp-inline-css can't use width in percentages */
width:30%;
/* @todo gulp-inline-css doesn't parse align */
align:right;
}
.footer__main__col2__td{
font-size: 14px;
color: #f5f5f5;
/* @todo gulp-inline-css doesn't parse align */
align:right;
}
.footer__main__col2__td__img{
border: 0;
padding-left:20px;
max-width: 100%;
max-height:65px;
height: auto;
}

View File

@ -0,0 +1,23 @@
<!-- @include head.inc.html -->
<body>
<br/>
<table class="main rbcc" width="100%" bgcolor="#ffffff";>
<tr class="sp" height="30px"></tr>
<tr class="rbcc">
<!-- @todo gulp-inline-css doesn't parse background-color -> bgcolor -->
<td class="footer footer--simple" bgcolor="#ffffff">
<table class="rbcc footer__main" width="100%">
<tr>
<!-- @todo gulp-inline-css doesn't parse align -->
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<!-- @echo name --><br />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>

View File

@ -0,0 +1,14 @@
<!-- @include head.inc.html -->
<body>
<br/> <!-- <br/> Makes it easier to add text when composing -->
<!-- @todo gulp-inline-css can't use width in percentages, doesn't parse background-color -> bgcolor -->
<table class="main rbcc" width="100%" bgcolor="#ffffff";>
<tr class="sp" height="30px"></tr>
<tr class="rbcc">
<!-- @todo gulp-inline-css doesn't parse background-color -> bgcolor -->
<!-- @include footer.inc.html -->
</tr>
</table>
</body>

223
demo/index.html vendored Normal file
View File

@ -0,0 +1,223 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Responsive HTML emails & emails signature</title>
<meta name="description" content="Automate the creation of HTML emails and email signatures. Generate multiple emails for your colleagues, friends or enemies too!">
<style>
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
box-sizing: border-box;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
body {
font-size: 12px;
background-color: rgb(21, 21, 21);
}
body, h1, h2, h3, h4, h5, h6, p {
font-family: -apple-system, BlinkMacSystemFont, Arial, sans-serif;
font-weight: 300;
color: white;
margin: 0;
}
p {
line-height: 1.3em;
}
h1 { font-size: 3em; }
h2 { font-size: 2.2em; }
h3 { font-size: 1.8em; margin-bottom: 0.3em; }
img {
max-width: 100%;
}
.dark { min-height: 430px; }
.light { min-height: 350px; }
iframe {
border: 0;
}
header {
min-height: 100vh;
padding: 5em;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
header h1 {
max-width: 600px;
}
header a {
opacity: 0.7;
font-size: 1.2em;
color: white;
text-decoration: none;
font-weight: 300;
border: 1px solid white;
border-radius: 4px;
max-width: 280px;
margin-top: 2em;
padding: 1em 2em;
text-align: center;
display: inline-block;
line-height: 1.2em;
transition: opacity 0.3s;
}
header a:hover,
header a:focus {
opacity: 1;
transition: opacity 0.3s;
}
figure {
margin-top: -60px;
display: flex;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
figure svg { height: 60px; width: 40px; }
footer {
padding: 5em;
}
footer a {
opacity: 0.7;
font-size: 1em;
color: white;
text-decoration: none;
font-weight: 300;
border: 1px solid white;
border-radius: 4px;
max-width: 280px;
margin-top: 2em;
padding: 0.6em 1em;
text-align: center;
display: inline-block;
line-height: 1.2em;
transition: opacity 0.3s;
}
footer a:hover,
footer a:focus {
opacity: 1;
transition: opacity 0.3s;
}
@media only screen and (min-width: 767px) {
header {
font-size: 16px;
}
}
</style>
</head>
<body>
<header>
<h1>HTML emails & email signatures should be easier than this.</h1>
<a href="https://github.com/fadeit/responsive-html-email-signature">Get started on Github</a>
</header>
<figure>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path fill="white" d="M349.7,322.2c-3.1-3.1-8-3-11.3,0L264,388.6V104c0-4.4-3.6-8-8-8c-4.4,0-8,3.6-8,8v284.6l-74.4-66.3
c-3.4-2.9-8.1-3.2-11.2-0.1c-3.1,3.1-3.3,8.5-0.1,11.4c0,0,87,79.2,88,80s2.8,2.4,5.7,2.4s4.9-1.6,5.7-2.4s88-80,88-80
c1.5-1.5,2.3-3.6,2.3-5.7C352,325.8,351.2,323.8,349.7,322.2z"/>
</svg>
</figure>
<main>
<img src="https://cloud.githubusercontent.com/assets/1515742/10591901/139c4954-76b9-11e5-80f7-5b0ccaf5af81.png" alt="Email / email signature HTML template dark">
<img src="https://cloud.githubusercontent.com/assets/1515742/10591900/13889d32-76b9-11e5-8dc0-b89d80189e93.png" alt="Email / email signature HTML template white">
</main>
<footer>
<h3>HTML emails, please.</h3>
<p>
Grab the code on Github to simplify how HTML emails are built.
</p>
<a href="https://github.com/fadeit/responsive-html-email-signature">Get started on Github</a>
</footer>
<!-- can do demos later! -->
<!-- <iframe class="dark" src="./dist/dark/signature-dark.html"></iframe>
<iframe class="light" src="./dist/light/signature-light.html"></iframe> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/webfont/1.6.27/webfontloader.js"></script>
<script>
WebFontLoader.load({
active () {
const body = document.querySelector('body')
if (body) body.style.fontFamily = 'Roboto, -apple-system, BlinkMacSystemFont, Arial, sans-serif'
}
google: {
families: ['Roboto:300,400']
}
})
</script>
</body>
</html>

View File

@ -1 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><style type="text/css">@media only screen and (max-width:480px){.footer td{font-size:12px!important}.footer__main__col1,.footer__main__col2{width:100%!important}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><table class="main rbcc" width="100%" bgcolor="#ffffff" ;="" style="background-color: #ffffff; border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="main__welcome" style="color: #000; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; line-height: 22px; padding: 10px 30px 0 30px;"><b>Hi there,</b></td></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="main__content" style="color: #000; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; padding: 10px 30px 0 30px;">Thanks for writing up this email.<br>We are delighted to reply with a responsive template.</td></tr><tr class="sp" height="30px" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; height: 30px; line-height: 20px;"></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer" bgcolor="#f5f5f5" style="background-color: #f5f5f5; border-top: 8px solid #EAEAEA; color: #888; padding: 20px 30px 0px 30px;"><table class="rbcc footer__main" width="100%" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Yours truly,<br>Jane Whatsmyname<br></td></tr><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td width="100%"><hr class="gray-hr" style="border-bottom: 1px solid #E4E4E4; border-top: none; margin-bottom: 20px; margin-top: 20px;"></td></tr><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><table class="rbcc footer__main__col1" width="70%" align="left" style="align: left; border: 0; cellpadding: 0; cellspacing: 0; margin-bottom: 30px; width: 70%;" border="0" cellpadding="0" cellspacing="0"><td class="footer__main__col1__td" align="left" style="align: left; color: #888; font-size: 14px;"><strong>Call <a href="tel:81100200" style="color: #888; text-decoration: none;"><span style="color: #888; text-decoration: none;">81100200</span></a> or email us at <a href="mailto:info@fadeit.dk" target="_blank" style="color: #888; text-decoration: none;">info@fadeit.dk</a></strong><br>Anelystparken 31, DK-8381 Tilst, Aarhus</td></table><table class="rbcc footer__main__col2" width="30%" align="right" style="align: right; border: 0; cellpadding: 0; cellspacing: 0; width: 30%;" border="0" cellpadding="0" cellspacing="0"><td class="footer__main__col2__td" align="right" style="align: right; color: #888; font-size: 14px;"><a href="http://fadeit.dk" style="color: #888; text-decoration: none;"><img src="http://fadeit.dk/src/assets/img/brand/fadeit-logo.png" alt="fadeit logo" class="footer__main__col2__td__img" style="border: 0; height: auto; max-height: 38px; max-width: 100%; padding-left: 10px; padding-top: 6px;"></a></td></table></tr></table></td></tr></table></body></html>

View File

@ -1 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><style type="text/css">@media only screen and (max-width:480px){.footer td{font-size:12px!important}.footer__main__col1,.footer__main__col2{width:100%!important}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" width="100%" bgcolor="#ffffff" ;="" style="background-color: #ffffff; border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr class="sp" height="30px" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; height: 30px; line-height: 20px;"></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer" bgcolor="#f5f5f5" style="background-color: #f5f5f5; border-top: 8px solid #EAEAEA; color: #888; padding: 20px 30px 0px 30px;"><table class="rbcc footer__main" width="100%" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Yours truly,<br>Jane Whatsmyname<br></td></tr><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td width="100%"><hr class="gray-hr" style="border-bottom: 1px solid #E4E4E4; border-top: none; margin-bottom: 20px; margin-top: 20px;"></td></tr><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><table class="rbcc footer__main__col1" width="70%" align="left" style="align: left; border: 0; cellpadding: 0; cellspacing: 0; margin-bottom: 30px; width: 70%;" border="0" cellpadding="0" cellspacing="0"><td class="footer__main__col1__td" align="left" style="align: left; color: #888; font-size: 14px;"><strong>Call <a href="tel:81100200" style="color: #888; text-decoration: none;"><span style="color: #888; text-decoration: none;">81100200</span></a> or email us at <a href="mailto:info@fadeit.dk" target="_blank" style="color: #888; text-decoration: none;">info@fadeit.dk</a></strong><br>Anelystparken 31, DK-8381 Tilst, Aarhus</td></table><table class="rbcc footer__main__col2" width="30%" align="right" style="align: right; border: 0; cellpadding: 0; cellspacing: 0; width: 30%;" border="0" cellpadding="0" cellspacing="0"><td class="footer__main__col2__td" align="right" style="align: right; color: #888; font-size: 14px;"><a href="http://fadeit.dk" style="color: #888; text-decoration: none;"><img src="http://fadeit.dk/src/assets/img/brand/fadeit-logo.png" alt="fadeit logo" class="footer__main__col2__td__img" style="border: 0; height: auto; max-height: 38px; max-width: 100%; padding-left: 10px; padding-top: 6px;"></a></td></table></tr></table></td></tr></table></body></html>

View File

@ -1 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><style type="text/css">@media only screen and (max-width:480px){.footer td{font-size:12px!important}.footer__main__col1,.footer__main__col2{width:100%!important}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" width="100%" bgcolor="#ffffff" ;="" style="background-color: #ffffff; border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr class="sp" height="30px" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; height: 30px; line-height: 20px;"></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer footer--simple" bgcolor="#ffffff" style="background-color: #FFFFFF; border-top: 8px solid #EAEAEA; color: #888; padding: 20px 30px 0px 30px; padding-bottom: 20px;"><table class="rbcc footer__main" width="100%" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Yours truly,<br>Jane Whatsmyname<br></td></tr></table></td></tr></table></body></html>

View File

@ -1 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><style type="text/css">@media only screen and (max-width:560px){.footer__main__col1,.footer__main__col2{width:100%!important}.footer td{font-size:12px!important}.footer__main__col1__td{text-align:left}.footer__main__col1__td>span{margin-bottom:10px}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" width="100%" bgcolor="#ffffff" ;="" style="background-color: #ffffff; border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr class="sp" height="30px" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; height: 30px; line-height: 22px;"></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer" bgcolor="#303030" style="background-color: #303030; border-top: 8px solid #585858; color: #f5f5f5; padding: 20px 30px 0px 30px;"><table class="rbcc footer__main" width="100%" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer__main__signature" align="left" style="align: left; color: #f5f5f5; font-size: 14px;">Best regards,<br><strong>Jane Whatsmyname</strong><br></td></tr><tr class="spd" height="60px" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; height: 60px; line-height: 22px;"></tr><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><table class="rbcc footer__main__col2" width="30%" align="right" style="align: right; border: 0; cellpadding: 0; cellspacing: 0; width: 30%;" border="0" cellpadding="0" cellspacing="0"><td class="footer__main__col2__td" align="right" style="align: right; color: #f5f5f5; font-size: 14px;"><a href="http://tryplay.dk" style="color: #f5f5f5; text-decoration: none;"><img src="https://informationscreen.com/manage/assets/images/play-logo.png" alt="Play. logo" class="footer__main__col2__td__img" style="border: 0; height: auto; max-height: 65px; max-width: 100%; padding-left: 20px;"></a></td></table><table class="rbcc footer__main__col1" width="70%" align="left" style="align: left; border: 0; cellpadding: 0; cellspacing: 0; margin-bottom: 40px; width: 70%;" border="0" cellpadding="0" cellspacing="0"><td class="footer__main__col1__td" align="left" style="align: left; color: #9E9E9E; padding-top: 15px;"><span style="font-size: 18px; margin-bottom: 5px;">LED Pylon. LED Wall. Digital Signage.</span><br>Call <a href="tel:004581100200" style="color: #f5f5f5; text-decoration: none;"><span style="color: #f5f5f5; text-decoration: none;">(45) 81100200</span></a> or email us at <a href="mailto:info@tryplay.dk" target="_blank" style="color: #f5f5f5; text-decoration: none;">info@tryplay.dk</a></td></table></tr></table></td></tr></table></body></html>

View File

@ -1 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><style type="text/css">@media only screen and (max-width:560px){.footer__main__col1,.footer__main__col2{width:100%!important}.footer td{font-size:12px!important}.footer__main__col1__td{text-align:left}.footer__main__col1__td>span{margin-bottom:10px}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" width="100%" bgcolor="#ffffff" ;="" style="background-color: #ffffff; border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr class="sp" height="30px" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; height: 30px; line-height: 22px;"></tr><tr class="rbcc" style="border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer footer--simple" bgcolor="#ffffff" style="background-color: #FFFFFF; border-top: 8px solid #585858; color: #f5f5f5; padding: 20px 30px 0px 30px; padding-bottom: 20px;"><table class="rbcc footer__main" width="100%" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0"><tr style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Best regards,<br>Jane Whatsmyname<br></td></tr></table></td></tr></table></body></html>

View File

@ -1,17 +1,50 @@
'use strict';
const gulp = require('gulp');
const plumber = require('gulp-plumber');
var gulp = require('gulp'),
wrench = require('wrench');
const { SOURCE_DIR, DIST_DIR, WORKING_DIR, CONFIGURATION_FILE } = require('./constants');
var options = {
src: 'src',
dist: 'dist'
const options = {
sourceDir: SOURCE_DIR,
distDir: DIST_DIR,
workingDir: WORKING_DIR,
configurationFile: CONFIGURATION_FILE,
src: function plumbedSrc() {
return gulp.src.apply(gulp, arguments).pipe(plumber());
}
};
wrench.readdirSyncRecursive('./tasks').filter(function(file) {
return (/\.(js|coffee)$/i).test(file);
}).map(function(file) {
require('./tasks/' + file)(options);
});
/**
* Load tasks from the '/tasks' directory.
*/
require('./tasks/build')(options);
require('./tasks/dupe')(options);
require('./tasks/less')(options);
require('./tasks/lint')(options);
require('./tasks/postcss')(options);
require('./tasks/sass')(options);
require('./tasks/check-for-unused').checkForUnusedTask(options);
gulp.task('default', ['build', 'watch']);
/* Runs the entire pipeline once. */
gulp.task(
'run-pipeline',
gulp.series('dupe', 'less', 'sass', 'postcss', 'lint', 'build', gulp.parallel('check-for-unused'))
);
/* By default templates will be built into '/dist'. */
gulp.task(
'default',
gulp.series('run-pipeline', () => {
/* gulp will watch for changes in '/templates'. */
gulp.watch(
[
options.sourceDir + '/**/*.html',
options.sourceDir + '/**/*.css',
options.sourceDir + '/**/*.scss',
options.sourceDir + '/**/*.less',
options.sourceDir + '/**/conf.json'
],
{ delay: 500 },
gulp.series('run-pipeline')
);
})
);

19
i18n/README.md Normal file
View File

@ -0,0 +1,19 @@
# Translated docs
The [main README](https://github.com/fadeit/responsive-html-email-signature) is always going to be the most up-to-date, so if something doesn't add up, take a look there.
*Available translations are:*
- [Korean](ko-KR.md) by [JooHyung Park](https://github.com/dusskapark)
<!-- SOON! - [Romanian](ro-RO.md) by [Dan Mindru](https://github.com/danmindru) -->
## Contributing
You're very welcome to contribute & maintain translations.
Mini-guide:
1. Fork the repo
2. Create a translation file and name it (i18n standard format, e.g. en-US)
3. Put this file in the i18n folder
4. Translate the original English version to be current with the latest changes
5. Add a new line to this file with a link to your translation
6. Make a Pull Request

130
i18n/ko-KR.md Normal file
View File

@ -0,0 +1,130 @@
# 반응형 HTML 메일 서명
### 이메일 클라이언트를 씹어먹자(?!)
이메일 서명 전용 반응형 템플릿<br/>
> 모바일에서 잘 동작하는 기본 서명이 필요하신가요? <br/>
> ... 그리고 직장동료들도 필요한가요? <br/>
> ... 근데 지저분하게 테이블이랑 인라인 CSS를 만들기 싫은가요? <br/>
## Preview
본 템플릿의 기본 동작방식은 아래와 같습니다:
![responsive emails-01](https://cloud.githubusercontent.com/assets/1515742/10591900/13889d32-76b9-11e5-8dc0-b89d80189e93.png)
![responsive emails-02](https://cloud.githubusercontent.com/assets/1515742/10591901/139c4954-76b9-11e5-80f7-5b0ccaf5af81.png)
## 만들게된 동기 (Motivation)
이메일용 html은 일반적인 HTML과 달리 모든 코드를 in-line CSS로 만들어야 합니다. 그래서 이메일 템플릿이랑 서명을 만들기가 굉장히 어렵습니다. "이런 HTML 템플릿과 서명을 편하게 만들어보자!" 라는 생각에서 이 템플릿을 만들었습니다. 물론 모든 이메일 클라이언트의 이슈를 전부 다 고칠 수는 없지만, 이 템플릿을 활용해서 조금 더 쉽고 깔끔한 반응형 이메일을 만들어서 받는 사람 보내는 사람 모두가 만족하게 만들 수 있습니다!
## 이 템플릿에서 무엇을 할 수 있나? (What does it do?)
- [x] config-based template generation
- [x] allows generating multiple templates (for your colleagues too!)
- [x] transforms linked (`<link>`) CSS into inline styles
- [x] embeds local `img[src]` into the template (base64).*
- [x] minifies the template
- [x] media queries for mail clients that support them
- [x] can build templates from multiple sources
- [x] watches HTML/CSS files for changes and re-builds
> *일부 이메일 클라이언트는 base64 기반의 이미지 표시 기능을 지원하지 않습니다. 외부 링크를 사용하는 것이 더 좋은 선택일 것 같아요.
## 시작하기 (Getting started)
```
$ npm install
$ gulp
```
`src/dark/` 를 확인해보시면 멋진 2개의 이메일 템플릿 샘플이 있습니다. 폴더를 통째로 다른 이름으로 복사/붙여넣기 하시고 그 안에 있는 `src/dark/conf.js` 파일을 입맛대로 바꿔보세요. 다음으로는 `gulp`를 실행해서 여러분 만의 이메일 템플릿을 빌드하세요. gulp 의 task가 동작하면서 기본 html CSS 파일을 확인하고 새로운 html 파일을 `/dist`에 저장합니다.
## 살펴보기 (Overview)
아래 순서도는 여러분이 만든 템플릿이 어떻게 빌드가 되는지를 보여줍니다.
![Responsive HTML email template/signatures diagram](http://fadeit.dk/posts/html-emails-and-email-signatures-how-hard-can-it-be/html-responsive-email-template-build-diagram.png)
## CSS 서포트 (CSS Support)
기억해둘 것은... 이것은 이메일용 HTML 을 만드는 것입니다. 그러니깐 이 프로젝트로 이메일을 빌드하는 여러분은 요즘은 잘 쓰지도 않는 멍청한 테이블 코드 덩어리를 확인하고 그 속에서 어떤 CSS가 동작하는지 안하는지를 알아봐야 할지도 모릅니다.(일단 이 [포스트](https://www.campaignmonitor.com/css/)를 참고하세요.) 아무튼 이런 과정을 통해서 여러분이 어떤 CSS 파일을 만들면, [gulp-inline-css](https://www.npmjs.com/package/gulp-inline-css) 모듈을 통해서 인라인 CSS로 바뀌어서 여러분의 HTML 파일로 빌드됩니다.
## 앞으로 할 일 (TODO):
- [ ] closing `inline-css` issue [#8](https://github.com/jonkemp/inline-css/issues/8#issuecomment-149025428) would greatly improve this repo
- [ ] preprocessor support (simplifies BEM)
- [ ] use github pages to show live demos
- [ ] check [gulp-inline-css](https://github.com/jonkemp/inline-css) for new features
## 다른 이메일 클라이언트에서 사용하는 법 (Usage with different e-mail clients)
### Thunderbird
썬더버드 이메일 클라이언트에 html 서명을 자동으로 넣어주는 몇몇 플러그인이 있스빈다. 일단 우리는 [SmartTemplate4](https://addons.mozilla.org/en-us/thunderbird/addon/smarttemplate4) 를 추천합니다. 이 플러그인을 쓰면 새 이메일, 답장, 전달 등을 할 때마다 각각 다른 이메일 템플릿을 쓸 수 있습니다.
### Apple Mail / OS X (꼭.. 써야 한다면?)
#### 방법 1
- 이메일 앱을 열고 `Mail` -> `Preferences` -> `Signatures` 로 이동하세요.
- 아무거나 새 이메일 서명을 만들세요. (나중에 찾기 편하게 placeholder 를 써두는 것이 좋습니다.)
- 이메일을 닫으세요.
- 터미널을 열고 TextEdit으로 서명 파일을 열어보세요. (iCloud drive를 사용하는 경우는 잘 작동하지 않는 경우가 있습니다. 아래 troubleshooting을 참고하세요. )
```
$ open -a TextEdit ~/Library/Mobile\ Documents/com~apple~mail/Data/V3/MailData/Signatures/ubiquitous_*.mailsignature
```
- 위에서 placeholder를 넣어둔 파일을 열어봅니다.
- `<body>...</body>` 의 모든 html 코드를 여러분이 빌드한 `/dist/`의 html 파일로 교체 합니다. (`<body>`외에 다른 메타 정보는 수정하지 마세요!)
- 메일앱을 다시 실행하고 새로 바뀐 서명을 확인해보세요 :)
> **주의**: 이미지 파일은 원래 `preference`의 미리보기 화면에서는 나오지 않습니다. 하지만 이메일을 만들고 발송하는 곳에서는 잘 보여지니깐 걱정마세요!
#### 방법 2
다른 방법으로는 `/dist` 에 빌드한 html 파일을 CMD + A, CMD + C 해서 설정에 이메일 서명 박스에 붙여넣기 해서 쓸 수도 있습니다. 하지만 이렇게 복붙을 하는 경우 파일의 `<html>` 이나 반응형 웹을 위한 미디어쿼리가 들어있는 `<style>` 부분을 복붙하는 것이 아니라 정상적으로 작동하지 않을 수 있습니다.
#### Troubleshooting
만약 위의 방법 1이 정상적으로 작동하지 않는다면 파일을 수정 후 메일 앱을 열기전에 아래 방법으로 파일을 잠궈야 합니다.
Lock Files:
```
$ chflags uchg ~/Library/Mail/V3/MailData/Signatures/*.mailsignature
```
나중에 파일을 수정할 생각이면 아래 방법으로 언락하세요 :
```
$ chflags nouchg ~/Library/Mail/V3/MailData/Signatures/*.mailsignature
```
만약 iCloud drive 를 사용하는 경우에는 위와 같은 문제가 있을 수 있습니다. 아래 블로그 포스팅을 참고하시면 도움이 될 것 입니다. [아이클라우드 드라이브 문제 해결하기 (보기)](http://matt.coneybeare.me/how-to-make-an-html-signature-in-apple-mail-for-el-capitan-os-x-10-dot-11/).
### 아웃룩 2010에서 사용하기 (Outlook 2010)
#### 방법 1
- 아웃룩 2010을 켜고 `File > Option > Mail > Signature` 으로 접속하세요.
- 새 서명을 만드세요. (나중에 확인하기 좋게, 표시를 해두시면 좋습니다.)
- CMD를 켜고 아래와 같이 입력하세요.
> AppData 폴더가 숨김 폴더라 가급적이면 CMD를 사용하는 것을 권장합니다.
```
cd AppData\Roamin\Microsoft
start Signatures
```
- 이 폴더에서 아까 만든 서명파일을 찾아서 우클릭해서 편집을 하세요.
- 모든 HTML코드를 여러분이 새로 만든 코드로 바꿔버리세요.
- 아웃룩을 열고 서명이 적용됐는지 확인해주세요.
> **주의** 위 방법으로 진행할 경우, 한글 등 유니코드가 깨지는 문제가 있습니다. 한글 이메일 서명의 경우 아래 **방법2**을 사용하시기 바랍니다.
#### 방법 2
아웃룩에서는 html 파일을 넣는 방법을 제공하지 않습니다. (아...) 그래서 위의 **방법 2** 처럼 파일을 복사/붙여넣기 하는 방법으로 사용할 수 있습니다.
- `/dist` 에 빌드한 html 파일을 브라우저에서 열고, ctrl A + C 로 복사하세요.
- Outlook 을 열고 `파일 > 옵션 > 메일 > 서명` 으로 들어가세요.
- 새 서명을 만들고 아래 박스에 Ctrl + V 로 파일을 붙여넣기 하세요.
> base 64로 만든 이메일 파일은 잘 작동하지 않을 수 있습니다. 외부 링크를 활용하시기를 권장합니다.

0
i18n/ro-RO.md Normal file
View File

28783
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,94 @@
{
"name": "responsive-html-email-signature",
"version": "3.0.0",
"description": "Responsive template for email signatures",
"version": "6.1.0",
"description": "Responsive template for emails & email signatures.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/fadeit/responsive-html-email-signature.git"
"url": "git+https://github.com/danmindru/responsive-html-email-signature.git"
},
"keywords": [
"responsive",
"template",
"email",
"signature"
"signature",
"email-signatures",
"inline-styles",
"watches-html"
],
"author": "Dan Mindru <mindrudan@gmail.com> (http://mindrudan.com/)",
"author": "Dan Mindru <mindrudan@gmail.com> (https://mindrudan.com/)",
"license": "MIT",
"bugs": {
"url": "https://github.com/fadeit/responsive-html-email-signature/issues"
"url": "https://github.com/danmindru/responsive-html-email-signature/issues"
},
"homepage": "https://github.com/danmindru/responsive-html-email-signature#readme",
"scripts": {
"start": "./node_modules/.bin/gulp",
"once": "./node_modules/.bin/gulp run-pipeline",
"deploy": "npm run test && cp -r dist demo && git push origin `git subtree split --prefix demo develop`:gh-pages --force",
"test": "npm run once && npm run _test",
"test:watch": "npm run once && npm run _test:watch",
"format": "./node_modules/.bin/prettier {tasks,tests}/**/*.js gulpfile.js .eslintrc.js --write",
"lint": "./node_modules/.bin/eslint ./**/*.js gulpfile.js",
"_test": "./node_modules/.bin/ava",
"_test:watch": "./node_modules/.bin/ava --watch"
},
"dependencies": {
"autoprefixer": "^9.6.1",
"chalk": "^2.4.2",
"cheerio": "^0.22.0",
"del": "^5.1.0",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^7.0.1",
"gulp-david": "^1.0.1",
"gulp-inline-css": "^3.5.0",
"gulp-inline-images-no-http": "^1.3.3",
"gulp-jsonlint": "^1.3.2",
"gulp-less": "^4.0.1",
"gulp-minify-html": "~1.0.5",
"gulp-minify-inline": "^1.1.0",
"gulp-plumber": "^1.2.1",
"gulp-postcss": "^8.0.0",
"gulp-preprocess": "^3.0.3",
"gulp-rename": "^2.0.0",
"gulp-sass": "^4.1.0",
"klaw": "^3.0.0",
"node-sass": "^7.0.0",
"plugin-error": "^1.0.1",
"through2": "^2.0.5"
},
"homepage": "https://github.com/fadeit/responsive-html-email-signature#readme",
"devDependencies": {
"del": "^2.0.2",
"gulp": "^3.9.0",
"gulp-inline-css": "^3.0.0",
"gulp-inline-image-html": "^0.2.1",
"gulp-minify-html": "^1.0.4",
"gulp-minify-inline": "^0.1.1",
"gulp-preprocess": "^1.2.0",
"gulp-rename": "^1.2.2",
"q": "^1.4.1",
"run-sequence": "^1.1.4",
"wrench": "^1.5.8"
"ava": "^2.4.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"graceful-fs": "^4.2.4",
"gulp-cli": "^2.3.0",
"opencollective-postinstall": "^2.0.3",
"prettier": "^1.19.1",
"pretty-quick": "^2.0.1"
},
"resolutions": {
"graceful-fs": "^4.2.4",
"vinyl-fs": "^3.0.3"
},
"browserslist": [
"last 5 versions"
],
"husky": {
"hooks": {
"pre-push": "npm run test",
"pre-commit": "npm run lint && node ./node_modules/.bin/pretty-quick --staged --pattern ./**/*.js"
}
},
"ava": {
"helpers": [
"**/util.js"
]
}
}

View File

@ -1,19 +0,0 @@
/*
* NB: for images, if you pass in a relative path ('assets/logo.png'), they will be automatically embedded (base64). If you pass in a URL, it will stay as it is.
*/
module.exports = [
{
id: 'fadeit', // Will be appended to the built templates.
signature: 'Yours truly,',
name: 'Jane Whatsmyname',
welcome: 'Hi there,',
introParagraph: 'Thanks for writing up this email.<br/> We are delighted to reply with a responsive template.',
contactMain: 'Call <a href="tel:81100200"><span>81100200</span></a> or email us at', // Wrap phone numbers like this to prevent iOS mail from making them blue.
contactMail: 'info@fadeit.dk',
contactSecondary: 'Anelystparken 31, DK-8381 Tilst, Aarhus',
logoUrl: 'http://fadeit.dk/src/assets/img/brand/fadeit-logo.png',
logoAlt: 'fadeit logo',
website: 'http://fadeit.dk'
}
]

View File

@ -1,13 +0,0 @@
module.exports = [
{
id: 'play',
signature: 'Best regards,',
name: 'Jane Whatsmyname',
contactMain: 'Call <a href="tel:004581100200"><span>(45) 81100200</span></a> or email us at', // Wrap phone numbers like this to prevent iOS mail from making them blue.
contactMail: 'info@tryplay.dk',
slogan: 'LED Pylon. LED Wall. Digital Signage.',
logoUrl: 'https://informationscreen.com/manage/assets/images/play-logo.png',
logoAlt: 'Play. logo',
website: 'http://tryplay.dk'
}
]

View File

@ -1,58 +1,77 @@
'use strict';
const gulp = require('gulp');
const inlineCss = require('gulp-inline-css');
const minifyHTML = require('gulp-minify-html');
const minifyInline = require('gulp-minify-inline');
const preprocess = require('gulp-preprocess');
const rename = require('gulp-rename');
const del = require('del');
const { inlineImg } = require('./check-for-image-url');
const { getConfigsForDir, getFilePathsForDir, getCssLinkTagsFromFilelist } = require('./util/util');
var gulp = require('gulp'),
inlineCss = require('gulp-inline-css'),
minifyHTML = require('gulp-minify-html'),
minifyInline = require('gulp-minify-inline'),
preprocess = require('gulp-preprocess'),
rename = require('gulp-rename'),
wrench = require('wrench'),
Q = require('q'),
del = require('del'),
inlineimg = require('gulp-inline-image-html');
function buildTask(options) {
// Requires: 'dupe', 'less', 'sass', 'postcss', 'lint'.
gulp.task('build', function build(done) {
/**
* Makes templates for a given directory & its configurations.
*
* @function makeTemplates
* @param {String} dir Directory to make templates from.
* @param {Array} confItems A list of configurations objects (usually persons) to make templates from.
*/
function makeTemplates(dir, confItems) {
return confItems.map(async conf => {
const cwd = `${options.workingDir}/${dir}`;
function buildTask(options){
gulp.task('build', function(cb) {
var promises = []
del(options.dist).then(function(){
wrench.readdirSyncRecursive(options.src).filter(function(file) {
return (!file.match('/') && !file.match(/^\.+/g)) ? file : false
}).forEach(function(dir){
var confPath = './../' + options.src + '/' + dir + '/conf.js';
delete require.cache[require.resolve(confPath)]
promises.push(makeTemplates(dir, require(confPath)));
});
function makeTemplates(dir, confItems){
confItems.forEach(function(item){
var cwd = options.src + '/' + dir;
gulp.src([cwd + '/**/*.html', '!' + cwd + '/**/*.inc.html'])
.pipe(preprocess({
context: item
}))
.pipe(inlineimg(cwd))
.pipe(inlineCss({
applyTableAttributes: true,
applyWidthAttributes: true,
preserveMediaQueries: true,
removeStyleTags: false
}))
.pipe(minifyHTML({quotes: true}))
.pipe(minifyInline())
.pipe(rename(function rename(path){
path.dirname = dir;
path.basename += '-' + item.id;
return path;
}))
.pipe(gulp.dest(options.dist));
/**
* Find stylesheets relative to the CWD & generate <link> tags.
* This way we can automagically inject them into <head>.
*/
const files = await getFilePathsForDir(cwd);
const context = Object.assign(conf, {
stylesheets: getCssLinkTagsFromFilelist(files)
});
}
Q.all(promises).then(function(){ cb(); });
});
return options
.src([cwd + '/**/*.html', '!' + cwd + '/**/*.inc.html'])
.pipe(preprocess({ context }))
.pipe(inlineImg({ getHTTP: confItems[0]['inlineRemoteUrl'] }))
.pipe(
inlineCss({
applyTableAttributes: true,
applyWidthAttributes: true,
preserveMediaQueries: true,
removeStyleTags: false
})
)
.pipe(minifyHTML({ quotes: true }))
.pipe(minifyInline())
.pipe(
rename(function rename(path) {
path.dirname = dir;
path.basename += '-' + conf.id;
return path;
})
)
.pipe(gulp.dest(options.distDir));
});
}
/*
* Clean up & then read from workingDir to generate templates.
* For each found config, a template group will be generated through `makeTemplates`.
*/
return del(options.distDir)
.then(() => {
/**
* Loop through dirs and load their conf files.
* Promisify all 'makeTemplate' calls and when resolved, let gulp know we're done.
*/
const configs = getConfigsForDir(options.workingDir, options.configurationFile);
return Promise.all(configs.map(({ dir, confItems }) => makeTemplates(dir, confItems)));
})
.then(() => done())
.catch(err => console.log(err));
});
}
module.exports = buildTask
module.exports = buildTask;

View File

@ -0,0 +1,155 @@
'use strict';
const https = require('https');
const http = require('http');
const path = require('path');
const url = require('url');
const fs = require('fs');
const PluginError = require('plugin-error');
const through = require('through2');
const cheerio = require('cheerio');
const { log } = require('./util/util');
const PLUGIN_NAME = 'gulp-inline-images';
const MIME_TYPE_REGEX = /.+\/([^\s]*)/;
const INLINE_ATTR = 'inline';
const NOT_INLINE_ATTR = `!${INLINE_ATTR}`;
function inlineImg(options = {}) {
const selector = options.selector || 'img[src]';
const attribute = options.attribute || 'src';
const getHTTP = options.getHTTP || false;
return through.obj(function(file, encoding, callback) {
if (file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
return callback();
}
if (file.isBuffer()) {
const contents = file.contents.toString(encoding);
// Load it into cheerio's virtual DOM for easy manipulation
const $ = cheerio.load(contents);
const inlineFlag = $(`img[${INLINE_ATTR}]`);
// If images with an inline attr are found that is the selection we want
const imgTags = inlineFlag.length ? inlineFlag : $(selector);
let count = 0;
imgTags.each(function() {
const $img = $(this);
const src = $img.attr(attribute);
// Save the file format from the extension
const extFormat = path.extname(src).substr(1);
// If inlineFlag tags were found we want to remove the inline tag
if (inlineFlag.length) {
$img.removeAttr(INLINE_ATTR);
}
// Find !inline attribute
const notInlineFlag = $img.attr(NOT_INLINE_ATTR);
if (typeof notInlineFlag !== typeof undefined && notInlineFlag !== false) {
// Remove the tag and don't process this file
return $img.removeAttr(NOT_INLINE_ATTR);
}
// Count async ops
count++;
getSrcBase64(options.basedir || file.base, getHTTP, src, (err, result, resFormat, skipFormatting) => {
if (err) {
log.warn(`Failed to load http image. Check the format of ${src}.`);
log.error(err);
} else {
// Need a format in and a result for this to work
if (!skipFormatting) {
if (result && (extFormat || resFormat)) {
$img.attr('src', `data:image/${extFormat};base64,${result}`);
} else {
$img.attr('src', ``);
$img.attr('alt', `Image not found, Please check Url`);
log.warn(`Failed to read image. Check the format of ${src}.`);
}
}
if (!--count) {
file.contents = Buffer.from($.html());
callback(null, file);
}
}
});
});
// If no files are processing we don't need to wait as none were ever started
if (!imgTags.length) {
file.contents = Buffer.from($.html());
callback(null, file);
}
}
});
}
function getHTTPBase64(url, callback) {
// Get applicable library
const lib = url.startsWith('https') ? https : http;
// Initiate a git request to our URL
const req = lib.get(url, res => {
// Check for redirect
if (res.statusCode >= 301 && res.statusCode < 400 && res.headers.location) {
// Redirect
return getHTTPBase64(res.headers.location, callback);
}
// Check for HTTP errors
if (res.statusCode < 200 || res.statusCode >= 400) {
return callback(new Error('Failed to load page, status code: ' + res.statusCode));
}
// Get file format
let format;
if (res.headers['content-type']) {
const matches = res.headers['content-type'].match(MIME_TYPE_REGEX);
if (matches) {
format = matches[1];
}
}
// Create an empty buffer to store the body in
let body = Buffer.from([]);
// Append each chunk to the body
res.on('data', chunk => (body = Buffer.concat([body, chunk])));
// Done callback
res.on('end', () => callback(null, body.toString('base64'), format));
});
// Listen for network errors
req.on('error', err => callback(err));
}
function getSrcBase64(base, getHTTP, src, callback) {
// TODO: @deprecated — since v11.0.0 url.parse should be replaced with url.URL() ctor
if (!url.parse(src).hostname) {
// Get local file
const filePath = path.join(base, src);
if (fs.existsSync(filePath)) {
fs.readFile(filePath, 'base64', callback);
} else {
callback(null);
}
} else {
// Get remote file
if (getHTTP) {
return getHTTPBase64(src, callback);
} else {
callback(null, src, null, true);
}
}
}
module.exports = {
inlineImg,
getHTTPBase64,
getSrcBase64
};

View File

@ -0,0 +1,10 @@
const gulp = require('gulp');
function checkForUnusedTask(options) {
gulp.task('check-for-missing', async done => {
// TODO
done();
});
}
module.exports = checkForUnusedTask;

75
tasks/check-for-unused.js Normal file
View File

@ -0,0 +1,75 @@
const gulp = require('gulp');
const chalk = require('chalk');
const { getConfigsForDir, getFilePathsForDir, getHtmlTemplatesFromFilelist, log } = require('./util/util');
const OUTPUT_KEYWORD = '@echo';
function checkForUnusedTask(options) {
gulp.task('check-for-unused', async done => {
const configs = getConfigsForDir(options.workingDir, options.configurationFile);
const unusedItems = await checkForUnusedItemsInConfigs(options.workingDir, configs);
outputWarningsForUnusedItems(unusedItems, configs);
done();
});
}
/**
* Outputs warnings for unused items.
*
* @param { Array<Array<string>> } unusedItems
* @param { Array<object> } configs
*/
const outputWarningsForUnusedItems = (unusedItems, configs) => {
const find = OUTPUT_KEYWORD;
const regex = new RegExp(find, 'g');
unusedItems.forEach((unusedInConfigs, index) => {
const { dir } = configs[index];
unusedInConfigs.forEach(unusedInConfItems => {
const unusedItemsToLog = unusedInConfItems
.filter(item => item !== `${OUTPUT_KEYWORD} id`)
.filter(item => item !== '@echo inlineRemoteUrl');
if (unusedItemsToLog.length) {
log.warn(
`${unusedItemsToLog.length} unused properties in ${dir}: ${unusedItemsToLog
.reduce((acc, cur) => (acc ? `${acc}, ${chalk.white(cur)}` : chalk.white(cur)), '')
.replace(regex, '')}`
);
}
});
});
};
/**
* In a directory, checks for unused configs.
*
* @param { string } rootDir
* @param { Array } configs Array of configs.
*/
const checkForUnusedItemsInConfigs = (rootDir, configs) =>
Promise.all(
configs.map(async ({ dir, confItems }) => {
return Promise.all(
confItems.map(async confItem => {
const definedStrings = Object.keys(confItem).map(key => `${OUTPUT_KEYWORD} ${key}`);
const cwd = `${rootDir}/${dir}`;
const files = await getFilePathsForDir(cwd);
const htmlTemplates = await getHtmlTemplatesFromFilelist(files);
const concatenatedTemplates = htmlTemplates.join('');
return definedStrings.filter(str => !concatenatedTemplates.includes(str));
})
);
})
);
const self = {
checkForUnusedTask,
outputWarningsForUnusedItems,
checkForUnusedItemsInConfigs
};
module.exports = self;

12
tasks/dupe.js Normal file
View File

@ -0,0 +1,12 @@
const gulp = require('gulp');
const del = require('del');
function dupeTask(options) {
gulp.task('dupe', function() {
del.sync([options.workingDir]);
return options.src([options.sourceDir + '/**/*']).pipe(gulp.dest('./' + options.workingDir));
});
}
module.exports = dupeTask;

18
tasks/less.js Normal file
View File

@ -0,0 +1,18 @@
const gulp = require('gulp');
const less = require('gulp-less');
const autoprefixer = require('gulp-autoprefixer');
const rename = require('gulp-rename');
function lessTask(options) {
// Requires: dupe.
gulp.task('less', function() {
return options
.src(options.workingDir + '/**/*.less')
.pipe(less())
.pipe(autoprefixer())
.pipe(rename({ extname: '.css' }))
.pipe(gulp.dest(options.workingDir));
});
}
module.exports = lessTask;

14
tasks/lint.js Normal file
View File

@ -0,0 +1,14 @@
const gulp = require('gulp');
const jsonlint = require('gulp-jsonlint');
function lintTask(options) {
// Requiers: dupe.
gulp.task('lint', function() {
return options
.src(options.workingDir + '/**/conf.json')
.pipe(jsonlint())
.pipe(jsonlint.reporter());
});
}
module.exports = lintTask;

17
tasks/postcss.js Normal file
View File

@ -0,0 +1,17 @@
const gulp = require('gulp');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
function postcssTask(options) {
// Requires: dupe.
gulp.task('postcss', function() {
var processors = [autoprefixer()];
return options
.src(options.workingDir + '/**/*.css')
.pipe(postcss(processors))
.pipe(gulp.dest(options.workingDir));
});
}
module.exports = postcssTask;

21
tasks/sass.js Normal file
View File

@ -0,0 +1,21 @@
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const sass = require('gulp-sass');
const rename = require('gulp-rename');
function sassTask(options) {
// Requires: dupe.
gulp.task(
'sass',
gulp.series('dupe', function() {
return options
.src(options.workingDir + '/**/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(rename({ extname: '.css' }))
.pipe(gulp.dest(options.workingDir));
})
);
}
module.exports = sassTask;

131
tasks/util/util.js Normal file
View File

@ -0,0 +1,131 @@
const fs = require('fs');
const path = require('path');
const klaw = require('klaw');
const chalk = require('chalk');
// todo test
/**
* Given a directory, scans all directories in it (not deep) and returns found config items.
*
* @param { string } rootDir Dir to look into.
* @param { string } configFileName Files to look for in each dir, i.e. conf.json
*/
const getConfigsForDir = (rootDir, configFileName) => {
return fs
.readdirSync(rootDir)
.map(dir => {
const confPath = `${dir}/${configFileName}`;
/** Exit with warn if no configuration file found. */
if (!fs.existsSync(path.resolve(rootDir, confPath))) {
self.log.warn(`Missing configuration in "${dir}". Did you remember to create "${dir}/${configFileName}"?`);
return false;
}
let current = null;
let confItems;
const resolvedPath = path.resolve(rootDir, confPath);
delete require.cache[resolvedPath]; // NB: For 'watch' to properly work, the cache needs to be deleted before each require.
current = require(resolvedPath);
// Handle single objects or arrays of configs.
if (current && current.length) {
confItems = [...current];
} else {
confItems = [current];
}
return {
dir,
confItems
};
})
.filter(config => config);
};
/**
* Given a directory, gets all file paths in it.
*
* @param { string } dir Dir to get files paths for.
*/
const getFilePathsForDir = dir => {
const files = [];
return new Promise(resolve => {
klaw(dir)
.on('readable', function walkTemplateDir() {
let file;
while ((file = this.read())) {
const relativePath = `${__dirname.substring(0, __dirname.lastIndexOf('/'))}/${dir}`;
files.push(file.path.replace(relativePath, ''));
}
})
.on('end', function finishedTemplateDirWalk() {
resolve(files);
});
});
};
/**
* Gets an array of html files in a filelist.
*
* @param { Array } filelist
*/
const getHtmlTemplatesFromFilelist = filelist => {
return Promise.all(
filelist
.filter(file => file.match(/.*\.html/) || file.match(/.*\.inc*\.html/))
.map(
htmlTemplate =>
new Promise((resolve, reject) => {
fs.readFile(htmlTemplate, 'utf8', (error, data) => {
if (error) {
reject(error);
}
resolve(data);
});
})
)
);
};
/**
* Gets an array of css link tags from a filelist (if css files are in the filelist).
*
* @param { Array } filelist
*/
const getCssLinkTagsFromFilelist = filelist => {
return filelist
.filter(file => !!file.match(/.*\.css/)) // Read only CSS files.
.reduce((acc, cur) => {
const cssPath = path.win32.basename(cur);
return (acc += '<link rel="stylesheet" href="' + cssPath + '">');
}, '');
};
const log = {
warn: (...messages) => {
console.warn('🔵 ', chalk.yellow(messages));
},
log: (...messages) => {
console.log('🔘 ', chalk.gray(messages));
},
error: (...messages) => {
console.error('🔴 ', chalk.red(messages));
}
};
const self = {
log,
getConfigsForDir,
getFilePathsForDir,
getHtmlTemplatesFromFilelist,
getCssLinkTagsFromFilelist
};
module.exports = self;

View File

@ -1,11 +0,0 @@
'use strict';
var gulp = require('gulp');
function watchTask(options){
gulp.task('watch', function(){
gulp.watch([options.src + '/**/*.html', options.src + '/**/*.css', options.src + '/**/conf.js'], ['build']);
});
};
module.exports = watchTask

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

11
templates/dark/conf.json Normal file
View File

@ -0,0 +1,11 @@
{
"id": "dark",
"signature": "Best regards,",
"name": "The dark mail team",
"contactMain": "Call <a href='tel:004580100100'><span>(45) 80100100</span></a> or email us at",
"contactMail": "info@dark.dk",
"slogan": "LED Pylon. LED Wall. Digital Signage.",
"logoUrl": "/assets/dark.png",
"logoAlt": "dark logo",
"website": "http://dark.dk"
}

160
templates/dark/dark.css Normal file
View File

@ -0,0 +1,160 @@
/*
* =====================================
* 1. Common styles for general table things.
* =====================================
*/
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
tr {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
box-sizing: border-box;
font-size: 14px;
line-height: 22px;
}
.main {
width: 100%;
background-color: #ffffff;
}
.rbcc {
/*
* rbcc -> reset - border - cellspacing - cellpading
*
* Resets table attributes.
*/
border: 0;
cellpadding: 0;
cellspacing: 0;
}
.sp {
/* Separator tr; props are actually contained by it's inner element atm. */
}
.sp__inner {
padding: 15px 0;
}
.spd {
/* Separator tr (double); props are actually contained by it's inner element atm. */
}
.spd__inner {
height: 60px;
}
a {
text-decoration: none;
color: #0fade1;
}
/*
* =================
* 2. Content styles.
* ==================
*/
.main__welcome {
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 22px;
}
.main__content {
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
}
/*
* ================
* 3. Footer styles.
* ================
*/
.footer {
background-color: #303030;
padding: 20px 30px 0px 30px;
color: #f5f5f5;
border-top: 8px solid #585858;
}
.footer a {
color: #f5f5f5;
}
.footer--simple {
padding-bottom: 20px;
background-color: #ffffff;
}
.footer--simple tr td {
color: #888;
}
.footer__main {
/* This style property fucks up the width on OS X, needs to be *JUST* attribute */
width: 100%;
}
.footer__main__signature {
font-size: 14px;
color: #f5f5f5;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: left;
}
.footer__main__col1 {
width: 70%;
margin-bottom: 40px;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: left;
}
.footer__main__col1__td {
color: #9e9e9e;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: left;
padding-top: 15px;
}
.footer__main__col1__td > span {
font-size: 18px;
margin-bottom: 5px;
}
.footer__main a > span {
/* Revert apple blue-link style. */
color: #f5f5f5 !important;
text-decoration: none !important;
}
.footer__main__col2 {
width: 30%;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: right;
}
.footer__main__col2__td {
font-size: 14px;
color: #f5f5f5;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: right;
}
.footer__main__col2__td__img {
border: 0;
padding-left: 20px;
max-width: 100%;
max-height: 65px;
height: auto;
}

View File

@ -0,0 +1,32 @@
<td class="footer">
<table class="rbcc footer__main">
<tr>
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<strong><!-- @echo name --></strong><br />
</td>
</tr>
<tr class="spd">
<td class="spd__inner"></td>
</tr>
<tr>
<table class="rbcc footer__main__col2" align="right">
<td class="footer__main__col2__td" align="right">
<a href="<!-- @echo website -->">
<img src="<!-- @echo logoUrl -->" alt="<!-- @echo logoAlt -->" class="footer__main__col2__td__img" />
</a>
</td>
</table>
<table class="rbcc footer__main__col1" align="left">
<td class="footer__main__col1__td" align="left">
<span><!-- @echo slogan --></span><br />
<!-- @echo contactMain -->
<a href="mailto:<!-- @echo contactMail -->" target="_blank"><!-- @echo contactMail --></a>
</td>
</table>
</tr>
</table>
</td>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Inject stylesheets after they are processed with LESS, SASS or postcss. -->
<!-- @echo stylesheets -->
<style type="text/css">
/* Ideally, this would be part of a linked CSS file. @see https://github.com/fadeit/responsive-html-email-signature/issues/15 */
/*
* ================
* 4. Basic responsive stuff.
* ================
*/
@media only screen and (max-width:560px){
.footer td{
font-size: 12px!important;
}
.footer__main__col1{
width: 100%!important;
}
.footer__main__col1__td{
text-align: left;
}
.footer__main__col1__td > span{
margin-bottom:10px;
}
.footer__main__col2{
width: 100%!important;
}
.footer__main__col2__td{
text-align: left;
padding-bottom:20px;
}
.footer__main__col2__td__img{
padding-left:0!important;
}
}
</style>
</head>

View File

@ -0,0 +1,25 @@
<!-- @include head.inc.html -->
<body>
<br />
<!-- <br/> Makes it easier to add text when composing -->
<table class="main rbcc">
<tr class="sp">
<td class="sp__inner"></td>
</tr>
<tr class="rbcc">
<td class="footer footer--simple">
<table class="rbcc footer__main">
<tr>
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<!-- @echo name --><br />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>

View File

@ -0,0 +1,13 @@
<!-- @include head.inc.html -->
<body>
<br/> <!-- <br/> Makes it easier to add text when composing -->
<table class="main rbcc">
<tr class="sp"><td class="sp__inner"></td></tr>
<tr class="rbcc">
<!-- @include footer.inc.html -->
</tr>
</table>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

13
templates/light/conf.json Normal file
View File

@ -0,0 +1,13 @@
{
"id": "light",
"signature": "Yours truly,",
"name": "The light mail team",
"welcome": "Hi there,",
"introParagraph": "Thanks for writing up this email.<br/> We are delighted to reply with a responsive template.",
"contactMain": "Call <a href='tel:80100100'><span>80100100</span></a> or email us at",
"contactMail": "info@light.dk",
"contactSecondary": "<a href='https://mapurl.com'><span>Happy Steet 31, DK-8000 Aarhus C, Denmark</span></a>",
"logoUrl": "/assets/light.png",
"logoAlt": "light logo",
"website": "http://light.dk"
}

View File

@ -0,0 +1,32 @@
<td class="footer">
<table class="rbcc footer__main">
<tr>
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<!-- @echo name --><br />
</td>
</tr>
<tr class="gray-hr">
<td><hr class="gray-hr" /></td>
</tr>
<tr>
<table class="rbcc footer__main__col1" align="left">
<td class="footer__main__col1__td" align="left">
<strong>
<!-- @echo contactMain -->
<a href="mailto:<!-- @echo contactMail -->" target="_blank"><!-- @echo contactMail --></a> </strong
><br />
<!-- @echo contactSecondary -->
</td>
</table>
<table class="rbcc footer__main__col2" align="right">
<td class="footer__main__col2__td" align="right">
<a href="<!-- @echo website -->">
<img src="<!-- @echo logoUrl -->" alt="<!-- @echo logoAlt -->" class="footer__main__col2__td__img" />
</a>
</td>
</table>
</tr>
</table>
</td>

View File

@ -0,0 +1,28 @@
<!-- @include head.inc.html -->
<body class="body-with-bg">
<table class="background rbcc">
<tr>
<td>
<table class="main rbcc">
<tr class="rbcc">
<td class="main__welcome">
<b><!-- @echo welcome --></b>
</td>
</tr>
<tr class="rbcc">
<td class="main__content">
<!-- @echo introParagraph -->
</td>
</tr>
<tr class="sp"><td class="sp__inner"></td></tr>
<tr class="rbcc">
<!-- @include footer.inc.html -->
</tr>
</table>
</td>
</tr>
</table>
</body>

View File

@ -0,0 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Inject stylesheets after they are processed with LESS, SASS or postcss. -->
<!-- @echo stylesheets -->
<style type="text/css">
/* Ideally, this would be part of a linked CSS file. @see https://github.com/fadeit/responsive-html-email-signature/issues/15 */
/*
* ================
* 4. Basic responsive stuff.
* ================
*/
@media only screen and (max-width:480px){
.footer td{
font-size: 12px!important;
}
.footer__main__col1{
width: 100%!important;
}
.footer__main__col2{
width: 100%!important;
}
.footer__main__col2__td{
text-align: left;
padding-bottom:20px;
}
.footer__main__col2__td__img{
padding-left:0!important;
}
.gray-hr hr{
margin-bottom:10px!important;
margin-top:10px!important;
}
}
@media only screen and (min-width:1025px){
/* After iPad size */
.body-with-bg{
background-color: #F1F1F1;
}
.body-with-bg .main{
border:1px solid #E9E9E9!important; /* Sorry! */
max-width:960px;
margin:0 auto;
}
.background{
padding:30px;
background-color: #F1F1F1;
}
}
</style>
</head>

166
templates/light/light.css Normal file
View File

@ -0,0 +1,166 @@
/*
* =====================================
* 1. Common styles for general table things.
* =====================================
*/
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
}
tr {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
box-sizing: border-box;
font-size: 14px;
line-height: 20px;
}
.rbcc {
/*
* rbcc -> reset - border - cellspacing - cellpading
*
* Resets table attributes.
*/
border: 0;
cellpadding: 0;
cellspacing: 0;
}
.background {
width: 100%;
}
.main {
width: 100%;
background-color: #ffffff;
padding-top: 15px;
}
.sp {
/* Separator tr; props are actually contained by it's inner element atm. */
}
.sp__inner {
padding: 15px 0;
}
.gray-hr {
/* 100% width light grey line; props are actually contained by inner elements atm. */
}
.gray-hr td {
width: 100%;
}
.gray-hr hr {
border-bottom: 1px solid #e4e4e4;
border-top: none;
margin-bottom: 20px;
margin-top: 20px;
color: transparent;
background: transparent;
}
a {
text-decoration: none;
color: #0fade1;
}
/*
* =================
* 2. Content styles.
* ==================
*/
.main__welcome {
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 22px;
}
.main__content {
color: #000;
padding: 10px 30px 0 30px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
}
/*
* ================
* 3. Footer styles.
* ================
*/
.footer {
background-color: #f5f5f5;
padding: 20px 30px 0px 30px;
color: #888;
border-top: 8px solid #eaeaea;
}
.footer a {
color: #888;
}
.footer--simple {
padding-bottom: 20px;
background-color: #ffffff;
}
.footer__main {
/* NB: This prop fucks up the width on OS X, needs to be *JUST* attribute. */
width: 100%;
}
.footer__main__signature {
font-size: 14px;
color: #888;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: left;
}
.footer__main__col1 {
width: 70%;
margin-bottom: 30px;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: left;
}
.footer__main__col1__td {
font-size: 14px;
color: #888;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: left;
}
.footer__main a > span {
/* Revert apple blue-link style. */
color: #888 !important;
text-decoration: none !important;
}
.footer__main__col2 {
width: 30%;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: right;
}
.footer__main__col2__td {
font-size: 14px;
color: #888;
/* @todo gulp-inline-css doesn't parse align; it needs to be duplicated in the HTML template */
align: right;
}
.footer__main__col2__td__img {
border: 0;
padding-top: 6px;
padding-left: 10px;
max-width: 100%;
max-height: 38px;
height: auto;
}

View File

@ -0,0 +1,23 @@
<!-- @include head.inc.html -->
<body>
<br />
<table class="main rbcc">
<tr class="sp">
<td class="sp__inner"></td>
</tr>
<tr class="rbcc">
<td class="footer footer--simple">
<table class="rbcc footer__main">
<tr>
<td class="footer__main__signature" align="left">
<!-- @echo signature --><br />
<!-- @echo name --><br />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>

View File

@ -0,0 +1,13 @@
<!-- @include head.inc.html -->
<body>
<br/> <!-- <br/> Makes it easier to add text when composing -->
<table class="main rbcc">
<tr class="sp"><td class="sp__inner"></td></tr>
<tr class="rbcc">
<!-- @include footer.inc.html -->
</tr>
</table>
</body>

View File

@ -0,0 +1,37 @@
const test = require('ava');
const { readFileSync } = require('../util');
test('dark signature output', async t => {
const expected = readFileSync('tests/sample/dark/signature-dark.html');
const built = readFileSync('dist/dark/signature-dark.html');
t.deepEqual(expected, built);
});
test('dark signature reply output', async t => {
const expected = readFileSync('tests/sample/dark/signature-reply-dark.html');
const built = readFileSync('dist/dark/signature-reply-dark.html');
t.deepEqual(expected, built);
});
test('light signature output', async t => {
const expected = readFileSync('tests/sample/light/signature-light.html');
const built = readFileSync('dist/light/signature-light.html');
t.deepEqual(expected, built);
});
test('light signature reply output', async t => {
const expected = readFileSync('tests/sample/light/signature-reply-light.html');
const built = readFileSync('dist/light/signature-reply-light.html');
t.deepEqual(expected, built);
});
test('light full mail output', async t => {
const expected = readFileSync('tests/sample/light/full-mail-light.html');
const built = readFileSync('dist/light/full-mail-light.html');
t.deepEqual(expected, built);
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><style type="text/css">@media only screen and (max-width:560px){.footer td{font-size:12px!important}.footer__main__col1{width:100%!important}.footer__main__col1__td{text-align:left}.footer__main__col1__td>span{margin-bottom:10px}.footer__main__col2{width:100%!important}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}}</style></head><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffff" width="100%"><tr class="sp" style="-webkit-box-sizing: border-box; box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="sp__inner" style="padding: 15px 0;"></td></tr><tr class="rbcc" style="-webkit-box-sizing: border-box; border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer footer--simple" style="border-top: 8px solid #585858; color: #f5f5f5; padding: 20px 30px 0px 30px; padding-bottom: 20px;" bgcolor="#ffffff"><table class="rbcc footer__main" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0" width="100%"><tr style="-webkit-box-sizing: border-box; box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Best regards,<br>The dark mail team<br></td></tr></table></td></tr></table></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta name="viewport" content="width=device-width"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><style type="text/css">@media only screen and (max-width:480px){.footer td{font-size:12px!important}.footer__main__col1{width:100%!important}.footer__main__col2{width:100%!important}.footer__main__col2__td{text-align:left;padding-bottom:20px}.footer__main__col2__td__img{padding-left:0!important}.gray-hr hr{margin-bottom:10px!important;margin-top:10px!important}}@media only screen and (min-width:1025px){.body-with-bg{background-color:#f1f1f1}.body-with-bg .main{border:1px solid #e9e9e9!important;max-width:960px;margin:0 auto}.background{padding:30px;background-color:#f1f1f1}}</style></head><body style="-webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"><br><table class="main rbcc" style="border: 0; cellpadding: 0; cellspacing: 0; padding-top: 15px;" border="0" cellpadding="0" cellspacing="0" bgcolor="#ffffff" width="100%"><tr class="sp" style="-webkit-box-sizing: border-box; box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="sp__inner" style="padding: 15px 0;"></td></tr><tr class="rbcc" style="-webkit-box-sizing: border-box; border: 0; box-sizing: border-box; cellpadding: 0; cellspacing: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer footer--simple" style="border-top: 8px solid #eaeaea; color: #888; padding: 20px 30px 0px 30px; padding-bottom: 20px;" bgcolor="#ffffff"><table class="rbcc footer__main" style="border: 0; cellpadding: 0; cellspacing: 0;" border="0" cellpadding="0" cellspacing="0" width="100%"><tr style="-webkit-box-sizing: border-box; box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 20px;"><td class="footer__main__signature" align="left" style="align: left; color: #888; font-size: 14px;">Yours truly,<br>The light mail team<br></td></tr></table></td></tr></table></body></html>

5
tests/util.js Normal file
View File

@ -0,0 +1,5 @@
const fs = require('fs');
module.exports = {
readFileSync: path => fs.readFileSync(('./', path), 'utf8')
};