Skip to content

Commit

Permalink
Added feature matrix in README.md (#162)
Browse files Browse the repository at this point in the history
* Also added quick script to regenerate it based on feature-matrix.json
  • Loading branch information
sadiqkhoja authored Jul 15, 2024
1 parent 9e64b5d commit c426725
Show file tree
Hide file tree
Showing 7 changed files with 605 additions and 2 deletions.
288 changes: 288 additions & 0 deletions README.md

Large diffs are not rendered by default.

218 changes: 218 additions & 0 deletions feature-matrix.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
{
"Question types (basic functionality)": {
"text": "",
"integer": "",
"decimal": "",
"note": "🚧",
"select_one": "",
"select_multiple": "",
"repeat": "",
"group": "",
"geopoint": "",
"geotrace": "",
"geoshape": "",
"start-geopoint": "",
"range": "",
"image": "",
"barcode": "",
"audio": "",
"background-audio": "",
"video": "",
"file": "",
"date": "",
"time": "",
"datetime": "",
"rank": "",
"csv-external": "",
"acknowledge": "",
"start": "",
"end": "",
"today": "",
"deviceid": "",
"username": "",
"phonenumber": "",
"email": "",
"audit": ""
},
"Appearances": {
"numbers": "",
"multiline": "",
"url": "",
"ex:": "",
"thousands-sep": "",
"bearing": "",
"vertical": "",
"no-ticks": "",
"picker": "",
"rating": "",
"new": "",
"new-front": "",
"draw": "",
"annotate": "",
"signature": "",
"no-calendar": "",
"month-year": "",
"year": "",
"ethiopian": "",
"coptic": "",
"islamic": "",
"bikram-sambat": "",
"myanmar": "",
"persian": "",
"placement-map": "",
"maps": "",
"hide-input": "",
"minimal": "",
"search / autocomplete": "",
"quick": "",
"columns-pack": "",
"columns": "",
"columns-n": "",
"no-buttons": "",
"image-map": "",
"likert": "",
"map": "",
"field-list": "",
"label": "",
"list-nolabel": "",
"list": "",
"table-list": ""
},
"Parameters": {
"randomize": "",
"seed": "",
"value": "",
"label": "",
"geopoint capture-accuracy, warning-accuracy, allow-mock-accuracy": "",
"range start, end, step": "",
"image max-pixels": "",
"audio quality": "",
"Audit: location-priority, location-min-interval, location-max-age, track-changes, track-changes-reasons, identify-user": ""
},
"Form Logic": {
"calculate": "",
"relevant": "",
"required": "",
"required message": "🚧",
"custom constraint": "🚧",
"constraint message": "🚧",
"read only": "",
"trigger": "",
"choice filter": "",
"default": "",
"query parameter": "",
"repeat_count": ""
},
"Descriptions and Annotations": {
"label": "",
"hint": "",
"guidance hint": "",
"Translations": "",
"Translations with field/question value": "",
"Markdown": "",
"Inline HTML": "",
"Form attachments": "",
"image": "",
"big-image": "",
"audio": "",
"video": "",
"secondary instance (external choice file)": "",
"secondary instance (last saved)": "",
"autoplay": ""
},
"Theme and Layouts": {
"grid": "",
"pages": "",
"print": "",
"logo": "",
"theme color": "",
"Submissions": "",
"preview": "",
"send": "",
"view": "",
"edit": "",
"attachments": ""
},
"Offline capabilities": {
"List of projects & forms": "",
"local persistence (single)": "",
"save as draft": "",
"offline entities": "",
"MBtiles / offline map layers": ""
},
"XPath": {
"operators": "",
"predicates": "",
"axes": "",
"string(* arg)": "",
"concat(string arg*|node-set arg*)": "",
"join(string separator, node-set nodes*)": "",
"substr(string value, number start, number end?)": "",
"substring-before(string, string)": "",
"substring-after(string, string)": "",
"translate(string, string, string)": "",
"string-length(string arg)": "",
"normalize-space(string arg?)": "",
"contains(string haystack, string needle)": "",
"starts-with(string haystack, string needle)": "",
"ends-with(string haystack, string needle)": "",
"uuid(number?)": "",
"digest(string src, string algorithm, string encoding?)": "",
"pulldata(string instance_id, string desired_element, string query_element, string query)": "",
"if(boolean condition, * then, * else)": "",
"coalesce(string arg1, string arg2)": "",
"once(string calc)": "",
"true()": "",
"false()": "",
"boolean(* arg)": "",
"boolean-from-string(string arg)": "",
"not(boolean arg)": "",
"regex(string value, string expression)": "",
"checklist(number min, number max, string v*)": "",
"weighted-checklist(number min, number max, [string v, string w]*)": "",
"number(* arg)": "",
"random()": "",
"int(number arg)": "",
"sum(node-set arg)": "",
"max(node-set arg*)": "",
"min(node-set arg*)": "",
"round(number arg, number decimals?)": "",
"pow(number value, number power)": "",
"log(number arg)": "",
"log10(number arg)": "",
"abs(number arg)": "",
"sin(number arg)": "",
"cos(number arg)": "",
"tan(number arg)": "",
"asin(number arg)": "",
"acos(number arg)": "",
"atan(number arg)": "",
"atan2(number arg, number arg)": "",
"sqrt(number arg)": "",
"exp(number arg)": "",
"exp10(number arg)": "",
"pi()": "",
"count(node-set arg)": "",
"count-non-empty(node-set arg)": "",
"position(node arg?)": "",
"instance(string id)": "",
"current()": "",
"randomize(node-set arg, number seed)": "",
"today()": "",
"now()": "",
"format-date(date value, string format)": "",
"format-date-time(dateTime value, string format)": "",
"date(* value)": "",
"decimal-date-time(dateTime value)": "",
"decimal-time(time value)": "",
"selected(string list, string value)": "",
"selected-at(string list, number index)": "",
"count-selected(node node)": "",
"jr:choice-name(node node, string value)": "",
"jr:itext(string id)": "",
"indexed-repeat(node-set arg, node-set repeat1, number index1, [node-set repeatN, number indexN]{0,2})": " ",
"area(node-set ns|geoshape gs)": "",
"distance(node-set ns|geoshape gs|geotrace gt|(geopoint|string) arg*)": "",
"base64-decode(base64Binary input)": ""
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"bump": "changeset add",
"format": "prettier -w \"**/*\" --ignore-unknown --cache",
"format:checkonly": "prettier -c \"**/*\" --ignore-unknown",
"lint": "eslint . --report-unused-disable-directives"
"lint": "eslint . --report-unused-disable-directives",
"feature-matrix": "node scripts/feature-matrix/render.js"
},
"dependencies": {
"@changesets/changelog-github": "^0.5.0",
Expand Down
75 changes: 75 additions & 0 deletions scripts/feature-matrix/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* eslint-disable */
// @ts-nocheck

import Mustache from 'mustache';
import fs from 'node:fs/promises';

const rootUrl = new URL('../..', import.meta.url);
const featureMatrix = JSON.parse(
await fs.readFile(new URL('./feature-matrix.json', rootUrl), 'utf-8')
);
const template = await fs.readFile(
new URL('scripts/feature-matrix/template.mustache', rootUrl),
'utf-8'
);
const readmeFile = await fs.readFile(new URL('./README.md', rootUrl), 'utf-8');

// Modified version of https://gist.github.com/rougier/c0d31f5cbdaac27b876c?permalink_comment_id=2269298#gistcomment-2269298
const progress = ({ value, length = 20 }) => {
const v = (value / 100) * length;
const x = v < 1 ? 1 : Math.floor(v);
const bar = Array(x).fill('█').join('');
const remaining = Array(length - bar.length)
.fill('█')
.join('');
return `\\color{green}${bar}\\color{LightGray}${remaining} \\space \\color{initial} ${value}\\%`;
};

// Not so smart, blindly breaks the word. Okay for now.
const wrapString = (str, maxLength) => {
let parts = [];
for (let i = 0; i < str.length; i += maxLength) {
parts.push(str.slice(i, i + maxLength));
}
return parts.join('<br/>');
};

// Transform feature-matrix.json object into array
const featureCategories = Object.keys(featureMatrix).map((featureCategory) => {
const features = Object.keys(featureMatrix[featureCategory]).map((feature) => {
return {
label: wrapString(feature.replaceAll('|', '\\|'), 40),
status: featureMatrix[featureCategory][feature],
};
});

// no points for 🚧
const progressPercentage = Math.floor(
(features.filter((f) => f.status === '✅').length / features.length) * 100
);

// hack: Space character in Latex monospace font is not same size as other characters.
// Using '=' sign with transparent color for padding. 🙃
let label = `${featureCategory}`.padEnd(40, '=').replaceAll(' ', ' \\space \\space ');
label = label.replace('=', '\\color{transparent}=');

const progressOutput = progress({ value: progressPercentage });

return {
// Using Latex for <summary> of collapsible - this allows using colored text in MD.
// mathtt is for monospace.
label: '${\\mathtt{' + label + ' ' + progressOutput + '}}$',
features,
};
});

const featureMatrixMd = Mustache.render(template, { categories: featureCategories });

const autogenOpen = '<!-- autogen: feature-matrix -->';
const autogenClose = '<!-- /autogen: feature-matrix -->';

const regex = new RegExp(`(${autogenOpen})[\\s\\S]*?(${autogenClose})`, 'm');

const updatedReadme = readmeFile.replace(regex, `$1\n${featureMatrixMd}\n$2`);

await fs.writeFile(new URL('./README.md', rootUrl), updatedReadme, { encoding: 'utf-8' });
15 changes: 15 additions & 0 deletions scripts/feature-matrix/template.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{ #categories }}

<details>
<summary>{{{ label }}}</summary>

<br/>

| Feature <img width=250px/> | Progress |
| ----------- | :----------: |
{{ #features }}
| {{{ label }}} | {{ status }} |
{{ /features }}

</details>
{{ /categories }}
3 changes: 2 additions & 1 deletion scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"test": "true"
},
"devDependencies": {
"globby": "^14.0.2"
"globby": "^14.0.2",
"mustache": "4.2.0"
}
}
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4804,6 +4804,11 @@ muggle-string@^0.4.0:
resolved "https://registry.yarnpkg.com/muggle-string/-/muggle-string-0.4.1.tgz#3b366bd43b32f809dc20659534dd30e7c8a0d328"
integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==

[email protected]:
version "4.2.0"
resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==

mute-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e"
Expand Down

0 comments on commit c426725

Please sign in to comment.