UNPKG

4.32 kBJavaScriptView Raw
1/**
2 * @author Titus Wormer
3 * @copyright 2015 Titus Wormer
4 * @license MIT
5 * @module mdast:utilities
6 * @version 2.2.2
7 * @fileoverview Collection of tiny helpers useful for
8 * both parsing and compiling markdown.
9 */
10
11'use strict';
12
13/* eslint-env commonjs */
14
15/*
16 * Dependencies.
17 */
18
19var collapseWhiteSpace = require('collapse-white-space');
20
21/*
22 * Expressions.
23 */
24
25var EXPRESSION_LINE_BREAKS = /\r\n|\r/g;
26var EXPRESSION_SYMBOL_FOR_NEW_LINE = /\u2424/g;
27var EXPRESSION_BOM = /^\ufeff/;
28
29/**
30 * Throw an exception with in its `message` `value`
31 * and `name`.
32 *
33 * @param {*} value - Invalid value.
34 * @param {string} name - Setting name.
35 */
36function raise(value, name) {
37 throw new Error(
38 'Invalid value `' + value + '` ' +
39 'for setting `' + name + '`'
40 );
41}
42
43/**
44 * Validate a value to be boolean. Defaults to `def`.
45 * Raises an exception with `context[name]` when not
46 * a boolean.
47 *
48 * @example
49 * validateBoolean({foo: null}, 'foo', true) // true
50 * validateBoolean({foo: false}, 'foo', true) // false
51 * validateBoolean({foo: 'bar'}, 'foo', true) // Throws
52 *
53 * @throws {Error} - When a setting is neither omitted nor
54 * a boolean.
55 * @param {Object} context - Settings.
56 * @param {string} name - Setting name.
57 * @param {boolean} def - Default value.
58 */
59function validateBoolean(context, name, def) {
60 var value = context[name];
61
62 if (value === null || value === undefined) {
63 value = def;
64 }
65
66 if (typeof value !== 'boolean') {
67 raise(value, 'options.' + name);
68 }
69
70 context[name] = value;
71}
72
73/**
74 * Validate a value to be boolean. Defaults to `def`.
75 * Raises an exception with `context[name]` when not
76 * a boolean.
77 *
78 * @example
79 * validateNumber({foo: null}, 'foo', 1) // 1
80 * validateNumber({foo: 2}, 'foo', 1) // 2
81 * validateNumber({foo: 'bar'}, 'foo', 1) // Throws
82 *
83 * @throws {Error} - When a setting is neither omitted nor
84 * a number.
85 * @param {Object} context - Settings.
86 * @param {string} name - Setting name.
87 * @param {number} def - Default value.
88 */
89function validateNumber(context, name, def) {
90 var value = context[name];
91
92 if (value === null || value === undefined) {
93 value = def;
94 }
95
96 if (typeof value !== 'number' || value !== value) {
97 raise(value, 'options.' + name);
98 }
99
100 context[name] = value;
101}
102
103/**
104 * Validate a value to be in `map`. Defaults to `def`.
105 * Raises an exception with `context[name]` when not
106 * not in `map`.
107 *
108 * @example
109 * var map = {bar: true, baz: true};
110 * validateString({foo: null}, 'foo', 'bar', map) // 'bar'
111 * validateString({foo: 'baz'}, 'foo', 'bar', map) // 'baz'
112 * validateString({foo: true}, 'foo', 'bar', map) // Throws
113 *
114 * @throws {Error} - When a setting is neither omitted nor
115 * in `map`.
116 * @param {Object} context - Settings.
117 * @param {string} name - Setting name.
118 * @param {string} def - Default value.
119 * @param {Object} map - Enum.
120 */
121function validateString(context, name, def, map) {
122 var value = context[name];
123
124 if (value === null || value === undefined) {
125 value = def;
126 }
127
128 if (!(value in map)) {
129 raise(value, 'options.' + name);
130 }
131
132 context[name] = value;
133}
134
135/**
136 * Clean a string in preperation of parsing.
137 *
138 * @example
139 * clean('\ufefffoo'); // 'foo'
140 * clean('foo\r\nbar'); // 'foo\nbar'
141 * clean('foo\u2424bar'); // 'foo\nbar'
142 *
143 * @param {string} value - Content to clean.
144 * @return {string} - Cleaned content.
145 */
146function clean(value) {
147 return String(value)
148 .replace(EXPRESSION_BOM, '')
149 .replace(EXPRESSION_LINE_BREAKS, '\n')
150 .replace(EXPRESSION_SYMBOL_FOR_NEW_LINE, '\n');
151}
152
153/**
154 * Normalize an identifier. Collapses multiple white space
155 * characters into a single space, and removes casing.
156 *
157 * @example
158 * normalizeIdentifier('FOO\t bar'); // 'foo bar'
159 *
160 * @param {string} value - Content to normalize.
161 * @return {string} - Normalized content.
162 */
163function normalizeIdentifier(value) {
164 return collapseWhiteSpace(value).toLowerCase();
165}
166
167/*
168 * Expose `validate`.
169 */
170
171exports.validate = {
172 'boolean': validateBoolean,
173 'string': validateString,
174 'number': validateNumber
175};
176
177/*
178 * Expose.
179 */
180
181exports.normalizeIdentifier = normalizeIdentifier;
182exports.clean = clean;
183exports.raise = raise;