Skip to content
This repository has been archived by the owner on Feb 4, 2020. It is now read-only.

Commit

Permalink
Releasing 1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
attilabuti committed Sep 28, 2018
1 parent 9085580 commit 7982146
Show file tree
Hide file tree
Showing 20 changed files with 3,625 additions and 1,059 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
out
node_modules
documentation/*
!documentation/build.ts
!documentation/tsconfig.json
*.vsix
4 changes: 4 additions & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ src/**
**/*.map
.gitignore
images/**/*.gif
documentation/**
!documentation/examples/*
!documentation/images/*
!documentation/documentation.html
tsconfig.json
vsc-extension-quickstart.md
tslint.json
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
All notable changes to the "mjml" extension will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).

### [1.5.0] (2018-09-28)
* [new] Configuration property `mjml.previewBackgroundColor`: preview background color ([#39](https://github.com/attilabuti/vscode-mjml/issues/39)).
* [new] Configuration property `mjml.showSaveDialog`: show the save as dialog instead of input box.
* [new] Configuration property `mjml.autoClosePreview`: automatically close preview when all open MJML documents have been closed.
* [new] `MJML: Documentation`: open the MJML documentation.
* [new] `MJML: Search in MJML documentation`: search for the selected mj-element in the MJML documentation.
* [#38](https://github.com/attilabuti/vscode-mjml/issues/38): added support for beautify mj-style.
* [#35](https://github.com/attilabuti/vscode-mjml/issues/35): show more useful information on error in sending the email.
* [#29](https://github.com/attilabuti/vscode-mjml/pull/29): merged pull request.
* MJML syntax highlight with CSS support.
* The `PreviewManager` has been completely rewritten.
* Built-in MJML documentation with `Try it live` support.
* `Search in MJML documentation` from context menu.
* MJML 4.1.2
* Some other improvements.

### [1.4.0] (2018-07-14)
* [#30](https://github.com/attilabuti/vscode-mjml/issues/30): fixed PhantomJS rebuild issue.
* [#27](https://github.com/attilabuti/vscode-mjml/issues/27) [#31](https://github.com/attilabuti/vscode-mjml/issues/31): fixed rendering issue.
Expand Down
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ MJML preview, lint, compile for Visual Studio Code.
* Fetch official templates. Based on [mjml-app](https://github.com/mjmlio/mjml-app).
* Beautify MJML code.
* Migrate a template from MJML 3 to MJML 4.
* MJML syntax highlight. Based on [mjml-syntax](https://github.com/mjmlio/mjml-syntax).
* Built-in MJML documentation with `Try it live` support.

## It looks like this

Expand Down Expand Up @@ -45,6 +47,8 @@ The following command is available:
* **MJML: Screenshot** Take a screenshot of the rendered MJML document, and save it as a file.
* **MJML: Send Email** Send email with Nodemailer or Mailjet.
* **MJML: Template** Fetch official templates.
* **MJML: Documentation** open the MJML documentation.
* **MJML: Search in MJML documentation** search for the selected mj-element in the MJML documentation.

## Settings

Expand All @@ -71,6 +75,9 @@ The following command is available:
| `mjml.screenshotWidth` | `650` | Screenshot width. |
| `mjml.screenshotWidths` | `640,750` | Screenshot widths. |
| `mjml.updateWhenTyping` | `true` | Update preview when typing. |
| `mjml.previewBackgroundColor` | ` ` | Preview background color. |
| `mjml.autoClosePreview` | `true` | Automatically close preview when all open MJML documents have been closed. |
| `mjml.showSaveDialog` | `false` | Show the save as dialog instead of input box. |

## Snippets

Expand Down Expand Up @@ -152,6 +159,22 @@ Please see the [Nodemailer](https://nodemailer.com) documentation for more infor

## Change Log

### [1.5.0] (2018-09-28)
* [new] Configuration property `mjml.previewBackgroundColor`: preview background color ([#39](https://github.com/attilabuti/vscode-mjml/issues/39)).
* [new] Configuration property `mjml.showSaveDialog`: show the save as dialog instead of input box.
* [new] Configuration property `mjml.autoClosePreview`: automatically close preview when all open MJML documents have been closed.
* [new] `MJML: Documentation`: open the MJML documentation.
* [new] `MJML: Search in MJML documentation`: search for the selected mj-element in the MJML documentation.
* [#38](https://github.com/attilabuti/vscode-mjml/issues/38): added support for beautify mj-style.
* [#35](https://github.com/attilabuti/vscode-mjml/issues/35): show more useful information on error in sending the email.
* [#29](https://github.com/attilabuti/vscode-mjml/pull/29): merged pull request.
* MJML syntax highlight with CSS support.
* The `PreviewManager` has been completely rewritten.
* Built-in MJML documentation with `Try it live` support.
* `Search in MJML documentation` from context menu.
* MJML 4.1.2
* Some other improvements.

### [1.4.0] (2018-07-14)
* [#30](https://github.com/attilabuti/vscode-mjml/issues/30): fixed PhantomJS rebuild issue.
* [#27](https://github.com/attilabuti/vscode-mjml/issues/27) [#31](https://github.com/attilabuti/vscode-mjml/issues/31): fixed rendering issue.
Expand Down Expand Up @@ -259,14 +282,15 @@ A big thanks to the people that have contributed to this project:

- Christian Brevik ([@cbrevik](https://github.com/cbrevik)) - [contributions](https://github.com/attilabuti/vscode-mjml/commits?author=cbrevik))
- Kevin Oliveira ([@kvnol](https://github.com/kvnol)) - [contributions](https://github.com/attilabuti/vscode-mjml/commits?author=kvnol))
- Joshua Skrzypek ([@jskrzypek](https://github.com/jskrzypek)) - [contributions](https://github.com/attilabuti/vscode-mjml/commits?author=jskrzypek))

## License

This extension is licensed under the [MIT License][license-url].

[license-img]: https://img.shields.io/github/license/mashape/apistatus.svg?style=flat-square
[license-img]: https://img.shields.io/github/license/attilabuti/vscode-mjml.svg?style=flat-square
[license-url]: https://raw.githubusercontent.com/attilabuti/vscode-mjml/master/LICENSE
[vs-market-version]: https://vsmarketplacebadge.apphb.com/version-short/attilabuti.vscode-mjml.svg?style=flat-square
[vs-market-installs]: https://vsmarketplacebadge.apphb.com/installs/attilabuti.vscode-mjml.svg?style=flat-square
[vs-market-version]: https://img.shields.io/vscode-marketplace/v/attilabuti.vscode-mjml.svg?style=flat-square
[vs-market-installs]: https://img.shields.io/vscode-marketplace/d/attilabuti.vscode-mjml.svg?style=flat-square
[vs-market-url]: https://marketplace.visualstudio.com/items?itemName=attilabuti.vscode-mjml
[dependencies-status]: https://david-dm.org/attilabuti/vscode-mjml/status.svg?style=flat-square
250 changes: 250 additions & 0 deletions documentation/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
"use strict";

import * as fs from "fs";
import * as path from "path";

import * as fetch from "node-fetch";
import * as hljs from "highlight.js";

const md = require("markdown-it")({
html: true,
highlight: (str: string, lang: string) => {
if (lang && hljs.getLanguage(lang)) {
if (lang && hljs.getLanguage(lang)) {
try {
return `<div>${hljs.highlight(lang, str, true).value}</div>`;
} catch (err) {}
}
}

return "";
}
}).use(require("markdown-it-anchor"));


let githubAccessToken: string = "";

let exampleFolder: string = "./examples";
let imagesFolder: string = "./images";
let documentationHTML: string = "./documentation.html";

async function run(): Promise<void> {
clean();

let documentation: string = `<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<style>${await getStyle()}</style>
<script>
const vscode = acquireVsCodeApi();
function openExample(data) {
vscode.postMessage({
command: "openExample",
data: data
});
}
window.addEventListener("message", event => {
let message = event.data;
if (message.command == "scrollTo") {
location.hash = message.anchor;
}
});
</script>
</head>
<body>
${md.render(await getContent()).replace(/(<br\s*\/?>[\n\t\s]*){2,}/gi, "<br />")}
</body>
</html>`;

if (documentation) {
fs.writeFile(documentationHTML, documentation, (err) => {
if (err) {
return console.log(err);
}

console.log("The file was saved!");
});
}
}

function clean(): void {
let deleteFolderRecursive = (path: string) => {
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach((file: string) => {
let currentPath: string = `${path}/${file}`;

if (fs.lstatSync(currentPath).isDirectory()) {
deleteFolderRecursive(currentPath);
}
else {
fs.unlinkSync(currentPath);
}
});

fs.rmdirSync(path);
}
};

if (fs.existsSync(exampleFolder) && fs.statSync(exampleFolder).isDirectory()) {
deleteFolderRecursive(exampleFolder);
}

if (fs.existsSync(imagesFolder) && fs.statSync(imagesFolder).isDirectory()) {
deleteFolderRecursive(imagesFolder);
}

if (fs.existsSync(documentationHTML) && fs.statSync(documentationHTML).isFile()) {
fs.unlinkSync(documentationHTML);
}

fs.mkdirSync(exampleFolder);
fs.mkdirSync(imagesFolder);
}

async function getContent(): Promise<string> {
let docs: string[] = [
"https://api.github.com/repos/mjmlio/mjml/contents/doc/guide.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/getting_started.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/basic.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/components.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/head_components.md",
"mjml-head-attributes/README.md",
"mjml-head-breakpoint/README.md",
"mjml-head-font/README.md",
"mjml-head-preview/README.md",
"mjml-head-style/README.md",
"mjml-head-title/README.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/body_components.md",
"mjml-accordion/README.md",
"mjml-body/README.md",
"mjml-button/README.md",
"mjml-carousel/README.md",
"mjml-column/README.md",
"mjml-divider/README.md",
"mjml-group/README.md",
"mjml-hero/README.md",
"mjml-image/README.md",
"mjml-navbar/README.md",
"mjml-raw/README.md",
"mjml-section/README.md",
"mjml-social/README.md",
"mjml-spacer/README.md",
"mjml-table/README.md",
"mjml-text/README.md",
"mjml-wrapper/README.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/community-components.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/mjml-chart.md",
"https://api.github.com/repos/mjmlio/mjml/contents/doc/create.md"
];

let content: string = "";

for (let i in docs) {
if (docs[i].indexOf("api.github.com") !== -1) {
content += await fetchFromGithub(docs[i]);
}
else {
let mdFile: string = path.join("../", "node_modules", docs[i]);

if (mdFile && fs.existsSync(mdFile) && fs.statSync(mdFile).isFile()) {
content += fs.readFileSync(mdFile, "utf8");
}
}

content += "\n\n";
}

return await tryItLive(
await getImages(
content.replace(/---[\s\S]*?---/, "").replace(/^\s+|\s+$/g, "")
)
);
}

async function getImages(content: string): Promise<string> {
let imagePath: string[] = [];
let pattern: RegExp = /<img\s+[^>]*?src=("|')([^"']+)\1/g;

let match: RegExpMatchArray;
while (match = pattern.exec(content)) {
if (imagePath.indexOf(match[2]) == -1) {
imagePath.push(match[2]);

let res = await fetch(match[2]);

await new Promise((resolve, reject) => {
const fileStream = fs.createWriteStream(`./images/${path.basename(match[2])}`);

res.body.pipe(fileStream);

res.body.on("error", (err) => {
reject(err);
});

fileStream.on("finish", () => {
resolve();
});
});
}
}

return content.replace(/src=['"]((?:[^"'\/]*\/)*([^'"]+))['"]/gi, "src=\"{{root}}/images/$2\"");
}

async function getStyle(): Promise<string> {
let css: string = "";
let previewStyles: string[] = [
"https://api.github.com/repos/Microsoft/vscode/contents/extensions/markdown-language-features/media/markdown.css",
"https://api.github.com/repos/Microsoft/vscode/contents/extensions/markdown-language-features/media/highlight.css"
];

for (let i in previewStyles) {
css += await fetchFromGithub(previewStyles[i]);
}

return css.replace(/\/\*(?:(?!\*\/)[\s\S])*\*\/|[\r\n\t]+/g, "").replace(/ {2,}/g, " ").replace(/ ([{:}]) /g, "$1").replace(/([;,]) /g, "$1").replace(/ !/g, "!");
}

async function fetchFromGithub(url: string): Promise<string> {
let response = await fetch(`${url}?access_token=${githubAccessToken}`);
let json = await response.json();

if (json.content && json.encoding == "base64") {
return new Buffer(json.content, "base64").toString();
}

return "";
}

async function tryItLive(html: string): Promise<string> {
let tryItLive: string[] = [];

html = html.replace(/href=\"\/try-it-live\//gi, "href=\"https:\/\/mjml.io/try-it-live/");

let match;
while (match = /<a[^>]*?href\s*=\s*['"](https?:\/\/mjml\.io\/try-it-live\/([^"']*?))['"][^>]*?>/gi.exec(html)) {
let fileName: string = match[2].replace(/\//g, "-");

if (tryItLive.indexOf(match[2]) == -1) {
let response = await fetch(match[1]);

let mjmlMatch = /"value":*?["']([\s\S]*?)["']*?}/gi.exec(await response.text());

mjmlMatch[1].replace(/\\"/g, "\"").replace(/src="\/(assets\/img)\/(.*?)"/gi, "src=\"https://mjml.io/assets/img/$2\"").split("\\n").forEach((line) => {
fs.appendFileSync(`./examples/${fileName}.mjml`, line.replace(/\\/g, "").toString() + "\n");
});

tryItLive.push(match[2]);
}

html = html.replace(`href="${match[1]}"`, `href="javascript:void(0)" onclick="openExample('${fileName}')" title="${fileName.replace(/components-/gi, "")}"`);
}

return html;
}

run();
14 changes: 14 additions & 0 deletions documentation/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"lib": [
"es6"
],
"sourceMap": true
},
"exclude": [
"node_modules",
"src"
]
}
Loading

0 comments on commit 7982146

Please sign in to comment.