import { getCollection } from "astro:content";
import { slug } from "github-slugger";
import slugify from "slugify";
export const customSlugify = (content) => {
if (!content) return null;
// ΠΡΠΎΠ²Π΅ΡΠΊΠ°, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π»ΠΈ ΡΡΡΠΎΠΊΠ° ΡΡΡΡΠΊΠΈΠ΅ ΡΠΈΠΌΠ²ΠΎΠ»Ρ
const isRussian = /[Π°-ΡΠ-Π―ΠΡ]/.test(content);
if (isRussian) {
// ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ slugify Π΄Π»Ρ ΡΡΡΡΠΊΠΈΡ
ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ²
return slugify(content, { lower: true, strict: true, locale: "ru" });
} else {
// ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ slug Π΄Π»Ρ Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΈΡ
ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ²
return slug(content);
}
};
// Π€ΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΡ ΡΡΡΠΎΠΊΠΈ Π² slug
// export const slugify = (content) => {
// if (!content) return null;
// return slug(content);
// };
// Π€ΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΡΠ°Π½ΠΈΡ, ΠΈΡΠΊΠ»ΡΡΠ°Ρ ΡΠ΅ΡΠ½ΠΎΠ²ΠΈΠΊΠΈ ΠΈ ΡΡΡΠ°Π½ΠΈΡΡ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΌΠΈ ID
export const getSinglePage = async (collection) => {
const allPage = await getCollection(collection);
const removeIndex = allPage.filter((data) => data.id.match(/^(?!-)/));
const removeDrafts = removeIndex.filter((data) => !data.data.draft);
return removeDrafts;
};
// Π€ΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π²ΡΠ΅Ρ
ΡΠ°ΠΊΡΠΎΠ½ΠΎΠΌΠΈΠΉ
export const getTaxonomy = async (collection, name) => {
const singlePages = await getSinglePage(collection);
const taxonomyPages = singlePages.map((page) => page.data[name]);
let taxonomies = [];
for (let i = 0; i < taxonomyPages.length; i++) {
const categoryArray = taxonomyPages[i];
for (let j = 0; j < categoryArray.length; j++) {
// customSlugify <-> slugify
taxonomies.push(customSlugify(categoryArray[j])); // ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ customSlugify Π·Π΄Π΅ΡΡ
}
}
const taxonomy = [...new Set(taxonomies)];
return taxonomy;
};
ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ΅Ρ Markdown-ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ Π² HTML. ΠΡΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° Π½ΡΠΆΠ½ΠΎ ΠΎΡΠΎΠ±ΡΠ°Π·ΠΈΡΡ ΡΠ΅ΠΊΡΡ, Π½Π°ΠΏΠΈΡΠ°Π½Π½ΡΠΉ Π² Markdown, Π² Π²ΠΈΠ΄Π΅ HTML Π½Π° Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΠ΅.
export const markdownify = (content: string) => {
if (!content) return null;
return marked.parseInline(content);
};
const markdownText = "# ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ\nΠΡΠΎ *ΠΊΡΡΡΠΈΠ²* ΠΈ ΡΡΠΎ **ΠΆΠΈΡΠ½ΡΠΉ** ΡΠ΅ΠΊΡΡ.";
const htmlContent = markdownify(markdownText);
// Π Π΅Π·ΡΠ»ΡΡΠ°Ρ: "<h1>ΠΠ°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ</h1><p>ΠΡΠΎ <em>ΠΊΡΡΡΠΈΠ²</em> ΠΈ ΡΡΠΎ <strong>ΠΆΠΈΡΠ½ΡΠΉ</strong> ΡΠ΅ΠΊΡΡ.</p>"
ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ΅Ρ ΡΡΡΠΎΠΊΡ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡ ΠΏΠΎΠ΄ΡΠ΅ΡΠΊΠΈΠ²Π°Π½ΠΈΡ ΠΈΠ»ΠΈ ΠΏΡΠΎΠ±Π΅Π»Ρ, Π² ΡΠΈΡΠ°Π΅ΠΌΡΠΉ Π²ΠΈΠ΄, Π΄Π΅Π»Π°Ρ ΠΏΠ΅ΡΠ²ΡΡ Π±ΡΠΊΠ²Ρ Π·Π°Π³Π»Π°Π²Π½ΠΎΠΉ. ΠΡΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠ² ΠΈΠ»ΠΈ ΠΊΠΎΠ΄ΠΎΠ²ΡΡ ΠΈΠΌΠ΅Π½ Π² Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ½ΡΡΠ½ΠΎΠΉ ΡΠΎΡΠΌΠ΅.
// humanize
export const humanize = (content: string) => {
if (!content) return null;
return content
.replace(/^[\s_]+|[\s_]+$/g, "")
.replace(/[_\s]+/g, " ")
.replace(/^[a-z]/, function (m) {
return m.toUpperCase();
});
};
const codeName = "hello_world_example";
const humanizedName = humanize(codeName);
// Π Π΅Π·ΡΠ»ΡΡΠ°Ρ: "Hello world example"
plainify & htmlEntityDecoder: Π£Π΄Π°Π»ΡΡΡ HTML-ΡΠ΅Π³ΠΈ ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΡΡ HTML-ΡΡΡΠ½ΠΎΡΡΠΈ, ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Ρ HTML-ΠΊΠΎΠ½ΡΠ΅Π½Ρ Π² ΠΎΠ±ΡΡΠ½ΡΠΉ ΡΠ΅ΠΊΡΡ. ΠΡΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, Π΅ΡΠ»ΠΈ Π²Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΈΠ·Π²Π»Π΅ΡΡ ΡΠΈΡΡΡΠΉ ΡΠ΅ΠΊΡΡ ΠΈΠ· HTML, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΎΡΠ΅ ΠΈΠ»ΠΈ Π΄Π»Ρ Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ.
// plainify
export const plainify = (content: string) => {
if (!content) return null;
const filterBrackets = content.replace(/<\/?[^>]+(>|$)/gm, "");
const filterSpaces = filterBrackets.replace(/[\r\n]\s*[\r\n]/gm, "");
const stripHTML = htmlEntityDecoder(filterSpaces);
return stripHTML;
};
// strip entities for plainify
const htmlEntityDecoder = (htmlWithEntities: string): string => {
let entityList: { [key: string]: string } = {
" ": " ",
"<": "<",
">": ">",
"&": "&",
""": '"',
"'": "'",
};
let htmlWithoutEntities: string = htmlWithEntities.replace(
/(&|<|>|"|')/g,
(entity: string): string => {
return entityList[entity];
}
);
return htmlWithoutEntities;
};
const htmlContent = "<p>Hello <b>World</b> & everyone!</p>";
const plainText = plainify(htmlContent);
// Π Π΅Π·ΡΠ»ΡΡΠ°Ρ: "Hello World & everyone!"
// content reading
const readingTime = (content: string) => {
const WPS = 275 / 60;
let images = 0;
const regex = /\w/;
let words = content.split(" ").filter((word) => {
if (word.includes("<img")) {
images += 1;
}
return regex.test(word);
}).length;
let imageAdjust = images * 4;
let imageSecs = 0;
let imageFactor = 12;
while (images) {
imageSecs += imageFactor;
if (imageFactor > 3) {
imageFactor -= 1;
}
images -= 1;
}
const minutes = Math.ceil(((words - imageAdjust) / WPS + imageSecs) / 60);
if (minutes < 10) {
if (minutes < 2) {
return "0" + minutes + ` Min read`;
} else {
return "0" + minutes + ` Mins read`;
}
} else {
return minutes + ` Mins read`;
}
};
export default readingTime;