Skip to content

Commit

Permalink
Cleanup file formatters. (#759)
Browse files Browse the repository at this point in the history
* Clean up frontmatter formatter.

* Move `formatToExtension`.

* Use plain objects for file formatters.

* Use same parsers for files and frontmatter.

We want to use our file parsers for frontmatter, instead of the builtin
ones, as they process some formats (images, dates) properly.

* Cleanup YAML frontmatter parser code.
  • Loading branch information
tech4him1 authored and Benaiah committed Oct 30, 2017
1 parent 2c19c22 commit 1bb2b56
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 52 deletions.
4 changes: 1 addition & 3 deletions src/formats/__tests__/frontmatter.spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import Frontmatter from '../frontmatter';
import FrontmatterFormatter from '../frontmatter';

jest.mock("../../valueObjects/AssetProxy.js");

const FrontmatterFormatter = new Frontmatter();

describe('Frontmatter', () => {
it('should parse YAML with --- delimiters', () => {
expect(
Expand Down
19 changes: 11 additions & 8 deletions src/formats/formats.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import YAML from './yaml';
import TOML from './toml';
import JSONFormatter from './json';
import Frontmatter from './frontmatter';
import yamlFormatter from './yaml';
import tomlFormatter from './toml';
import jsonFormatter from './json';
import FrontmatterFormatter from './frontmatter';

const yamlFormatter = new YAML();
const tomlFormatter = new TOML();
const jsonFormatter = new JSONFormatter();
const FrontmatterFormatter = new Frontmatter();
export const formatToExtension = format => ({
markdown: 'md',
yaml: 'yml',
toml: 'toml',
json: 'json',
html: 'html',
}[format]);

function formatByType(type) {
// Right now the only type is "editorialWorkflow" and
Expand Down
46 changes: 19 additions & 27 deletions src/formats/frontmatter.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import matter from 'gray-matter';
import TOML from './toml';
import YAML from './yaml';

const tomlFormatter = new TOML();
import tomlFormatter from './toml';
import yamlFormatter from './yaml';
import jsonFormatter from './json';

const parsers = {
toml: tomlFormatter.fromFile.bind(tomlFormatter),
json: (input) => {
toml: input => tomlFormatter.fromFile(input),
json: input => {
let JSONinput = input.trim();
// Fix JSON if leading and trailing brackets were trimmed.
if (JSONinput.substr(0, 1) !== '{') {
Expand All @@ -15,7 +14,11 @@ const parsers = {
if (JSONinput.substr(-1) !== '}') {
JSONinput = JSONinput + '}';
}
return matter.engines.json.parse(JSONinput);
return jsonFormatter.fromFile(JSONinput);
},
yaml: {
parse: input => yamlFormatter.fromFile(input),
stringify: (metadata, { sortedKeys }) => yamlFormatter.toFile(metadata, sortedKeys),
},
}

Expand All @@ -37,31 +40,20 @@ function inferFrontmatterFormat(str) {
}
}

export default class Frontmatter {
export default {
fromFile(content) {
const result = matter(content, { engines: parsers, ...inferFrontmatterFormat(content) });
const data = result.data;
data.body = result.content;
return data;
}
return {
...result.data,
body: result.content,
};
},

toFile(data, sortedKeys) {
const meta = {};
let body = '';
Object.keys(data).forEach((key) => {
if (key === 'body') {
body = data[key];
} else {
meta[key] = data[key];
}
});
const { body, ...meta } = data;

// always stringify to YAML
const parser = {
stringify(metadata) {
return new YAML().toFile(metadata, sortedKeys);
},
};
return matter.stringify(body, meta, { language: "yaml", delimiters: "---", engines: { yaml: parser } });
// `sortedKeys` is not recognized by gray-matter, so it gets passed through to the parser
return matter.stringify(body, meta, { engines: parsers, language: "yaml", delimiters: "---", sortedKeys });
}
}
4 changes: 2 additions & 2 deletions src/formats/json.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export default class JSONFormatter {
export default {
fromFile(content) {
return JSON.parse(content);
}
},

toFile(data) {
return JSON.stringify(data);
Expand Down
4 changes: 2 additions & 2 deletions src/formats/toml.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ const outputReplacer = (key, value) => {
return false;
};

export default class TOML {
export default {
fromFile(content) {
return toml.parse(content);
}
},

toFile(data, sortedKeys = []) {
return tomlify.toToml(data, { replace: outputReplacer, sort: sortKeys(sortedKeys) });
Expand Down
4 changes: 2 additions & 2 deletions src/formats/yaml.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ const OutputSchema = new yaml.Schema({
explicit: yaml.DEFAULT_SAFE_SCHEMA.explicit,
});

export default class YAML {
export default {
fromFile(content) {
return yaml.safeLoad(content);
}
},

toFile(data, sortedKeys = []) {
return yaml.safeDump(data, { schema: OutputSchema, sortKeys: sortKeys(sortedKeys) });
Expand Down
9 changes: 1 addition & 8 deletions src/reducers/collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import consoleError from '../lib/consoleError';
import { CONFIG_SUCCESS } from '../actions/config';
import { FILES, FOLDER } from '../constants/collectionTypes';
import { INFERABLE_FIELDS } from '../constants/fieldInference';
import { formatToExtension } from '../formats/formats';

const collections = (state = null, action) => {
const configCollections = action.payload && action.payload.collections;
Expand All @@ -26,14 +27,6 @@ const collections = (state = null, action) => {
}
};

const formatToExtension = format => ({
markdown: 'md',
yaml: 'yml',
toml: 'toml',
json: 'json',
html: 'html',
}[format]);

const selectors = {
[FOLDER]: {
entryExtension(collection) {
Expand Down

0 comments on commit 1bb2b56

Please sign in to comment.