Skip to content

Commit ea74411

Browse files
committed
feat(*): automate parser listing
1 parent e7b91ae commit ea74411

File tree

10 files changed

+278
-12
lines changed

10 files changed

+278
-12
lines changed

.github/workflows/parser-listing.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
name: 'Parser Listing'
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
types: ['ready_for_review', 'opened', 'synchronize', 'reopened']
8+
env:
9+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
10+
jobs:
11+
list:
12+
runs-on: ubuntu-latest
13+
if: github.event.pull_request.draft == false
14+
steps:
15+
- uses: actions/checkout@main
16+
- name: Extract branch name
17+
shell: bash
18+
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
19+
id: extract_branch
20+
- name: Install
21+
run: yarn install --frozen-lockfile
22+
- name: Create Listing
23+
run: yarn list-parsers
24+
- uses: technote-space/get-diff-action@v6
25+
id: diff
26+
with:
27+
FILES: |
28+
SUMMARY.md
29+
- name: Pushes parser list
30+
uses: dmnemec/copy_file_to_another_repo_action@main
31+
if: steps.diff.outputs.diff
32+
env:
33+
API_TOKEN_GITHUB: ${{ secrets.GH_PARSERS_TOKEN }}
34+
with:
35+
source_file: 'output/parsers.md'
36+
destination_repo: 'Specifyapp/Documentation'
37+
destination_folder: 'concepts'
38+
user_email: '[email protected]'
39+
user_name: 'AllanMichay'
40+
commit_message: 'feat(parsers): update parsers list'

output/.gitkeep

Whitespace-only changes.

output/PARSERS.md

Lines changed: 106 additions & 0 deletions
Large diffs are not rendered by default.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"test": "jest --coverage --runInBand",
4444
"generate:seeds": "ts-node ./tests/helper/generate.seed.ts",
4545
"format": "prettier '**/*' -u -w",
46-
"prepare": "git config --local core.hooksPath .hooks"
46+
"prepare": "git config --local core.hooksPath .hooks",
47+
"list-parsers": "node ./scripts/list-parsers.js"
4748
}
4849
}

parsers/sort-by/README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Sort By
22

33
## Description
4-
This parser helps loop on several design tokens and sort them according to their respective key values.
4+
5+
This parser helps you loop on several design tokens and sort them according to their respective key values.
56

67
Learn more about how to configure Specify in the API documentation: [https://specifyapp.com/developers](https://specifyapp.com/developers).
78

@@ -160,16 +161,16 @@ type output = Array<{ [key: string]: any }>;
160161
"value": {
161162
"unit": "px",
162163
"measure": 8
163-
},
164+
}
164165
},
165166
{
166167
"name": "base-space-01",
167168
"type": "measurement",
168169
"value": {
169170
"unit": "px",
170171
"measure": 4
171-
},
172-
},
172+
}
173+
}
173174
]
174175
```
175176

@@ -183,15 +184,15 @@ type output = Array<{ [key: string]: any }>;
183184
"value": {
184185
"unit": "px",
185186
"measure": 4 // <---
186-
},
187+
}
187188
},
188189
{
189190
"name": "base-space-02",
190191
"type": "measurement",
191192
"value": {
192193
"unit": "px",
193194
"measure": 8 // <---
194-
},
195-
},
195+
}
196+
}
196197
]
197198
```

parsers/to-flutter/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Description
44

5-
Format design tokens to create a theme compatible with the [Flutter specification](https://docs.flutter.dev/cookbook/design/themes).
5+
This parser helps you format design tokens to create a theme compatible with the [Flutter specification](https://docs.flutter.dev/cookbook/design/themes).
66

77
Learn more about how to configure Specify in the API documentation: [https://specifyapp.com/developers](https://specifyapp.com/developers).
88

parsers/to-tailwind/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Description
44

5-
Format design tokens to create a theme compatible with the [TailwindCSS specification](https://tailwindcss.com/docs/theme).
5+
This parser helps you format design tokens to create a theme compatible with the [TailwindCSS specification](https://tailwindcss.com/docs/theme).
66
The theme is also compatible with [WindiCSS](https://windicss.org/).
77

88
This parser creates a file containing the whole theme. It can then be used in the `tailwind.config.js`.

parsers/to-theme-ui/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Description
44

5-
Format design tokens to create a theme compatible with the [theme-ui specification](https://theme-ui.com/theme-spec).
5+
This parser helps you format design tokens to create a theme compatible with the [theme-ui specification](https://theme-ui.com/theme-spec).
66

77
Learn more about how to configure Specify in the API documentation: [https://specifyapp.com/developers](https://specifyapp.com/developers).
88

parsers/to-typescript-definition/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Description
44

5-
Format design tokens to create their corresponding TypeScript types.
5+
This parser helps you format design tokens to create their corresponding TypeScript types.
66

77
This parser generates TypeScript types corresponding to [Specify Token types](https://docs.specifyapp.com/concepts/token-types). All types respective values match the name of your design tokens returned by Specify.
88

scripts/list-parsers.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
const directoryPath = path.join(__dirname, '../', 'parsers');
5+
let parsers = [];
6+
const fileNames = fs.readdirSync(directoryPath);
7+
8+
const directories = fileNames.filter(fileName => !fileName.includes('.ts'));
9+
10+
parsers = directories.map(directory => {
11+
const readmeParserPath = path.join(__dirname, '../', 'parsers', directory, 'README.md');
12+
const parserContent = fs.readFileSync(readmeParserPath, { encoding: 'utf8', flag: 'r' });
13+
14+
const parserDescription = parserContent.match(/This parser helps you (.*)/)[1];
15+
const capitalizedParserDescription =
16+
parserDescription.charAt(0).toUpperCase() + parserDescription.slice(1);
17+
const exampleLink = `https://github.com/Specifyapp/parsers/blob/master/parsers/${directory}/README.md#usage`;
18+
const parserLink = `https://github.com/Specifyapp/parsers/blob/master/parsers/${directory}`;
19+
20+
return {
21+
title: directory,
22+
description: capitalizedParserDescription,
23+
parserLnk,
24+
exampleLink,
25+
};
26+
});
27+
28+
const markdownFullPage = `---
29+
description: >-
30+
Parsers are functions allowing you to transform design tokens and assets
31+
coming from Specify to fit your needs and company standards.
32+
---
33+
34+
# Parsers
35+
36+
## Why you need parsers
37+
38+
<figure><img src="../front/documentation/.gitbook/assets/where-parsers-happen-dark.jpg" alt=""><figcaption><p>Parsers help you transform raw design tokens and assets returned by Specify to match your company standards</p></figcaption></figure>
39+
40+
By default, without any parsers, Specify will return your design data as raw data:
41+
42+
* Design tokens are returned in JSON
43+
* Assets are returned as files
44+
45+
There are high chances you need to transform those design data to fit your needs. Parsers help you do just that.
46+
47+
## What are parsers?
48+
49+
Parsers are functions allowing you to transform design tokens and assets coming from Specify to fit your needs and company standards.
50+
51+
<figure><img src="../front/documentation/.gitbook/assets/how-parsers-work.jpg" alt=""><figcaption><p>An example output pipeline that pulls colors from Specify, sorts them alphabetically and transforms them as CSS Custom Properties</p></figcaption></figure>
52+
53+
A parser does the following job:
54+
55+
1. Receives design data as input
56+
2. Transforms this design data
57+
3. Returns the transformed data
58+
59+
The data returned by a parser can either be:
60+
61+
* Design data that can be used by another parser coming next in your transformation pipeline
62+
* A file so it can be used by people, frameworks, or scripts
63+
64+
{% hint style="info" %}
65+
Parsers are what make Specify powerful and flexible. They help you be in total control of the design data you pull from Specify.
66+
{% endhint %}
67+
68+
Parsers are ordered and takes specific input to generate specific output. This way, we can easily test the input coming from the previous parser to check if the whole parsers process will work.
69+
70+
## Categories
71+
72+
Parsers are classified in 2 categories: technology and utility.
73+
74+
### Technology
75+
76+
Technology parsers help you transform your design tokens to specific technologies and formats (CSS Custom properties, SCSS, Tailwind, a Javascript theme object compatible with React Native...)
77+
78+
Some examples:
79+
80+
* [to-react-native](https://github.com/Specifyapp/parsers/tree/master/parsers/to-react-native)
81+
* [to-css-custom-properties](https://github.com/Specifyapp/parsers/tree/master/parsers/to-css-custom-properties)
82+
* [to-scss-variables](https://github.com/Specifyapp/parsers/tree/master/parsers/to-scss-variables)
83+
* [to-tailwind](https://github.com/Specifyapp/parsers/tree/master/parsers/to-tailwind)
84+
85+
### Utility
86+
87+
Utility parsers take care of "smaller" transformation. Like converting a pixel value to \`rem\` or transforming a string to kebabcase.
88+
89+
Some examples:
90+
91+
* [convert-font](https://github.com/Specifyapp/parsers/tree/master/parsers/convert-font)
92+
* [kebabcasify](https://github.com/Specifyapp/parsers/tree/master/parsers/kebabcasify)
93+
* [px-to-rem](https://github.com/Specifyapp/parsers/tree/master/parsers/px-to-rem)
94+
95+
## All parsers available
96+
97+
All parsers are open source and available on [the following GitHub repository](https://github.com/Specifyapp/parsers).
98+
99+
`;
100+
101+
const markdownHeader = `| Parser | Description | Usage Example |
102+
|---|---|---|`;
103+
104+
const parsersMarkdown = parsers.reduce((acc, currentParser) => {
105+
const { title, description, exampleLink } = currentParser;
106+
if (!acc) {
107+
return `${markdownHeader}
108+
| [${title}](${parserLink}) | ${description} | [Example](${exampleLink}) |`;
109+
}
110+
return `${acc}
111+
| [${title}](${parserLink}) | ${description} | [Example](${exampleLink}) |`;
112+
}, '');
113+
114+
const summaryFilePath = path.join(__dirname, '../output/', 'parsers.md');
115+
fs.writeFileSync(summaryFilePath, markdownFullPage + parsersMarkdown, {
116+
encoding: 'utf8',
117+
flag: 'w',
118+
});

0 commit comments

Comments
 (0)