| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- interface PathParts {
- readonly headingSlashes: string;
- readonly content: string;
- readonly trailingSlashes: string;
- readonly hasHeadingSlash: boolean;
- readonly hasTrailingSlash: boolean;
- }
- function parsePath(path: string): PathParts | null {
- if (typeof path !== 'string' || !path || path === '') return null;
- // Special case for root path
- if (path === '/') {
- return {
- headingSlashes: '/',
- content: '',
- trailingSlashes: '',
- hasHeadingSlash: true,
- hasTrailingSlash: true,
- };
- }
- let startIndex = 0;
- let endIndex = path.length;
- // Find leading slashes
- while (startIndex < path.length && path[startIndex] === '/') {
- startIndex++;
- }
- // Find trailing slashes
- while (endIndex > startIndex && path[endIndex - 1] === '/') {
- endIndex--;
- }
- const headingSlashes = path.substring(0, startIndex);
- const content = path.substring(startIndex, endIndex);
- const trailingSlashes = path.substring(endIndex);
- return {
- headingSlashes,
- content,
- trailingSlashes,
- hasHeadingSlash: headingSlashes.length > 0,
- hasTrailingSlash: trailingSlashes.length > 0,
- };
- }
- export function hasHeadingSlash(path: string): boolean {
- if (path === '/') return true;
- const parts = parsePath(path);
- return parts?.hasHeadingSlash ?? false;
- }
- export function hasTrailingSlash(path: string): boolean {
- if (path === '/') return true;
- const parts = parsePath(path);
- return parts?.hasTrailingSlash ?? false;
- }
- export function addHeadingSlash(path: string): string {
- if (path === '/') return path;
- if (path === '') return '/';
- const parts = parsePath(path);
- if (!parts?.hasHeadingSlash) {
- return `/${path}`;
- }
- return path;
- }
- export function addTrailingSlash(path: string): string {
- if (path === '/') return path;
- if (path === '') return '/';
- const parts = parsePath(path);
- if (!parts?.hasTrailingSlash) {
- return `${path}/`;
- }
- return path;
- }
- export function removeHeadingSlash(path: string): string {
- if (path === '/') return path;
- if (path === '') return path;
- const parts = parsePath(path);
- if (!parts?.hasHeadingSlash) return path;
- // Special case for '//' -> '/'
- if (path === '//') return '/';
- // Remove heading slashes and return content + trailing slashes
- return parts.content + parts.trailingSlashes;
- }
- export function removeTrailingSlash(path: string): string {
- if (path === '/') return path;
- if (path === '') return path;
- const parts = parsePath(path);
- if (parts == null) return path;
- // Return heading slashes + content (without trailing slashes)
- return parts.headingSlashes + parts.content;
- }
- /**
- * A short-hand method to add heading slash and remove trailing slash.
- */
- export function normalizePath(path: string): string {
- if (typeof path !== 'string' || path === '' || path === '/') {
- return '/';
- }
- const parts = parsePath(path);
- if (parts == null) {
- return '/';
- }
- return `/${parts.content}`;
- }
- export function attachTitleHeader(path: string): string {
- return `# ${path}`;
- }
- /**
- * If the pagePath is top page path, eliminate the pageId from the url path.
- */
- export function returnPathForURL(path: string, id: string): string {
- if (path === '/') {
- return path;
- }
- return addHeadingSlash(id);
- }
- /**
- * Get the parent path of the specified path.
- */
- export function getParentPath(path: string): string {
- return normalizePath(path.split('/').slice(0, -1).join('/'));
- }
|