80 lines
1.9 KiB
TypeScript
80 lines
1.9 KiB
TypeScript
export interface PromptPart {
|
|
id: string;
|
|
content: string;
|
|
isPlaceholder?: boolean;
|
|
}
|
|
|
|
|
|
export interface ParsedQuestion {
|
|
id: string;
|
|
parts: PromptPart[];
|
|
editingPlaceholders: boolean;
|
|
}
|
|
|
|
const parseLine = (line: string): PromptPart[] => {
|
|
const parts: PromptPart[] = [];
|
|
let lastIndex = 0;
|
|
const regex = /{{(\d+)}}/g;
|
|
let match;
|
|
|
|
while ((match = regex.exec(line)) !== null) {
|
|
if (match.index > lastIndex) {
|
|
const textBefore = line.slice(lastIndex, match.index);
|
|
const words = textBefore.split(/(\s+)/).filter(Boolean);
|
|
words.forEach(word => {
|
|
parts.push({
|
|
id: `text-${Date.now()}-${parts.length}`,
|
|
content: word
|
|
});
|
|
});
|
|
}
|
|
|
|
const placeholderId = match[1];
|
|
parts.push({
|
|
id: placeholderId,
|
|
content: match[0],
|
|
isPlaceholder: true
|
|
});
|
|
|
|
lastIndex = match.index + match[0].length;
|
|
}
|
|
|
|
if (lastIndex < line.length) {
|
|
const textAfter = line.slice(lastIndex);
|
|
const words = textAfter.split(/(\s+)/).filter(Boolean);
|
|
words.forEach(word => {
|
|
parts.push({
|
|
id: `text-${Date.now()}-${parts.length}`,
|
|
content: word
|
|
});
|
|
});
|
|
}
|
|
|
|
return parts;
|
|
};
|
|
|
|
const reconstructLine = (parts: PromptPart[]): string => {
|
|
const text = parts
|
|
.map(part => part.content)
|
|
.join(' ')
|
|
.replace(/\s+/g, ' ')
|
|
.trim();
|
|
return text;
|
|
};
|
|
|
|
|
|
const formatDisplayContent = (content: string): string => {
|
|
return content.replace(/{{(\d+)}}/g, '[$1]');
|
|
};
|
|
|
|
const formatStorageContent = (content: string): string => {
|
|
return content.replace(/\[(\d+)\]/g, '{{$1}}');
|
|
};
|
|
|
|
export {
|
|
parseLine,
|
|
reconstructLine,
|
|
formatDisplayContent,
|
|
formatStorageContent
|
|
}
|