const assert = require('assert'); const htmlToPlaintext = require('../'); describe('Html to Plaintext', function () { function getEmailandExcert(input) { const excerpt = htmlToPlaintext.excerpt(input); const email = htmlToPlaintext.email(input); return {email, excerpt}; } describe('excerpt vs email behavior', function () { it('example case with img & link', function () { const input = '

Some thing Google once told me.

An important image

And another thing.

'; const {excerpt, email} = getEmailandExcert(input); assert.equal(excerpt, 'Some thing Google once told me.\n\nAnd another thing.'); assert.equal(email, 'Some thing Google [https://google.com] once told me.\n\nAnd another thing.'); }); it('example case with figure + figcaption', function () { const input = '
A snippet from a post template

See? Not that scary! But still completely optional.

'; const {excerpt, email} = getEmailandExcert(input); assert.equal(excerpt, 'See? Not that scary! But still completely optional.'); assert.equal(email, 'A snippet from a post template\n\nSee? Not that scary! But still completely optional.'); }); it('example case with figure + figcaption inside a link', function () { const input = '
A snippet from a post template

See? Not that scary! But still completely optional.

'; const {excerpt, email} = getEmailandExcert(input); assert.equal(excerpt, 'See? Not that scary! But still completely optional.'); assert.equal(email, 'A snippet from a post template [https://mysite.com]\n\nSee? Not that scary! But still completely optional.'); }); it('longer example', function () { const input = '

As discussed in the introduction post, one of the best things about Ghost is just how much you can customize to turn your site into something unique. Everything about your layout and design can be changed, so you\'re not stuck with yet another clone of a social network profile.

How far you want to go with customization is completely up to you, there\'s no right or wrong approach! The majority of people use one of Ghost\'s built-in themes to get started, and then progress to something more bespoke later on as their site grows.

The best way to get started is with Ghost\'s branding settings, where you can set up colors, images and logos to fit with your brand.

Ghost Admin → Settings → Branding

Any Ghost theme that\'s up to date and compatible with Ghost 4.0 and higher will reflect your branding settings in the preview window, so you can see what your site will look like as you experiment with different options.

When selecting an accent color, try to choose something which will contrast well with white text. Many themes will use your accent color as the background for buttons, headers and navigational elements. Vibrant colors with a darker hue tend to work best, as a general rule.

Installing Ghost themes

By default, new sites are created with Ghost\'s friendly publication theme, called Casper. Everything in Casper is optimized to work for the most common types of blog, newsletter and publication that people create with Ghost — so it\'s a perfect place to start.

However, there are hundreds of different themes available to install, so you can pick out a look and feel that suits you best.

Ghost Admin → Settings → Theme

Inside Ghost\'s theme settings you\'ll find 4 more official themes that can be directly installed and activated. Each theme is suited to slightly different use-cases.

And if none of those feel quite right, head on over to the Ghost Marketplace, where you\'ll find a huge variety of both free and premium themes.

Building something custom

Finally, if you want something completely bespoke for your site, you can always build a custom theme from scratch and upload it to your site.

Ghost\'s theming template files are very easy to work with, and can be picked up in the space of a few hours by anyone who has just a little bit of knowledge of HTML and CSS. Templates from other platforms can also be ported to Ghost with relatively little effort.

If you want to take a quick look at the theme syntax to see what it\'s like, you can browse through the files of the default Casper theme. We\'ve added tons of inline code comments to make it easy to learn, and the structure is very readable.

{{#post}}\n<article class="article {{post_class}}">\n\n <h1>{{title}}</h1>\n \n {{#if feature_image}}\n \t<img src="{{feature_image}}" alt="Feature image" />\n {{/if}}\n \n {{content}}\n\n</article>\n{{/post}}
A snippet from a post template

See? Not that scary! But still completely optional.

If you\'re interested in creating your own Ghost theme, check out our extensive theme documentation for a full guide to all the different template variables and helpers which are available.

'; const {excerpt, email} = getEmailandExcert(input); // No link assert.doesNotMatch(excerpt, /https:\/\/demo\.ghost\.io\/welcome/); // No figcaption assert.doesNotMatch(excerpt, /Ghost Admin → Settings → Theme/); // contains link assert.match(email, /https:\/\/demo\.ghost\.io\/welcome/); // contains figcaption assert.match(email, /Ghost Admin → Settings → Theme/); }); }); describe('footnotes', function () { it('strips multiple inline footnotes', function () { const html = '

Testing1, my footnotes. And stuff. Footnote2with a link right after.'; const expected = 'Testing, my footnotes. And stuff. Footnotewith a link right after.'; const {excerpt} = getEmailandExcert(html); assert.equal(excerpt, expected); }); it('strips inline and bottom footnotes', function () { const html = '

Testing1 a very short post with a single footnote.

\n' + '
  1. https://ghost.org

'; const expected = 'Testing a very short post with a single footnote.\n'; const {excerpt} = getEmailandExcert(html); assert.equal(excerpt, expected); }); }); describe('Special cases', function () { it('Instagram (blockquotes)', function () { // This is an instagram embed, but with all the style attributes & svg content removed for brevity const html = '

Some text in a paragraph.

View this post on Instagram

A post shared by Some Dude (@somedude)

'; const expected = 'Some text in a paragraph.\n\nView this post on Instagram\n\nA post shared by Some Dude (@somedude)'; const {excerpt} = getEmailandExcert(html); assert.equal(excerpt, expected); }); it('HRs', function () { const html = '

See you later alligator...


...in a while crocodile

'; const expected = 'See you later alligator...\n\n...in a while crocodile'; const {excerpt} = getEmailandExcert(html); assert.equal(excerpt, expected); }); }); });