diff --git a/eleventy.config.js b/eleventy.config.js index 19e0f45ff..ac02ecbc1 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -25,7 +25,6 @@ export default async function(eleventyConfig) { templateFormats: [ 'md', 'njk', - '11ty.js', ], }; }; diff --git a/src/eleventy-config/filters.js b/src/eleventy-config/filters.js index f4c5800ed..071e7fe28 100644 --- a/src/eleventy-config/filters.js +++ b/src/eleventy-config/filters.js @@ -1,6 +1,7 @@ import hyphenLibRu from 'hyphen/ru/index.js'; import markdownIt from 'markdown-it'; import htmlmin from 'html-minifier-terser'; +import { stripHeadings, stripLists } from '../libs/markdown-transforms.js'; const markdown = markdownIt({ html: true, @@ -61,12 +62,33 @@ export default function(eleventyConfig) { return markdown.renderInline(value); }); - eleventyConfig.addFilter('htmlmin', (value) => { - return htmlmin.minify( + eleventyConfig.addFilter('htmlmin', async(value) => { + return await htmlmin.minify( value, { collapseWhitespace: true, removeEmptyElements: true, } ); }); + + eleventyConfig.addFilter('duration', (time) => { + // если длительность берётся из json-файла, то она задана в миллисекундах + if (typeof time === 'number') { + return Math.round(time / 1000); + } + + return time.split(':').reduceRight((acc, item, index, items) => { + return acc += parseFloat(item) * Math.pow(60, items.length - 1 - index); + }, 0); + }); + + const podcastMarkdown = markdownIt({ + html: true, + }) + .use(stripHeadings) + .use(stripLists); + + eleventyConfig.addFilter('podcastMarkdown', (content) => { + return podcastMarkdown.render(content); + }); }; diff --git a/src/libs/markdown-transforms.js b/src/libs/markdown-transforms.js new file mode 100644 index 000000000..999773c24 --- /dev/null +++ b/src/libs/markdown-transforms.js @@ -0,0 +1,62 @@ +function stripHeadings(md) { + md.core.ruler.push('strip_headings', (state) => { + state.tokens.forEach((token) => { + if (token.type === 'heading_open') { + token.tag = 'p'; + token.type = 'paragraph_open'; + } + + if (token.type === 'heading_close') { + token.tag = 'p'; + token.type = 'paragraph_close'; + } + }); + }); +} + +function stripLists(md) { + md.core.ruler.push('strip_lists', (state) => { + let newTokens = []; + let isListItemProcessing = false; + + state.tokens.forEach((token) => { + if (token.type === 'bullet_list_open') { + const listOpenToken = new state.Token('html_paragraph', 'p', 1); + newTokens.push(listOpenToken); + return; + } + + if (token.type === 'bullet_list_close') { + const listCloseToken = new state.Token('html_paragraph', 'p', -1); + newTokens.push(listCloseToken); + return; + } + + if (token.type === 'list_item_open') { + isListItemProcessing = true; + return; + } + + if (token.type === 'list_item_close') { + isListItemProcessing = false; + return; + } + + if (token.type === 'inline' && isListItemProcessing) { + const bulletToken = new state.Token('html_inline', '', 0); + bulletToken.content = '• '; + token.children.unshift(bulletToken); + + const breakToken = new state.Token('html_inline', '', 0); + breakToken.content = '
'; + token.children.push(breakToken); + } + + newTokens.push(token); + }); + + state.tokens = newTokens; + }); +} + +export { stripHeadings, stripLists }; diff --git a/src/pages/podcast/feed.11ty.js b/src/pages/podcast/feed.11ty.js deleted file mode 100644 index c2cf4e282..000000000 --- a/src/pages/podcast/feed.11ty.js +++ /dev/null @@ -1,105 +0,0 @@ -export default { - data: { - permalink: '/podcast/feed/index.xml', - }, - - duration(time) { - // если длительность берётся из json-файла, то она задана в миллисекундах - if (typeof time === 'number') { - return Math.round(time / 1000); - } - - return time.split(':').reduceRight((acc, item, index, items) => { - return acc += parseFloat(item) * Math.pow(60, items.length - 1 - index); - }, 0); - }, - - async getEpisodes(data) { - const { episodes } = data.collections; - - const result = await Promise.all( - episodes.map(async(episode) => { - const hosts = episode.data.hosts.join(', '); - return ` - - ${episode.fileSlug}. ${episode.data.title} - ${data.podcast.url}${episode.fileSlug}/ - ${episode.date.toUTCString()} - Ведущие -

${hosts}

- ${episode.data.chapters - ? `

Темы

` - : '' - } - ${await this.htmlmin(episode.content)} - ]]>
- ${data.podcast.url}episodes/${episode.fileSlug}.mp3 - - ${episode.fileSlug} - ${this.duration(episode.data.duration)} - ${hosts} - ${data.podcast.explicit} - ${this.ruDate(episode.date)}: ${episode.data.title}. ${hosts} - -
- `; - }) - ); - - return result.join(''); - }, - - async render(data) { - return ` - - - - ${data.podcast.title} - - ${data.podcast.copyright} - ${data.podcast.language} - ${data.podcast.url} - - - - ${data.podcast.subtitle} - ${data.podcast.type} - ${data.podcast.author} - ${data.podcast.explicit} - - ${data.podcast.owner.name} - ${data.podcast.owner.email} - - - - ${data.podcast.categories - .map( - (category) => - `${ - category.items - ? category.items - .map((category) => ``) - .join('') - : '' - }` - ) - .join('')} - - ${await this.getEpisodes(data)} - - - `; - }, -}; diff --git a/src/pages/podcast/feed.njk b/src/pages/podcast/feed.njk new file mode 100644 index 000000000..9a62ac5ff --- /dev/null +++ b/src/pages/podcast/feed.njk @@ -0,0 +1,75 @@ +--- +permalink: /podcast/feed/index.xml +--- + + + + + {{podcast.title}} + + {{podcast.copyright}} + {{podcast.language}} + {{podcast.url}} + + + + {{podcast.subtitle}} + {{podcast.type}} + {{podcast.author}} + {{podcast.explicit}} + + {{podcast.owner.name}} + {{podcast.owner.email}} + + + + {% for category in podcast.categories %} + + {% for categoryItem in category.items %} + + {% endfor %} + + {% endfor %} + + {% for episode in collections.episodes | reverse %} + {% set hosts = episode.data.hosts | join(', ') %} + + {{episode.fileSlug}}. {{episode.data.title}} + {{podcast.url}}{{episode.fileSlug}}/ + {{episode.date.toUTCString()}} + {% set hostsAndChaptersBlock %} +

Ведущие: {{hosts}}

+ {% if episode.data.chapters.length > 0 %} +

Темы

+

+ {% for chapter in episode.data.chapters %} + {{chapter.time}} {{chapter.title}}{% if not loop.last %}
{% endif %} + {% endfor %} +

+ {% endif %} + {% endset %} + + {{podcast.url}}episodes/{{episode.fileSlug}}.mp3 + + {{episode.fileSlug}} + {{episode.data.duration | duration}} + {{hosts}} + {{podcast.explicit}} + {{episode.date | ruDate}}: {{episode.data.title}}. {{hosts}} + +
+ {% endfor %} +
+