A CLI for publishing standard.site documents to ATProto

feat: add stripDatePrefix option for Jekyll-style filenames

Adds a new `stripDatePrefix` configuration option that removes
YYYY-MM-DD- prefixes from filenames when deriving slugs. This
supports Jekyll-style post naming where files like
`2024-01-15-my-post.md` should produce slug `my-post`.

authored by xx-c.tngl.sh and committed by tangled.org 45d74d99 2a742692

+18 -1
+1
packages/cli/src/commands/publish.ts
··· 110 110 ignorePatterns: config.ignore, 111 111 slugField: config.frontmatter?.slugField, 112 112 removeIndexFromSlug: config.removeIndexFromSlug, 113 + stripDatePrefix: config.stripDatePrefix, 113 114 }); 114 115 s.stop(`Found ${posts.length} posts`); 115 116
+1
packages/cli/src/commands/sync.ts
··· 105 105 ignorePatterns: config.ignore, 106 106 slugField: config.frontmatter?.slugField, 107 107 removeIndexFromSlug: config.removeIndexFromSlug, 108 + stripDatePrefix: config.stripDatePrefix, 108 109 }); 109 110 s.stop(`Found ${localPosts.length} local posts`); 110 111
+5
packages/cli/src/lib/config.ts
··· 82 82 frontmatter?: FrontmatterMapping; 83 83 ignore?: string[]; 84 84 removeIndexFromSlug?: boolean; 85 + stripDatePrefix?: boolean; 85 86 textContentField?: string; 86 87 bluesky?: BlueskyConfig; 87 88 }): string { ··· 122 123 123 124 if (options.removeIndexFromSlug) { 124 125 config.removeIndexFromSlug = options.removeIndexFromSlug; 126 + } 127 + 128 + if (options.stripDatePrefix) { 129 + config.stripDatePrefix = options.stripDatePrefix; 125 130 } 126 131 127 132 if (options.textContentField) {
+10 -1
packages/cli/src/lib/markdown.ts
··· 178 178 export interface SlugOptions { 179 179 slugField?: string; 180 180 removeIndexFromSlug?: boolean; 181 + stripDatePrefix?: boolean; 181 182 } 182 183 183 184 export function getSlugFromOptions( ··· 185 186 rawFrontmatter: Record<string, unknown>, 186 187 options: SlugOptions = {}, 187 188 ): string { 188 - const { slugField, removeIndexFromSlug = false } = options; 189 + const { slugField, removeIndexFromSlug = false, stripDatePrefix = false } = options; 189 190 190 191 let slug: string; 191 192 ··· 218 219 slug = slug.replace(/\/_?index$/, ""); 219 220 } 220 221 222 + // Strip Jekyll-style date prefix (YYYY-MM-DD-) from filename 223 + if (stripDatePrefix) { 224 + slug = slug.replace(/(^|\/)(\d{4}-\d{2}-\d{2})-/g, "$1"); 225 + } 226 + 221 227 return slug; 222 228 } 223 229 ··· 243 249 ignorePatterns?: string[]; 244 250 slugField?: string; 245 251 removeIndexFromSlug?: boolean; 252 + stripDatePrefix?: boolean; 246 253 } 247 254 248 255 export async function scanContentDirectory( ··· 274 281 ignorePatterns: ignore = [], 275 282 slugField, 276 283 removeIndexFromSlug, 284 + stripDatePrefix, 277 285 } = options; 278 286 279 287 const patterns = ["**/*.md", "**/*.mdx"]; ··· 302 310 const slug = getSlugFromOptions(relativePath, rawFrontmatter, { 303 311 slugField, 304 312 removeIndexFromSlug, 313 + stripDatePrefix, 305 314 }); 306 315 307 316 posts.push({
+1
packages/cli/src/lib/types.ts
··· 33 33 frontmatter?: FrontmatterMapping; // Custom frontmatter field mappings 34 34 ignore?: string[]; // Glob patterns for files to ignore (e.g., ["_index.md", "**/drafts/**"]) 35 35 removeIndexFromSlug?: boolean; // Remove "/index" or "/_index" suffix from paths (default: false) 36 + stripDatePrefix?: boolean; // Remove YYYY-MM-DD- prefix from filenames (Jekyll-style, default: false) 36 37 textContentField?: string; // Frontmatter field to use for textContent instead of markdown body 37 38 bluesky?: BlueskyConfig; // Optional Bluesky posting configuration 38 39 }