Repository: styleguidist/react-styleguidist
Pull request #1140 (2018-09-17 23:15:11)

Allow chunkify to accept other extensions than js, jsx and html
I am in the process of trying to simplify vue-styleguidist and I need to extract every react specific detail of styleguidist.
In this spirit, we want to be able to use example-loader.
Bad luck, we allow the use of "vue" as a language for our examples. 

This brought https://github.com/vue-styleguidist/vue-styleguidist#200

I thought the best way to clean up vsg's code while making rsg a little more powerful was to add an option to the example-loader customLangs.

Wether it's additional langs or replace entirely can be changed.

Thank you for your remarks.
Bart


Patch:
diff --git a/loaders/examples-loader.js b/loaders/examples-loader.js
index 6ef3eb17..457c2dff 100644
--- a/loaders/examples-loader.js
+++ b/loaders/examples-loader.js
@@ -30,7 +30,7 @@ function examplesLoader(source) {
 		: undefined;
 
 	// Load examples
-	const examples = chunkify(source, updateExample);
+	const examples = chunkify(source, updateExample, query.customLangs);
 
 	// We're analysing the examples' source code to figure out the require statements. We do it manually with regexes,
 	// because webpack unfortunately doesn't expose its smart logic for rewriting requires
diff --git a/loaders/utils/chunkify.js b/loaders/utils/chunkify.js
index 324c782d..4b99cc78 100644
--- a/loaders/utils/chunkify.js
+++ b/loaders/utils/chunkify.js
@@ -11,9 +11,10 @@ const CODE_PLACEHOLDER = '<%{#code#}%>';
  *
  * @param {string} markdown
  * @param {Function} updateExample
+ * @param {Array<string>} playgroundLangs
  * @returns {Array}
  */
-module.exports = function chunkify(markdown, updateExample) {
+module.exports = function chunkify(markdown, updateExample, playgroundLangs = PLAYGROUND_LANGS) {
 	const codeChunks = [];
 
 	/*
@@ -34,7 +35,7 @@ module.exports = function chunkify(markdown, updateExample) {
 
 				const lang = example.lang;
 				node.lang = lang;
-				if (!lang || (PLAYGROUND_LANGS.indexOf(lang) !== -1 && !example.settings.static)) {
+				if (!lang || (playgroundLangs.indexOf(lang) !== -1 && !example.settings.static)) {
 					codeChunks.push({
 						type: 'code',
 						content: example.content,


Test patch:
diff --git a/loaders/utils/__tests__/__snapshots__/chunkify.spec.js.snap b/loaders/utils/__tests__/__snapshots__/chunkify.spec.js.snap
index 437827ab..46f837fb 100644
--- a/loaders/utils/__tests__/__snapshots__/chunkify.spec.js.snap
+++ b/loaders/utils/__tests__/__snapshots__/chunkify.spec.js.snap
@@ -1,5 +1,23 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`should even parse examples with custom extensions 1`] = `
+Array [
+  Object {
+    "content": "Custom extensions",
+    "type": "markdown",
+  },
+  Object {
+    "content": 
+<AppButton>
+  Example in vue
+</AppButton>
+,
+    "settings": Object {},
+    "type": "code",
+  },
+]
+`;
+
 exports[`should parse examples settings correctly 1`] = `
 Array [
   Object {
@@ -54,6 +72,30 @@ Array [
 ]
 `;
 
+exports[`should parse undefined custom extensions without throwing 1`] = `
+Array [
+  Object {
+    "content": "Undefined extensions (default)",
+    "type": "markdown",
+  },
+  Object {
+    "content": 
+<AppButton>
+  Example in jsx with undefined extensions
+</AppButton>
+,
+    "settings": Object {},
+    "type": "code",
+  },
+  Object {
+    "content": "\`\`\`pizza
+Unknown language: \\"pizza\\"
+\`\`\`",
+    "type": "markdown",
+  },
+]
+`;
+
 exports[`should separate Markdown and component examples 1`] = `
 Array [
   Object {
diff --git a/loaders/utils/__tests__/chunkify.spec.js b/loaders/utils/__tests__/chunkify.spec.js
index 9d550243..24319e6b 100644
--- a/loaders/utils/__tests__/chunkify.spec.js
+++ b/loaders/utils/__tests__/chunkify.spec.js
@@ -127,3 +127,31 @@ it('should call updateExample function for example', () => {
 	const actual = chunkify(markdown, updateExample);
 	expect(actual).toEqual(expected);
 });
+
+it('should even parse examples with custom extensions', () => {
+	const markdown = `
+Custom extensions
+
+\`\`\`vue
+<AppButton>Example in vue</AppButton>
+\`\`\`
+`;
+	const actual = chunkify(markdown, undefined, ['vue']);
+	expect(actual).toMatchSnapshot();
+});
+
+it('should parse undefined custom extensions without throwing', () => {
+	const markdown = `
+Undefined extensions (default)
+
+\`\`\`jsx
+<AppButton>Example in jsx with undefined extensions</AppButton>
+\`\`\`
+
+\`\`\`pizza
+<AppButton>Example in pizza with undefined extensions (test double)</AppButton>
+\`\`\`
+`;
+	const actual = chunkify(markdown, undefined, undefined);
+	expect(actual).toMatchSnapshot();
+});