{code}287 | 288 |
{error.message}
37 | 38 | {#if dev && error.stack} 39 |{error.stack}40 | {/if} 41 | -------------------------------------------------------------------------------- /docs_src/src/routes/_layout.svelte: -------------------------------------------------------------------------------- 1 | 15 | 16 |
]+>)\\n\\t\\t\\t/,'$1').replace(/\\t\\t\\t/g,'');
47 | }
48 |
49 | return {
50 | name: 'rollup-plugin-svg-icons',
51 | writeBundle: async (bundle) => {
52 | fs.writeFileSync(path.resolve('./public/bundle.js'), bundle['bundle.js'].code.replace(/.+?<\/pre>/g,ident_remover));
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-preprocess-markdown",
3 | "version": "2.7.3",
4 | "description": "Using markdown in Svelte components",
5 | "main": "dist/index.js",
6 | "module": "dist/index.mjs",
7 | "scripts": {
8 | "build": "rollup -c",
9 | "pretest": "npm run build",
10 | "test": "node tests/test.js | tap-diff",
11 | "test-update": "node tests/test.js update | tap-diff",
12 | "test-new": "node tests/test.js new",
13 | "prepublishOnly": "npm run build",
14 | "docs-install": "cd docs_src && npm i",
15 | "docs-dev": "cd docs_src && npm run dev",
16 | "docs-export": "cd docs_src && npm run export",
17 | "docs-build": "cd docs_src && npm run build",
18 | "docs-start": "cd docs_src && npm run start"
19 | },
20 | "dependencies": {
21 | "front-matter": "^3.2.1",
22 | "marked": "^1.0.0"
23 | },
24 | "devDependencies": {
25 | "@detools/tap-diff": "^0.2.2",
26 | "fs-extra": "^8.1.0",
27 | "highlight.js": "^10.0.3",
28 | "highlightjs-svelte": "^1.0.5",
29 | "rollup": "^2.10.2",
30 | "rollup-plugin-terser": "^7.0.0",
31 | "tape": "^5.0.0"
32 | },
33 | "files": [
34 | "dist"
35 | ],
36 | "repository": {
37 | "type": "git",
38 | "url": "git+https://github.com/AlexxNB/svelte-preprocess-markdown.git"
39 | },
40 | "keywords": [
41 | "svelte",
42 | "preprocessor",
43 | "markdown",
44 | "marked"
45 | ],
46 | "author": "Alexey Schebelev",
47 | "license": "MIT",
48 | "bugs": {
49 | "url": "https://github.com/AlexxNB/svelte-preprocess-markdown/issues"
50 | },
51 | "homepage": "https://github.com/AlexxNB/svelte-preprocess-markdown#readme"
52 | }
53 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | const { terser } = require("rollup-plugin-terser");
2 |
3 | export default {
4 | input: 'src/index.js',
5 | output: [
6 | { file: 'dist/index.js', format: 'cjs' },
7 | { file: 'dist/index.mjs', format: 'es' }
8 | ],
9 | external: ['path', 'marked','front-matter'],
10 | plugins: [terser()]
11 | };
--------------------------------------------------------------------------------
/src/handlers/code.js:
--------------------------------------------------------------------------------
1 | import {moduleStore} from './../store';
2 |
3 | export default function code() {
4 |
5 | let savedCode = [];
6 | let id = 0;
7 |
8 | let marked = () => {};
9 |
10 | const code_sanitizer = (text,inline=false) => {
11 | text = text.replace(/{/g,'{').replace(/}/g,'}');
12 | if(inline) text = text.replace(//g,'>');
13 | return text;
14 | }
15 |
16 | const inline_code_replacer = (text,code) => {
17 | savedCode[id++] = code_sanitizer(code,true);
18 | return "```%svelte-md-inline-code-"+id+"%```";
19 | }
20 |
21 | const code_replacer = (code,spaces) => {
22 | code = code.replace(new RegExp(`^[\\t ]{0,${spaces}}`, "gm"),'');
23 | code = code_sanitizer(marked(code));
24 | savedCode[id++] = code;
25 | return "%svelte-md-block-code-"+id+"%";
26 | }
27 |
28 | const code_restorator_inline = (text,id) => {
29 | return savedCode[id-1];
30 | }
31 |
32 | const code_restorator_block = (text,id) => {
33 | moduleStore.add('const CODEBLOCK_'+id+' = `'+savedCode[id-1].replace(/`/g,'\\`')+'`;');
34 | return `{@html CODEBLOCK_${id}}`;
35 | }
36 |
37 | const before = (text,processor) => {
38 | marked = processor;
39 |
40 | const inline_re = /```(.+?)```/g;
41 | text = text.replace(inline_re,inline_code_replacer);
42 |
43 | const re = /^([\t ]*)(```.*)[\t ]*$/mg
44 | let result;
45 | let level = 0;
46 | let map = [];
47 | const mapitem = {start:0,end:0,spaces:0};
48 | while(result = re.exec(text)){
49 | if(result[2].length > 3) {
50 | level++;
51 | if(level === 1) {
52 | mapitem.start = result['index']
53 | mapitem.spaces = result[1].length
54 | }
55 | }else if(result[2].length === 3) {
56 | level--;
57 | if(level === 0) {
58 | mapitem.end = (result['index']+result[1].length+3)
59 | map.push({...mapitem});
60 | mapitem.start = mapitem.spaces = mapitem.end = 0;
61 | }
62 |
63 | }
64 | }
65 |
66 | let masked_text = text;
67 | for(let i = 0; i < map.length; i++){
68 | const codeblock = text.slice(map[i].start,map[i].end);
69 | masked_text = masked_text.replace(codeblock,()=>code_replacer(codeblock,map[i].spaces));
70 | }
71 |
72 | return masked_text;
73 | }
74 |
75 | const after = (text,processor) => {
76 | const re_inline = /%svelte\-md\-inline\-code\-(\d+)%/g;
77 | const re_block = /%svelte\-md\-block\-code\-(\d+)%/g;
78 | text = text.replace(re_inline,code_restorator_inline);
79 | text = text.replace(re_block,code_restorator_block);
80 | return text;
81 | }
82 | return {before,after}
83 | }
--------------------------------------------------------------------------------
/src/handlers/interpolation.js:
--------------------------------------------------------------------------------
1 |
2 | export default function interpolation() {
3 | let savedI11ns = [];
4 | let id = 0;
5 |
6 | const i11n_replacer = (text) => {
7 | savedI11ns[id++] = text;
8 |
9 | return `%svelte-md-inline-i11n-${id}%`;
10 | }
11 |
12 | const i11n_restorator = (text,id) => {
13 | return savedI11ns[id-1];
14 | }
15 |
16 | const before = (text,marked) => {
17 |
18 | const re = /{[^#@:\/][^{}]+}/mg;
19 | while(text.match(re)){
20 | text = text.replace(re,i11n_replacer);
21 | }
22 |
23 | return text;
24 | }
25 |
26 | const after = (text,marked) => {
27 | const re = /\%svelte\-md\-inline\-i11n\-(\d+)\%/g;
28 | while(text.match(re)){
29 | text = text.replace(re,i11n_restorator);
30 | }
31 | return text;
32 | }
33 |
34 | return {before,after}
35 | }
--------------------------------------------------------------------------------
/src/handlers/logic.js:
--------------------------------------------------------------------------------
1 | export default function logic() {
2 | let savedLogic = [];
3 | let id = 0;
4 |
5 | let marked = () => {};
6 |
7 | const logic_replacer = (text,space1,open,tag,content,space2,close) => {
8 | if(content.length > 0){
9 | content = before(content,marked);
10 | content = content.replace(new RegExp(`^[\\t ]{0,${space2.length}}`, "gm"),'');
11 |
12 | const subcontents = content.split(/\{:.+\}/);
13 |
14 | for(let i=0; i|<\/p>/g,'').trim();
24 |
25 | content = content.replace(subcontents[i],text);
26 | }
27 | }
28 |
29 | savedLogic[id++] = `${open}${content}${close}`;
30 | return space1+"%svelte-md-block-logic-"+id+"%";;
31 | }
32 |
33 | const logic_restorator = (text,id) => {
34 | return savedLogic[id-1];
35 | }
36 |
37 | const each_list_butify = (text,open,type,attr,content,close) => {
38 | return `<${type}${attr}>\n${open}\n${content}${close}\n${type}>`;
39 | }
40 |
41 |
42 | const table_butify = (text,head,body) => {
43 | const columns = getCols(head);
44 |
45 | body = body.replace(/{:else}\s+?(.+)<\/p>\s+?{\/each}/mgi,(_,string) => `{:else}\n${makeSpanedRow(string,columns)}\n{\/each}`);
46 | body = body.replace(/^(?:
)?(\|.+\|)(?:<\/p>)?$/mgi,(_,content)=>makeHTMLRows(content,columns));
47 |
48 | return `
49 | ${head}
50 |
51 | ${body}
52 |
53 |
`;
54 | }
55 |
56 | const before = (text,processor) => {
57 | marked = processor;
58 |
59 | const re = /([ \t]*)(\{#([a-z]+)[^}]*})(\n?([\s]*)[\S\s]*?)(\{\/\3\})/gmi
60 | while(text.match(re)) {
61 | text = text.replace(re,logic_replacer);
62 | }
63 |
64 | text = text.replace(/^[\\t ]+(%svelte\-md\-block\-logic\-\d+%)/gm,'$1');
65 |
66 | return text;
67 | }
68 |
69 | const after = (text,processor) => {
70 | const re = /%svelte\-md\-block\-logic\-(\d+)%/g;
71 | while(text.match(re)){
72 | text = text.replace(re,logic_restorator);
73 | }
74 |
75 | // Make list in each
76 | text = text.replace(/({#each.*?})\s*<([uo]l)(.*?)>\s*([\s\S]*)<\/\2>\s*({\/each})/gmi,each_list_butify);
77 |
78 | // Make table in each
79 | text = text.replace(/\s*\s*((?:(?!<\/tr>)[\s\S])+)<\/tr>\s*<\/thead>\s* \s*\s*((?:(?!<\/table>)[\s\S])*(?:\|[\s\S]+?\|<\/p>)[\s\S]*?)<\/td>[\s\S]+?<\/tr>\s*<\/tbody>\s*<\/table>/gmi,table_butify);
80 | return text;
81 | }
82 |
83 | return {before,after}
84 | }
85 |
86 | // Table helpers
87 |
88 | function makeHTMLRows(str,cols){
89 | return str.split('\n').map(line => {
90 | let cells = line.split('|');
91 |
92 | if(cells.length - cols.length !== 2) return line;
93 | if(cells[0] !== '' || cells[cells.length-1] !== '') return line;
94 |
95 | cells = cells.slice(1,-1).map((content,index) => `
${content} `)
96 |
97 | return ` ${cells.join('')} `
98 | }).join('\n');
99 | }
100 |
101 | function makeSpanedRow(str,cols){
102 | return ` 1 ? ` colspan="${cols.length}"` : ''}>${str} `
103 | }
104 |
105 | function getCols(str){
106 | let cols = [];
107 |
108 | let regexp = /.+?<\/th>/gim;
109 | let result;
110 | while (result = regexp.exec(str)) {
111 | cols.push(result[1] || 'left');
112 | }
113 |
114 | return cols;
115 | }
--------------------------------------------------------------------------------
/src/handlers/meta.js:
--------------------------------------------------------------------------------
1 | import fm from 'front-matter';
2 | import {moduleStore} from './../store';
3 |
4 | export default function tags() {
5 |
6 | const before = (text,processor) => {
7 | const {attributes,body} = fm(text);
8 | moduleStore.add(`export const META = ${JSON.stringify(attributes)};`);
9 | return body;
10 | }
11 |
12 | const after = (text,processor) => {
13 | return text;
14 | }
15 |
16 | return {before,after}
17 | }
--------------------------------------------------------------------------------
/src/handlers/systemTags.js:
--------------------------------------------------------------------------------
1 | import {moduleStore} from './../store';
2 | export default function systemTags() {
3 | let savedSystags = [];
4 | let id = 0;
5 |
6 | const systags_replacer = (text) => {
7 | savedSystags[id++] = text;
8 | return '';
9 | }
10 |
11 | const mdsv_parser = (text) => {
12 | if(!text.match(/^[\t ]*`;
57 | }
58 | moduleStore.clear();
59 | }
60 |
61 | return text;
62 | }
63 |
64 | export function Renderer() {
65 | return getMarkedRenderer();
66 | }
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | let STORE = [];
2 |
3 | export const moduleStore = {
4 | add: (value) => STORE.push(value),
5 | get: () => STORE,
6 | clear: () => STORE = []
7 | }
--------------------------------------------------------------------------------
/src/utils.js:
--------------------------------------------------------------------------------
1 | import marked from 'marked'
2 |
3 | export const getMarkedInstance = (options) =>{
4 | const defaults = marked.getDefaults();
5 | defaults.renderer = getMarkedRenderer();
6 | options = Object.assign(defaults,{headerIds:false},options);
7 |
8 | marked.setOptions(options);
9 |
10 | set_p_renderer(marked);
11 | set_checkbox_renderer(marked,options);
12 |
13 | return marked;
14 | }
15 |
16 |
17 | function set_p_renderer (marked_instance) {
18 | const defParagraph = marked_instance.defaults.renderer.paragraph.bind({});
19 |
20 | marked_instance.defaults.renderer.paragraph = (text) => {
21 | if(text.match(/^([\s]*%svelte\-md\-block\-\w+\-\d+%)+[\s]*$/)){
22 | return text.replace(/
/g,"\n")+"\n";
23 | }else{
24 | return defParagraph(text);
25 | }
26 | }
27 | }
28 |
29 | function set_checkbox_renderer (marked_instance,options) {
30 | marked_instance.defaults.renderer.checkbox = (checked) => {
31 | return ' ';
32 | }
33 | }
34 |
35 | export const getMarkedRenderer = () => {
36 | return new marked.Renderer();
37 | }
--------------------------------------------------------------------------------
/tests/1-simple-component.md:
--------------------------------------------------------------------------------
1 |
4 |
5 | # Hello *{name}*!
--------------------------------------------------------------------------------
/tests/10-checkbox.md:
--------------------------------------------------------------------------------
1 | ## Checkboxes test
2 |
3 | - [ ] unchecked
4 | - [x] checked
--------------------------------------------------------------------------------
/tests/11-renderer.js:
--------------------------------------------------------------------------------
1 | const {Renderer} = require('./../dist');
2 |
3 | const renderer = Renderer();
4 |
5 | renderer.heading = (text) => {
6 | return `${text} `;
7 | }
8 |
9 | module.exports = {
10 | renderer
11 | }
--------------------------------------------------------------------------------
/tests/11-renderer.md:
--------------------------------------------------------------------------------
1 |
2 | ### HELO ###
--------------------------------------------------------------------------------
/tests/2-setting-options.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | headerIds: true
3 | }
--------------------------------------------------------------------------------
/tests/2-setting-options.md:
--------------------------------------------------------------------------------
1 |
4 |
5 | # Hello *{name}*!
--------------------------------------------------------------------------------
/tests/3-markdown-testing.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | # Hello {name}!
7 |
8 | Let's try the list:
9 |
10 | * Item 1
11 | * Item 2
12 |
13 | [Link](https://ya.ru)
14 |
15 |
16 |
--------------------------------------------------------------------------------
/tests/4-logic-blocks.md:
--------------------------------------------------------------------------------
1 |
13 |
14 | # Testing list
15 |
16 | {#each list as item}
17 |
18 | {#if item === 'alexxnb'}
19 | * Hello, *{item}*!
20 | {:else}
21 | * Hello, stranger!
22 | {/if}
23 |
24 | {/each}
25 |
26 | {#each list as item}
27 | * Hello, *{item}*!
28 | {/each}
29 |
30 |
31 | {#if name}
32 | Hello, *{name}*!
33 | {:else}
34 | Hello, stranger!
35 | {/if}
36 |
37 | {#await promise}
38 | waiting for the promise to resolve...
39 | {:then value}
40 | The value is `{value}`
41 | {:catch error}
42 | Something went wrong: `{error.message}`
43 | {/await}
--------------------------------------------------------------------------------
/tests/5-mdsv-parsing.md:
--------------------------------------------------------------------------------
1 | import Block from './Block.svelte';
2 | import { data } from './my_data.js';
3 |
4 | # The MDSv example
5 |
6 | You can use components and a logic inside doc:
7 |
8 |
9 | My `data` list:
10 | {#each data as item}
11 | {item}
12 | {/each}
13 |
--------------------------------------------------------------------------------
/tests/6-codeblocks.md:
--------------------------------------------------------------------------------
1 | ```js
2 | // test
3 | console.log();
4 |
5 | ```
6 |
7 | ```html
8 | // test
9 |
12 |
13 | ```
14 |
15 | Code with interpolation `{var}`
16 |
17 | Code without interpolation ```{var}```
--------------------------------------------------------------------------------
/tests/7-highlight.js:
--------------------------------------------------------------------------------
1 | const hljs = require('highlight.js/lib/core');
2 | const xml_lang = require('highlight.js/lib/languages/xml');
3 | const js_lang = require('highlight.js/lib/languages/javascript');
4 | const css_lang = require('highlight.js/lib/languages/css');
5 | const hljs_svelte = require('highlightjs-svelte');
6 |
7 | hljs.registerLanguage('xml', xml_lang);
8 | hljs.registerLanguage('javascript', js_lang);
9 | hljs.registerLanguage('css', css_lang);
10 | hljs_svelte(hljs);
11 |
12 | module.exports = {
13 | highlight
14 | }
15 |
16 | function highlight(code, lang) {
17 | let result = hljs.highlight(lang,code).value;
18 | return result;
19 | }
--------------------------------------------------------------------------------
/tests/7-highlight.md:
--------------------------------------------------------------------------------
1 | ```svelte
2 |
7 | ...
8 | {#each items as item}
9 | * {item}
10 | {/each }
11 |
12 |
13 |
14 | ```
--------------------------------------------------------------------------------
/tests/8-each-blocks.md:
--------------------------------------------------------------------------------
1 | ### Case 1:
2 |
3 | {#each [1,2,3] as _}
4 | text
5 | {/each}
6 |
7 | ### Case 2:
8 |
9 | {#each [1,2,3] as _}text{/each}
10 |
11 | ### Case 3:
12 |
13 | {#each [1,2,3] as _}
14 |
15 | text
16 |
17 | {/each}
18 |
19 | ### Case 4:
20 |
21 | {#each [1,2,3] as _}
22 | One
23 | Two
24 | {/each}
25 |
26 | ### Case 5:
27 | {#each [1,2,3] as _}
28 | One
29 |
30 | Two
31 | {/each}
32 |
33 | ### Case 6:
34 | {#each [1,2,3] as num}
35 | * List item {num}
36 | {/each}
37 |
38 | ### Case 7:
39 | {#each [1,2,3] as num}
40 | * List item {num}
41 |
42 | and some text
43 | {/each}
44 |
45 | ### Case 8:
46 | {#each [1,2,3] as num}
47 | 0. List item
48 | {/each}
--------------------------------------------------------------------------------
/tests/9-table-in-each.md:
--------------------------------------------------------------------------------
1 | # Control
2 |
3 | | Name | Gender | Breed |
4 | | ------ | :----: | -------------------------- |
5 | | Dasher | male | Whippet |
6 | | Maisey | female | Treeing Walker Coonhound |
7 |
8 | # Simple table
9 |
10 | | Name | Gender | Breed |
11 | | ----: | :----: | ----- |
12 | {#each dogs as {name, gender, breed}}
13 | | {name} | {gender} | {breed} |
14 | {/each}
15 |
16 | # Multiline table
17 |
18 | | Name | Gender | Breed |
19 | | ---- | ---- | ----- |
20 | {#each dogs as {name, gender, breed}}
21 | | {name} | {gender || 'undefined'} | {breed} |
22 | | {name} | {gender} | {breed} |
23 | {/each}
24 |
25 |
26 | # Table in each with else
27 | | Name | Gender | Breed |
28 | | ---- | :----: | ----- |
29 | {#each dogs as {name, gender, breed}}
30 | | {name} | {gender} | {breed} |
31 | {:else}
32 | No entries
33 | {/each}
34 |
35 | # Table with if condition
36 |
37 | | Name | Gender | Breed |
38 | | ----: | :----: | ----- |
39 | {#if dogs.length > 2}
40 | {#each dogs as {name, gender, breed}}
41 | | {name} | {gender} | {breed} |
42 | {/each}
43 | {/if}
44 |
45 |
46 |
47 | # Table with nested if condition
48 |
49 | | Name | Gender | Breed |
50 | | ----: | :----: | ----- |
51 | {#each dogs as {name, gender, breed}}
52 | {#if breed === 'male'}
53 | | {name} | {gender} | {breed} |
54 | {/if}
55 | {/each}
56 |
57 | # Control - should not break
58 |
59 | | Name | Gender | Breed |
60 | | ------ | :----: | -------------------------- |
61 | | {#if blah}Bobik{/if} | male | Whippet |
62 | | Maisey | female | Treeing Walker Coonhound |
63 |
64 |
65 | # Control - cells num not equal - shouldn't be converted
66 |
67 | | Name | Gender | Breed |
68 | | ----: | :----: | ----- |
69 | {#each dogs as {name, gender, breed}}
70 | | {name} | {gender} | {breed} | {unknown} |
71 | {/each}
72 |
73 |
74 | # Control - blank line after header - shouldn't be converted
75 |
76 | | Name | Gender | Breed |
77 | | ----: | :----: | ----- |
78 |
79 | {#each dogs as {name, gender, breed}}
80 | | {name} | {gender} | {breed} |
81 | {/each}
--------------------------------------------------------------------------------
/tests/helpers/new.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var fs = require('fs-extra');
3 |
4 | const TESTS_DIR = path.resolve('tests');
5 | const TEST_EXT = '.md';
6 |
7 | module.exports.newTest = function(id){
8 | const new_file = path.join(TESTS_DIR,`${id}-new-test${TEST_EXT}`);
9 | fs.ensureFileSync(new_file);
10 | console.log('New test at:',new_file);
11 | }
12 |
--------------------------------------------------------------------------------
/tests/helpers/snapshots.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var fs = require('fs-extra');
3 |
4 | const TESTS_DIR = path.resolve('tests');
5 | const SNAPSHOTS_DIR = path.join(TESTS_DIR,'snapshots');
6 | const TEST_EXT = '.md';
7 | const SNAPSHOT_EXT = '.svelte';
8 |
9 | module.exports.getSnaplist = function(handler,update=false){
10 |
11 | if(update) fs.emptyDirSync(SNAPSHOTS_DIR);
12 |
13 | const files = fs.readdirSync(TESTS_DIR).filter(f => f.endsWith(TEST_EXT));
14 |
15 | let snaplist = [];
16 | for(let i=0; i < files.length; i++){
17 | const name = path.basename(files[i],TEST_EXT);
18 | const source = fs.readFileSync(path.join(TESTS_DIR,files[i]),'utf-8');
19 | const result = handler(source,{name,options:getOptions(name)});
20 | const snapshot = getSnapshot(name,result);
21 |
22 | snaplist.push({name,source,result,snapshot});
23 | }
24 |
25 | return snaplist;
26 | }
27 |
28 | function getOptions (name){
29 | const options_file = path.join(TESTS_DIR,name+'.js');
30 |
31 | if(fs.existsSync(options_file))
32 | return require(options_file);
33 | else
34 | return {};
35 |
36 | }
37 |
38 | function getSnapshot (name,initial){
39 | const snapshot_file = path.join(SNAPSHOTS_DIR,name+SNAPSHOT_EXT);
40 |
41 | if(fs.existsSync(snapshot_file))
42 | return fs.readFileSync(snapshot_file,'utf-8');
43 | else
44 | return updateSnapshot(name,initial);
45 | }
46 |
47 | function updateSnapshot (name,data){
48 |
49 | const snapshot_file = path.join(SNAPSHOTS_DIR,name+SNAPSHOT_EXT);
50 | fs.ensureFileSync(snapshot_file);
51 | fs.writeFileSync(snapshot_file,data);
52 | return data;
53 | }
--------------------------------------------------------------------------------
/tests/helpers/testing.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 |
3 | module.exports.doTesting = function(snaplist){
4 | snaplist.forEach(snapshot => {
5 | test(snapshot.name, function (t) {
6 | t.equal(snapshot.result,snapshot.snapshot);
7 | t.end();
8 | });
9 | })
10 | }
11 |
--------------------------------------------------------------------------------
/tests/helpers/visual.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var fs = require('fs-extra');
3 |
4 | const TESTS_DIR = path.resolve('tests');
5 | const VISUAL_DIR = path.join(TESTS_DIR,'visual');
6 | const VISUAL_EXT = '.svelte';
7 |
8 | module.exports.createVisualTest = function(snaplist){
9 | console.log('Open visual test at:');
10 | for(let i=0; i < snaplist.length; i++){
11 | const snapshot = snaplist[i];
12 | const visual_file = path.join(VISUAL_DIR,snapshot.name+VISUAL_EXT);
13 | fs.ensureFileSync(visual_file);
14 | fs.writeFileSync(visual_file,snapshot.result);
15 | console.log(`${i+1}.`,visual_file);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/snapshots/1-simple-component.svelte:
--------------------------------------------------------------------------------
1 | Hello {name}!
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/tests/snapshots/10-checkbox.svelte:
--------------------------------------------------------------------------------
1 | Checkboxes test
2 |
3 | - unchecked
4 | - checked
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/tests/snapshots/11-renderer.svelte:
--------------------------------------------------------------------------------
1 | HELO
2 |
3 |
--------------------------------------------------------------------------------
/tests/snapshots/2-setting-options.svelte:
--------------------------------------------------------------------------------
1 | Hello {name}!
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/tests/snapshots/3-markdown-testing.svelte:
--------------------------------------------------------------------------------
1 | Hello {name}!
2 | Let's try the list:
3 |
4 | - Item 1
5 | - Item 2
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tests/snapshots/4-logic-blocks.svelte:
--------------------------------------------------------------------------------
1 | Testing list
2 | {#each list as item}
3 | {#if item === 'alexxnb'}
4 |
5 | - Hello, {item}!
6 |
7 | {:else}
8 |
9 | - Hello, stranger!
10 |
11 | {/if}
12 | {/each}
13 |
14 | {#each list as item}
15 | - Hello, {item}!
16 | {/each}
17 |
18 | {#if name}
19 | Hello, {name}!
20 | {:else}
21 | Hello, stranger!
22 | {/if}
23 | {#await promise}
24 | waiting for the promise to resolve...
25 | {:then value}
26 | The value is {value}
27 | {:catch error}
28 | Something went wrong: {error.message}
29 | {/await}
30 |
31 |
32 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/tests/snapshots/5-mdsv-parsing.svelte:
--------------------------------------------------------------------------------
1 | The MDSv example
2 | You can use components and a logic inside doc:
3 | My data
list:
4 | {#each data as item}
5 |
{item}
6 | {/each}
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tests/snapshots/6-codeblocks.svelte:
--------------------------------------------------------------------------------
1 | {@html CODEBLOCK_2}
2 | {@html CODEBLOCK_3}
3 | Code with interpolation {var}
4 | Code without interpolation {var}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/tests/snapshots/7-highlight.svelte:
--------------------------------------------------------------------------------
1 | {@html CODEBLOCK_1}
2 |
3 |
4 |
--------------------------------------------------------------------------------
/tests/snapshots/8-each-blocks.svelte:
--------------------------------------------------------------------------------
1 | Case 1:
2 | {#each [1,2,3] as _}
3 | text
4 | {/each}
5 | Case 2:
6 | {#each [1,2,3] as _}text{/each}
7 | Case 3:
8 | {#each [1,2,3] as _}
9 | text
10 | {/each}
11 | Case 4:
12 | {#each [1,2,3] as _}
13 | One
14 | Two
15 | {/each}
16 | Case 5:
17 | {#each [1,2,3] as _}
18 | One
19 | Two
20 | {/each}
21 | Case 6:
22 |
23 | {#each [1,2,3] as num}
24 | - List item {num}
25 | {/each}
26 |
27 | Case 7:
28 | {#each [1,2,3] as num}
29 |
30 | - List item {num}
31 |
32 | and some text
33 | {/each}
34 | Case 8:
35 |
36 | {#each [1,2,3] as num}
37 | - List item
38 | {/each}
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/tests/snapshots/9-table-in-each.svelte:
--------------------------------------------------------------------------------
1 | Control
2 |
3 |
4 |
5 | Name
6 | Gender
7 | Breed
8 |
9 |
10 |
11 | Dasher
12 | male
13 | Whippet
14 |
15 |
16 | Maisey
17 | female
18 | Treeing Walker Coonhound
19 |
20 |
21 | Simple table
22 |
23 |
24 | Name
25 | Gender
26 | Breed
27 |
28 |
29 | {#each dogs as {name, gender, breed}}
30 | {name} {gender} {breed}
31 | {/each}
32 |
33 |
34 | Multiline table
35 |
36 |
37 | Name
38 | Gender
39 | Breed
40 |
41 |
42 | {#each dogs as {name, gender, breed}}
43 | {name} {gender || 'undefined'} {breed}
44 | {name} {gender} {breed}
45 | {/each}
46 |
47 |
48 | Table in each with else
49 |
50 |
51 | Name
52 | Gender
53 | Breed
54 |
55 |
56 | {#each dogs as {name, gender, breed}}
57 | {name} {gender} {breed}
58 | {:else}
59 | No entries
60 | {/each}
61 |
62 |
63 | Table with if condition
64 |
65 |
66 | Name
67 | Gender
68 | Breed
69 |
70 |
71 | {#if dogs.length > 2}
72 | {#each dogs as {name, gender, breed}}
73 | {name} {gender} {breed}
74 | {/each}
75 | {/if}
76 |
77 |
78 | Table with nested if condition
79 |
80 |
81 | Name
82 | Gender
83 | Breed
84 |
85 |
86 | {#each dogs as {name, gender, breed}}
87 | {#if breed === 'male'}
88 | {name} {gender} {breed}
89 | {/if}
90 | {/each}
91 |
92 |
93 | Control - should not break
94 |
95 |
96 |
97 | Name
98 | Gender
99 | Breed
100 |
101 |
102 |
103 | {#if blah}Bobik{/if}
104 | male
105 | Whippet
106 |
107 |
108 | Maisey
109 | female
110 | Treeing Walker Coonhound
111 |
112 |
113 | Control - cells num not equal - shouldn't be converted
114 |
115 |
116 | Name
117 | Gender
118 | Breed
119 |
120 |
121 | {#each dogs as {name, gender, breed}}
122 | | {name} | {gender} | {breed} | {unknown} |
123 | {/each}
124 |
125 |
126 | Control - blank line after header - shouldn't be converted
127 |
128 |
129 |
130 | Name
131 | Gender
132 | Breed
133 |
134 |
135 |
136 | {#each dogs as {name, gender, breed}}
137 | | {name} | {gender} | {breed} |
138 | {/each}
139 |
140 |
141 |
--------------------------------------------------------------------------------
/tests/test.js:
--------------------------------------------------------------------------------
1 | const command = process.argv[2];
2 |
3 | const {getSnaplist} = require('./helpers/snapshots');
4 | const {createVisualTest} = require('./helpers/visual');
5 | const {doTesting} = require('./helpers/testing');
6 | const {newTest} = require('./helpers/new');
7 | const {markdown} = require('./../dist');
8 |
9 | function handleSource(source,params={}){
10 | return markdown(params.options).markup({content:source,filename:params.name+'.md'}).code;
11 | }
12 |
13 |
14 | const snaplist = getSnaplist(handleSource,(command === 'update'));
15 |
16 | if(command === 'new'){
17 | newTest(snaplist.length+1)
18 | process.exit(0);
19 | }
20 |
21 | createVisualTest(snaplist);
22 | doTesting(snaplist);
23 |
24 |
--------------------------------------------------------------------------------