mirror of
https://github.com/bingryan/obsidian-markdown-export-plugin.git
synced 2026-07-22 07:10:24 +00:00
feat: add export to text (#110)
This commit is contained in:
parent
dece75da08
commit
595eb1f482
3 changed files with 274 additions and 3 deletions
|
|
@ -15,6 +15,7 @@ export const OUTGOING_LINK_REGEXP = /(?<!!)\[\[(.*?)\]\]/g;
|
|||
export enum OUTPUT_FORMATS {
|
||||
MD = "Markdown",
|
||||
HTML = "HTML",
|
||||
TEXT = "Text",
|
||||
}
|
||||
|
||||
export interface MarkdownExportPluginSettings {
|
||||
|
|
@ -30,6 +31,10 @@ export interface MarkdownExportPluginSettings {
|
|||
relAttachPath: boolean;
|
||||
convertWikiLinksToMarkdown: boolean;
|
||||
removeYamlHeader: boolean;
|
||||
// Text export settings
|
||||
textExportBulletPointMap: Record<number, string>;
|
||||
textExportCheckboxUnchecked: string;
|
||||
textExportCheckboxChecked: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: MarkdownExportPluginSettings = {
|
||||
|
|
@ -45,4 +50,14 @@ export const DEFAULT_SETTINGS: MarkdownExportPluginSettings = {
|
|||
relAttachPath: true,
|
||||
convertWikiLinksToMarkdown: false,
|
||||
removeYamlHeader: false,
|
||||
// Text export settings
|
||||
textExportBulletPointMap: {
|
||||
0: "●",
|
||||
4: "○",
|
||||
8: "■",
|
||||
12: "►",
|
||||
16: "•"
|
||||
},
|
||||
textExportCheckboxUnchecked: "☐",
|
||||
textExportCheckboxChecked: "☑"
|
||||
};
|
||||
|
|
|
|||
151
src/main.ts
151
src/main.ts
|
|
@ -46,7 +46,11 @@ export default class MarkdownExportPlugin extends Plugin {
|
|||
})
|
||||
);
|
||||
|
||||
for (const outputFormat of [OUTPUT_FORMATS.MD, OUTPUT_FORMATS.HTML]) {
|
||||
for (const outputFormat of [
|
||||
OUTPUT_FORMATS.MD,
|
||||
OUTPUT_FORMATS.HTML,
|
||||
OUTPUT_FORMATS.TEXT,
|
||||
]) {
|
||||
this.addCommand({
|
||||
id: "export-to-" + outputFormat,
|
||||
name: `Export to ${outputFormat}`,
|
||||
|
|
@ -63,7 +67,11 @@ export default class MarkdownExportPlugin extends Plugin {
|
|||
}
|
||||
|
||||
registerDirMenu(menu: Menu, file: TAbstractFile) {
|
||||
for (const outputFormat of [OUTPUT_FORMATS.MD, OUTPUT_FORMATS.HTML]) {
|
||||
for (const outputFormat of [
|
||||
OUTPUT_FORMATS.MD,
|
||||
OUTPUT_FORMATS.HTML,
|
||||
OUTPUT_FORMATS.TEXT,
|
||||
]) {
|
||||
const addMenuItem = (item: MenuItem) => {
|
||||
item.setTitle(`Export to ${outputFormat}`);
|
||||
item.onClick(async () => {
|
||||
|
|
@ -127,7 +135,13 @@ class MarkdownExportSettingTab extends PluginSettingTab {
|
|||
|
||||
containerEl.empty();
|
||||
|
||||
containerEl.createEl("h2", { text: "Markdown Export" });
|
||||
containerEl.createEl("h1", { text: "Obsidian Markdown Export" });
|
||||
containerEl.createEl("p", { text: "Created by " }).createEl("a", {
|
||||
text: "bingryan 🤓",
|
||||
href: "https://github.com/bingryan",
|
||||
});
|
||||
|
||||
containerEl.createEl("h3", { text: "Baisc Setting" });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Output Path")
|
||||
|
|
@ -292,5 +306,136 @@ class MarkdownExportSettingTab extends PluginSettingTab {
|
|||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
containerEl.createEl("h3", { text: "Export Text Setting" });
|
||||
|
||||
// Bullet point mapping settings
|
||||
containerEl.createEl("h6", { text: "Bullet Point Symbols" });
|
||||
containerEl.createEl("p", {
|
||||
text: "Configure symbols for different indentation levels of bullet points.",
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Level 0 Bullet Point")
|
||||
.setDesc("Symbol for top-level bullet points")
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("●")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportBulletPointMap[0] || "●"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportBulletPointMap[0] =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Level 1 Bullet Point")
|
||||
.setDesc("Symbol for first-level indented bullet points (4 spaces)")
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("○")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportBulletPointMap[4] || "○"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportBulletPointMap[4] =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Level 2 Bullet Point")
|
||||
.setDesc(
|
||||
"Symbol for second-level indented bullet points (8 spaces)"
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("■")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportBulletPointMap[8] || "■"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportBulletPointMap[8] =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Level 3 Bullet Point")
|
||||
.setDesc(
|
||||
"Symbol for third-level indented bullet points (12 spaces)"
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("►")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportBulletPointMap[12] || "►"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportBulletPointMap[12] =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Level 4 Bullet Point")
|
||||
.setDesc(
|
||||
"Symbol for fourth-level indented bullet points (16 spaces)"
|
||||
)
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("•")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportBulletPointMap[16] || "•"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportBulletPointMap[16] =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
// Checkbox symbols settings
|
||||
containerEl.createEl("h6", { text: "Checkbox Symbols" });
|
||||
containerEl.createEl("p", {
|
||||
text: "Configure symbols for checkboxes.",
|
||||
});
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Unchecked Checkbox")
|
||||
.setDesc("Symbol for unchecked checkboxes")
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("☐")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportCheckboxUnchecked || "☐"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportCheckboxUnchecked =
|
||||
value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Checked Checkbox")
|
||||
.setDesc("Symbol for checked checkboxes")
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("☑")
|
||||
.setValue(
|
||||
this.plugin.settings.textExportCheckboxChecked || "☑"
|
||||
)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.textExportCheckboxChecked = value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
111
src/utils.ts
111
src/utils.ts
|
|
@ -340,6 +340,102 @@ export async function getEmbedMap(
|
|||
return embedMap;
|
||||
}
|
||||
|
||||
// Convert Markdown to plain text with specific formatting
|
||||
export function convertMarkdownToText(
|
||||
plugin: MarkdownExportPlugin,
|
||||
markdown: string
|
||||
): string {
|
||||
let text = markdown;
|
||||
|
||||
// Replace checkboxes
|
||||
// - [ ] becomes ☐
|
||||
// - [x] becomes ☑
|
||||
text = text.replace(
|
||||
/- \[ \]/g,
|
||||
plugin.settings.textExportCheckboxUnchecked
|
||||
);
|
||||
text = text.replace(/- \[x\]/g, plugin.settings.textExportCheckboxChecked);
|
||||
|
||||
// Replace bullet points with specific characters
|
||||
// - becomes ●
|
||||
// - becomes ○
|
||||
// - becomes ■
|
||||
// - becomes ►
|
||||
// - becomes •
|
||||
const lines = text.split("\n");
|
||||
const processedLines = lines.map((line) => {
|
||||
// Count leading spaces or tabs to determine indentation level
|
||||
const leadingWhitespace = line.match(/^(\s*)/)?.[0] || "";
|
||||
|
||||
// Replace bullet points based on indentation level
|
||||
if (line.trim().startsWith("- ")) {
|
||||
// Remove leading whitespace for processing
|
||||
const trimmedLine = line.trim();
|
||||
|
||||
// First, normalize tabs to spaces (1 tab = 4 spaces)
|
||||
const normalizedIndent = leadingWhitespace.replace(/\t/g, " ");
|
||||
const indentationLevel = Math.floor(normalizedIndent.length / 4);
|
||||
let bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[indentationLevel * 4];
|
||||
|
||||
// If no symbol is configured for this level, use the default mapping
|
||||
if (!bulletPointSymbol) {
|
||||
// Use the configured symbol for this indentation level, or fall back to defaults
|
||||
switch (indentationLevel) {
|
||||
case 0:
|
||||
bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[0] || "●";
|
||||
break;
|
||||
case 1:
|
||||
bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[4] || "○";
|
||||
break;
|
||||
case 2:
|
||||
bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[8] || "■";
|
||||
break;
|
||||
case 3:
|
||||
bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[12] || "►";
|
||||
break;
|
||||
case 4:
|
||||
bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[16] || "•";
|
||||
break;
|
||||
default: {
|
||||
// For deeper levels, use the last configured symbol or default to "•"
|
||||
const levels = Object.keys(
|
||||
plugin.settings.textExportBulletPointMap
|
||||
)
|
||||
.map(Number)
|
||||
.sort((a, b) => a - b);
|
||||
if (levels.length > 0) {
|
||||
const deepestLevel = levels[levels.length - 1];
|
||||
bulletPointSymbol =
|
||||
plugin.settings.textExportBulletPointMap[
|
||||
deepestLevel
|
||||
] || "•";
|
||||
} else {
|
||||
bulletPointSymbol = "•";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
leadingWhitespace +
|
||||
bulletPointSymbol +
|
||||
" " +
|
||||
trimmedLine.slice(2)
|
||||
);
|
||||
}
|
||||
|
||||
return line;
|
||||
});
|
||||
|
||||
return processedLines.join("\n");
|
||||
}
|
||||
|
||||
export async function tryCopyMarkdownByRead(
|
||||
plugin: MarkdownExportPlugin,
|
||||
{ file, outputFormat, outputSubPath = "." }: CopyMarkdownOptions
|
||||
|
|
@ -511,6 +607,21 @@ export async function tryCopyMarkdownByRead(
|
|||
await tryCreate(plugin, targetFile, content);
|
||||
break;
|
||||
}
|
||||
case OUTPUT_FORMATS.TEXT: {
|
||||
let filename;
|
||||
if (plugin.settings.customFileName) {
|
||||
filename = plugin.settings.customFileName + ".md";
|
||||
} else {
|
||||
filename = file.name;
|
||||
}
|
||||
const targetFile = path.join(
|
||||
outDir,
|
||||
filename.replace(".md", ".txt")
|
||||
);
|
||||
const textContent = convertMarkdownToText(plugin, content);
|
||||
await tryCreate(plugin, targetFile, textContent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue