This content rule can check what markdown headings appear in content properties. PR Close #22759
		
			
				
	
	
		
			50 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			50 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * A factory for creating a rule for the `checkContentRules` processor, which disallows markdown
 | 
						|
 * headings in a content property.
 | 
						|
 *
 | 
						|
 * @param {...number|string} disallowedHeadings
 | 
						|
 * Each parameter identifies heading levels that are not allowed. They can be in the form of:
 | 
						|
 *
 | 
						|
 * - a number (e.g. 1), which implies that the specified heading is not allowed
 | 
						|
 * - a range (e.g. '2,3'), which implies the range of headings that are not allowed
 | 
						|
 *
 | 
						|
 * (A range can be open ended on the upper bound by not specifying a value after the comma.)
 | 
						|
 *
 | 
						|
 * @example
 | 
						|
 * To create a rule that will only allow level 3 headings:
 | 
						|
 *
 | 
						|
 * ```
 | 
						|
 * const rule = createNoMarkdownHeadingRule(1, 2, '4,');
 | 
						|
 * ```
 | 
						|
 *
 | 
						|
 */
 | 
						|
module.exports = function createrNoMarkdownHeadingRule() {
 | 
						|
  const args = Array.prototype.slice.apply(arguments);
 | 
						|
  const disallowedHeadings = args.map(arg => `#{${arg}}`);
 | 
						|
  if (!disallowedHeadings.length) {
 | 
						|
    disallowedHeadings.push('#{1,}');
 | 
						|
  }
 | 
						|
  const regex = new RegExp(`^ {0,3}(${disallowedHeadings.join('|')}) +.*$`, 'mg');
 | 
						|
  return (doc, prop, value) => {
 | 
						|
    let match, matches = [];
 | 
						|
    while(match = regex.exec(value)) { // eslint-disable-line no-cond-assign
 | 
						|
      matches.push(match[0]);
 | 
						|
    }
 | 
						|
    if (matches.length) {
 | 
						|
      const list = listify(matches.map(match => `"${match}"`));
 | 
						|
      return `Invalid headings found in "${prop}" property: ${list}.`;
 | 
						|
    }
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * Convert an array of strings in to a human list - e.g separated by commas and the word `and`.
 | 
						|
 * @param {string[]} values The strings to convert to a list
 | 
						|
 */
 | 
						|
function listify(values) {
 | 
						|
  if (values.length <= 1) return values;
 | 
						|
  const last = values[values.length - 1];
 | 
						|
  const rest = values.slice(0, values.length - 1);
 | 
						|
  return [rest.join(', '), last].join(' and ');
 | 
						|
} |