A comprehensive collection of utility functions for markdown processing, metadata extraction, content parsing, and validation. Built with TypeScript for excellent developer experience and type safety.
- 📅 Date Utilities - Extract creation/update dates from markdown content
- 📝 Content Parsing - Extract headings, paragraphs, links, images, and code blocks
- 🔧 Path Utilities - Handle file paths, slugs, and directory operations
- ✅ Validation - Validate markdown syntax, links, images, and tables
- 🎯 TypeScript Support - Full type definitions included
- 🌳 Tree Shakable - Import only what you need
- 📦 Multiple Formats - ESM and CommonJS support
• 👉 View live demo at: @asafarim/markdown-utils Demo
npm install @asafarim/markdown-utils
yarn add @asafarim/markdown-utils
pnpm add @asafarim/markdown-utils
import {
getFirstHeading,
getCreationDate,
stripMarkdown,
validateMarkdown
} from '@asafarim/markdown-utils';
const content = `
# My Document
Created: 2024-12-07
**Bold text** and *italic text*.
`;
// Extract heading
const title = getFirstHeading(content); // "My Document"
// Extract date
const created = getCreationDate(content); // Date object
// Get plain text
const plainText = stripMarkdown(content); // Clean text without markdown
// Validate content
const validation = validateMarkdown(content);
console.log(validation.isValid); // true
import markdownUtils from '@asafarim/markdown-utils';
// Use grouped utilities
const title = markdownUtils.content.getFirstHeading(content);
const created = markdownUtils.date.getCreationDate(content);
const isValid = markdownUtils.validation.isValidMarkdown(content);
Extract and work with dates from markdown content:
import {
getCreationDate,
getUpdateDate,
formatDate,
getTimeAgo
} from '@asafarim/markdown-utils';
// Extract dates from various patterns
const created = getCreationDate('Date: 2024-12-07');
const updated = getUpdateDate('Updated: December 8, 2024');
// Format dates
const formatted = formatDate(new Date()); // "Dec 7, 2024"
const timeAgo = getTimeAgo(new Date(Date.now() - 86400000)); // "1 day ago"
Parse and extract content from markdown:
import {
getFirstHeading,
getAllHeadings,
extractLinks,
extractImages,
getWordCount,
getReadingTime
} from '@asafarim/markdown-utils';
const content = `
# Main Title
## Subtitle
Check out [my website](https://example.com) and this .
`;
const title = getFirstHeading(content); // "Main Title"
const headings = getAllHeadings(content); // Array of heading objects
const links = extractLinks(content); // Array of link objects
const images = extractImages(content); // Array of image objects
const wordCount = getWordCount(content); // Number of words
const readingTime = getReadingTime(content); // Estimated minutes
Handle file paths and create slugs:
import {
getFileNameWithoutExtension,
filenameToSlug,
filenameToTitle,
extractDateFromPath
} from '@asafarim/markdown-utils';
const filename = getFileNameWithoutExtension('/docs/my-file.md'); // "my-file"
const slug = filenameToSlug('My Great Article!'); // "my-great-article"
const title = filenameToTitle('my-great-article'); // "My Great Article"
const date = extractDateFromPath('2024-12-07-article.md'); // Date object
Validate markdown content and syntax:
import {
validateMarkdown,
validateMarkdownLinks,
isValidMarkdown
} from '@asafarim/markdown-utils';
const content = `# Title\n[Link](https://example.com)`;
const validation = validateMarkdown(content);
console.log(validation.isValid); // true
console.log(validation.stats); // { wordCount: 2, headingCount: 1, ... }
const linkValidation = validateMarkdownLinks(content);
console.log(linkValidation[0].isValid); // true
import { getFirstHeading, getCreationDate, getReadingTime } from '@asafarim/markdown-utils';
function processMarkdownPost(content: string) {
return {
title: getFirstHeading(content),
publishedAt: getCreationDate(content),
readingTime: getReadingTime(content),
wordCount: getWordCount(content)
};
}
import { extractDateFromPath, filenameToSlug } from '@asafarim/markdown-utils';
function processMarkdownFiles(filePaths: string[]) {
return filePaths.map(path => ({
slug: filenameToSlug(path),
date: extractDateFromPath(path),
path
}));
}
import { validateMarkdown } from '@asafarim/markdown-utils';
function validateContent(content: string) {
const result = validateMarkdown(content);
if (!result.isValid) {
console.error('Validation errors:', result.errors);
}
if (result.warnings.length > 0) {
console.warn('Warnings:', result.warnings);
}
return result;
}
# Clone the repository
git clone https://github.com/AliSafari-IT/asafarim.git
cd asafarim/ASafariM.Clients/packages/markdown-utils
# Install dependencies
pnpm install
# Run tests
pnpm test
# Run tests with coverage
pnpm test:coverage
# Build the package
pnpm build
# Run linting
pnpm lint
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with TypeScript
- Bundled with tsup
- Tested with Vitest
- 📧 Email: asafarim@gmail.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
Made with ❤️ by Ali Safari