├── README.md ├── .eslintrc.json ├── index.html ├── style.css └── editor.js /README.md: -------------------------------------------------------------------------------- 1 | Checklist Generator 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "rules": { 8 | "no-sequences": "error", 9 | "no-console": "off", 10 | "indent": [ 11 | "error", 12 | 2, 13 | {"SwitchCase": 1} 14 | ], 15 | "linebreak-style": [ 16 | "error", 17 | "unix" 18 | ], 19 | "quotes": [ 20 | "error", 21 | "double" 22 | ], 23 | "semi": [ 24 | "error", 25 | "always" 26 | ] 27 | }, 28 | "parserOptions": { 29 | "sourceType": "module" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Checklist 7 | 8 | 9 | 10 | 35 |
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | font-family: Arial; 7 | } 8 | 9 | div#instructions { 10 | float: left; 11 | display: block; 12 | margin-right: 2em; 13 | } 14 | 15 | div#instructions pre { 16 | white-space: pre-line; 17 | } 18 | 19 | div#checklist_container { 20 | -webkit-column-count: 2; 21 | -moz-column-count: 2; 22 | column-count: 2; 23 | column-gap: 10px; 24 | column-fill: auto; 25 | } 26 | 27 | div.checklist { 28 | border-left: 1px solid #000; 29 | border-right: 1px solid #000; 30 | border-bottom: 1px solid #000; 31 | text-transform: uppercase; 32 | break-inside: avoid; 33 | margin-bottom: 10px; 34 | 35 | } 36 | div.checklist > h1 { 37 | margin: 0; 38 | margin-bottom: 0.3em; 39 | padding-top: 0.3em; 40 | padding-bottom: 0.3em; 41 | background-color: #000; 42 | text-align: center; 43 | font-weight: normal; 44 | font-size: 1.4em; 45 | letter-spacing: 0.1em; 46 | color: #fff; 47 | } 48 | 49 | 50 | div.checklist_item { 51 | display: flex; 52 | align-items: center; 53 | padding: 0.2em; 54 | } 55 | 56 | span.dots { 57 | flex: 1; 58 | text-align: center; 59 | white-space: nowrap; 60 | overflow: hidden; 61 | } 62 | 63 | span.dots::before { 64 | content: "......................................................................................................................................................................................................................"; 65 | letter-spacing: 2px; 66 | color: #000; 67 | } 68 | 69 | ul { 70 | margin: 0px; 71 | margin-bottom: 0.3em; 72 | padding: 0px; 73 | max-width: 100%; 74 | } 75 | 76 | li { 77 | list-style-type: none; 78 | line-height: 0.9em; 79 | padding-left: 0.3em; 80 | padding-right: 0.3em; 81 | } 82 | 83 | @media print { 84 | @page { 85 | size: a4; 86 | } 87 | 88 | body { 89 | font-size: 10pt !important; 90 | } 91 | 92 | div#header { 93 | display: none 94 | } 95 | 96 | div.checklist { 97 | page-break-inside: avoid; /* Avoid breaking divs between pages */ 98 | break-inside: avoid-column; /* CSS3 standard syntax */ 99 | print-color-adjust: exact; 100 | -webkit-print-color-adjust: exact; 101 | } 102 | 103 | div.checklist > h1 { 104 | print-color-adjust: exact; 105 | -webkit-print-color-adjust: exact; 106 | } 107 | } 108 | 109 | -------------------------------------------------------------------------------- /editor.js: -------------------------------------------------------------------------------- 1 | function Checklist() { 2 | let textarea = document.querySelector("div#editor > textarea"); 3 | let example_md = [ 4 | "# Cockpit Preparation", 5 | "* Parking Brake: set", 6 | "* Eng Master 1 & 2: off", 7 | "* Ignition Selectior: Normal", 8 | "", 9 | "# Before Start", 10 | "* Stairway: DISS", 11 | "* Seatbelt Signs: on", 12 | "* No Smoking Signs: on", 13 | "* Beacon Light: on"].join("\n"); 14 | 15 | function init() { 16 | bind_editor(); 17 | bind_try_button(); 18 | } 19 | 20 | function bind_editor() { 21 | textarea.addEventListener("input", function() { 22 | parse_md(textarea.value); 23 | }); 24 | } 25 | 26 | function bind_try_button() { 27 | let button = document.querySelector("button"); 28 | 29 | button.addEventListener("mouseup", function() { 30 | textarea.value = example_md; 31 | parse_md(example_md); 32 | }); 33 | } 34 | 35 | 36 | function parse_md(checklist_markup) { 37 | let lines = checklist_markup.split("\n"); 38 | 39 | let fold_fun = function(acc, line) { 40 | let match_result = null; 41 | 42 | if ((match_result = line.match(/^#\s(.+)$/))) { 43 | acc.push(new_checklist(match_result[1])); 44 | } else if ((match_result = line.match(/^\*\s(.+):\s(.+)$/))) { 45 | let current_checklist_element = acc.slice(-1)[0]; 46 | let current_item_list = current_checklist_element.querySelector("ul"); 47 | let new_item = new_checklist_item(match_result[1], match_result[2]); 48 | 49 | current_item_list.appendChild(new_item); 50 | } 51 | 52 | return acc; 53 | }; 54 | 55 | let result = lines.reduce(fold_fun, []); 56 | 57 | let new_checklist_container = generate_element( 58 | "
" 59 | ); 60 | 61 | result.forEach(function(c) {new_checklist_container.appendChild(c);}); 62 | document.querySelector("div#checklist_container").replaceWith(new_checklist_container); 63 | } 64 | 65 | function new_checklist(title) { 66 | let checklist_element = generate_element( 67 | "

" + title + "

" 68 | ); 69 | 70 | return checklist_element; 71 | } 72 | 73 | function new_checklist_item(item_name, action) { 74 | let checklist_item = generate_element( 75 | "
  • " + 76 | item_name + "" + action + 77 | "
  • " 78 | ); 79 | 80 | return checklist_item; 81 | } 82 | 83 | // Expects html with exactly one top level element 84 | function generate_element(html) { 85 | const template = document.createElement("template"); 86 | template.innerHTML = html.trim(); 87 | return template.content.children[0]; 88 | } 89 | 90 | return { 91 | init 92 | }; 93 | } 94 | 95 | const checklist = Checklist(); 96 | window.addEventListener("load", function() { 97 | checklist.init(); 98 | }); 99 | --------------------------------------------------------------------------------