#337 - Add support for other fm types

This commit is contained in:
Elio Struyf
2022-05-17 16:19:40 +02:00
parent 2825d5ddd8
commit 3583a2b962
6 changed files with 58 additions and 12 deletions
+1
View File
@@ -9,6 +9,7 @@
- [#333](https://github.com/estruyf/vscode-front-matter/issues/333): Automatically mark Jekyll posts in `_drafts` folder as draft
- [#335](https://github.com/estruyf/vscode-front-matter/issues/335): Merge media snippets with content snippets to allow you to define multiple media snippets and use these in your content
- [#336](https://github.com/estruyf/vscode-front-matter/issues/336): Support added for inverting the draft field so that SSGs/authors can use a published field instead
- [#337](https://github.com/estruyf/vscode-front-matter/issues/337): Allow multiple front matter types to be used.
### ⚡️ Optimizations
+1 -1
View File
@@ -238,7 +238,7 @@ export class Settings {
data[matterProp] = [...new Set(taxonomies)].sort();
const spaces = vscode.window.activeTextEditor?.options?.tabSize;
// Update the file
fs.writeFileSync(file.path, FrontMatterParser.toFile(article.content, article.data, {
fs.writeFileSync(file.path, FrontMatterParser.toFile(article.content, article.data, mdFile, {
indent: spaces || 2
} as DumpOptions as any), { encoding: "utf8" });
}
+1
View File
@@ -211,6 +211,7 @@ export async function activate(context: vscode.ExtensionContext) {
subscriptions.push(vscode.workspace.onDidChangeTextDocument((TextDocumentChangeEvent) => {
const filePath = TextDocumentChangeEvent.document.uri.fsPath;
if (filePath && !filePath.toLowerCase().startsWith(`extension-output`)) {
MarkdownFoldingProvider.triggerHighlighting();
statusDebouncer(() => triggerShowDraftStatus(`onDidChangeTextEditorSelection`), 200);
}
}));
+4 -3
View File
@@ -115,7 +115,7 @@ export class ArticleHelper {
const lastLine = lines.pop();
const endsWithNewLine = lastLine !== undefined && lastLine.trim() === "";
let newMarkdown = this.stringifyFrontMatter(article.content, Object.assign({}, article.data));
let newMarkdown = this.stringifyFrontMatter(article.content, Object.assign({}, article.data), document?.getText());
// Logic to not include a new line at the end of the file
if (!endsWithNewLine) {
@@ -150,8 +150,9 @@ export class ArticleHelper {
*
* @param content
* @param data
* @param originalContent
*/
public static stringifyFrontMatter(content: string, data: any) {
public static stringifyFrontMatter(content: string, data: any, originalContent?: string) {
const indentArray = Settings.get(SETTING_INDENT_ARRAY) as boolean;
const commaSeparated = Settings.get<string[]>(SETTING_COMMA_SEPARATED_FIELDS);
@@ -165,7 +166,7 @@ export class ArticleHelper {
}
}
return FrontMatterParser.toFile(content, data, ({
return FrontMatterParser.toFile(content, data, originalContent, ({
noArrayIndent: !indentArray,
skipInvalid: true,
noCompatMode: true,
+39 -2
View File
@@ -16,8 +16,13 @@ export interface ParsedFrontMatter {
export class FrontMatterParser {
public static currentContent: string | null = null;
/**
* Convert the current content to a Front Matter object
* @param content
* @returns
*/
public static fromFile(content: string): ParsedFrontMatter {
const format = getFormatOpts(this.getLanguage());
const format = getFormatOpts(this.getLanguageFromContent(content));
FrontMatterParser.currentContent = content;
const result = matter(content, { ...Engines, ...format });
// in the absent of a body when serializing an entry we use an empty one
@@ -29,13 +34,21 @@ export class FrontMatterParser {
};
}
/**
* Convert the Front Matter object to text
* @param content
* @param metadata
* @param options
* @returns
*/
public static toFile(
content: string,
metadata: Object,
originalContent?: string,
options?: any
) {
// Stringify to YAML if the format was not set
const format = getFormatOpts(this.getLanguage());
const format = getFormatOpts(this.getLanguageFromContent(originalContent));
const trimLastLineBreak = content.slice(-1) !== '\n';
const file = matter.stringify(content, metadata, {
@@ -46,6 +59,30 @@ export class FrontMatterParser {
return trimLastLineBreak && file.slice(-1) === '\n' ? file.substring(0, file.length - 1) : file;
}
/**
* Validate the type of front matter language that is used
* @param contents
*/
public static getLanguageFromContent(contents: string | undefined) {
if (!contents) {
return this.getLanguage();
}
if (contents.startsWith(`+++`)) {
return "toml";
} else if (contents.startsWith(`---`)) {
return "yaml";
} else if (contents.startsWith(`{`)) {
return "json";
} else {
return "yaml";
}
}
/**
* Get the front matter language type
* @returns
*/
private static getLanguage() {
const language = Settings.get(SETTING_FRONTMATTER_TYPE) as string || "YAML";
return language.toLowerCase();
+12 -6
View File
@@ -4,6 +4,7 @@ import { CancellationToken, FoldingContext, FoldingRange, FoldingRangeKind, Fold
import { SETTING_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_CONTENT_SUPPORTED_FILETYPES, SETTING_FRONTMATTER_TYPE } from '../constants';
import { Settings } from '../helpers';
import { FrontMatterDecorationProvider } from './FrontMatterDecorationProvider';
import { FrontMatterParser } from '../parsers';
export class MarkdownFoldingProvider implements FoldingRangeProvider {
private static start: number | null = null;
@@ -43,7 +44,7 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider {
if (isSupported) {
const fmHighlight = Settings.get<boolean>(SETTING_CONTENT_FRONTMATTER_HIGHLIGHT);
const range = this.getFrontMatterRange();
const range = MarkdownFoldingProvider.getFrontMatterRange();
if (range) {
if (MarkdownFoldingProvider.decType !== null) {
@@ -64,17 +65,22 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider {
* @returns
*/
public static getFrontMatterRange(document?: TextDocument) {
const language = Settings.get(SETTING_FRONTMATTER_TYPE) as string || "YAML";
const content = document?.getText();
const language = FrontMatterParser.getLanguageFromContent(content);
let lineStart = "---";
let lineEnd = "---";
if (language === "TOML") {
let lineEnd = lineStart;
if (language.toLowerCase() === "toml") {
lineStart = "+++";
lineEnd = lineStart;
} else if (language.toLowerCase() === "json") {
lineStart = "{";
lineEnd = "}";
}
if (document) {
const lines = document.getText().split('\n');
if (content) {
const lines = content.split('\n');
let start = null;
let end = null;