Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate generation of udl-list.md #203

Merged
merged 33 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
78b4a70
add optional boolean attribute "autoCompletion" to the UDLs definitio…
pryrt Nov 4, 2023
57ab491
test autoCompletion key for existence
pryrt Nov 4, 2023
d6f894e
rework key-existence check
pryrt Nov 4, 2023
93de0ec
look for autoCompletion file, if autoCompletion==true
pryrt Nov 4, 2023
b1ba499
fix else syntax
pryrt Nov 4, 2023
9fe2afc
improve autoCompletion logging
pryrt Nov 4, 2023
ad03f7f
fix typo
pryrt Nov 4, 2023
081a6d8
allow autoCompletion either as boolean or a string
pryrt Nov 4, 2023
54d6d02
add print to debug most recent error
pryrt Nov 4, 2023
881f73d
fix case, because `str(true) == "True"`
pryrt Nov 4, 2023
501904a
fix to `"autoCompletion": "vkosuri-robotframework"`
pryrt Nov 4, 2023
b34dcb9
fix double-xml in "also confirmed" printout
pryrt Nov 4, 2023
ef497a6
Sort the auto-generated udl-list.md
pryrt Nov 5, 2023
c5619df
fix the sorter
pryrt Nov 5, 2023
fe9109f
printing doesn't work
pryrt Nov 5, 2023
6d9b9fa
move markdown generator from validator_json to a separate action
pryrt Nov 5, 2023
793938c
fix EOL typo
pryrt Nov 5, 2023
5e6b544
append autoCompletion definitions
pryrt Nov 5, 2023
60ab2fd
debug
pryrt Nov 5, 2023
ce0e1cc
debug syntax error
pryrt Nov 5, 2023
7ab3222
fix missing close paren
pryrt Nov 5, 2023
645a705
fix the syntax errors locally
pryrt Nov 5, 2023
41070f8
clean up the generator
pryrt Nov 5, 2023
c181d68
add autoCompletionAuthor field
pryrt Nov 5, 2023
3acba8d
see if I can automatically update udl-list
pryrt Nov 5, 2023
deed0af
Automatically re-build udl-list.md
pryrt Nov 5, 2023
adfe820
work on all branches; artifact not needed
pryrt Nov 5, 2023
a33168c
fix on-push-branches syntax
pryrt Nov 5, 2023
3499755
remove debug print statement from generate_markdown.py
pryrt Nov 5, 2023
de20469
re-merge the validator and markdown generator into one action
pryrt Nov 5, 2023
18185e8
Automatically re-build udl-list.md
pryrt Nov 5, 2023
0fd328a
fix header; always end file in newline
pryrt Nov 5, 2023
edeeadb
Automatically re-build udl-list.md
pryrt Nov 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions .github/workflows/CI_build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI_build

on: [push, pull_request]
on: [push, pull_request, workflow_dispatch]

jobs:
build:
Expand All @@ -19,13 +19,17 @@ jobs:
working-directory: .
run: python .validators\validator_xml.py

- name: Validate json
- name: Validate json and rebuild udl-list.md
working-directory: .
run: python .validators\validator_json.py

- name: Archive artifacts udl markdown
uses: actions/upload-artifact@v3
- uses: stefanzweifel/git-auto-commit-action@v5
with:
name: markdown_udl_list
path: udl-list.md
commit_message: Automatically re-build udl-list.md

#- name: Archive artifacts udl markdown
# uses: actions/upload-artifact@v3
# with:
# name: markdown_udl_list
# path: udl-list.md

12 changes: 11 additions & 1 deletion .validators/udl.schema
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,18 @@
{"type": "string", "maxLength": 0},
{"format": "uri"}
]
},
"autoCompletion": {
"oneOf": [
{ "type": "boolean" },
{ "type": "string", "minLength": 1}
]
},
"autoCompletionAuthor": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
114 changes: 108 additions & 6 deletions .validators/validator_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
tmpl_tr_b = '| '
tmpl_td = ' | '
tmpl_tr_e = ' |'
tmpl_tab_head = '''|Name | Author | Description |
tmpl_tab_head = '''| Name | Author | Description |
|-----|--------|-------------|
'''

Expand Down Expand Up @@ -60,31 +60,108 @@ def rest_of_text(description):
return description[len(first_two_lines(description)):]

def gen_pl_table(filename):
udlfile = json.loads(open(filename, encoding="utf8").read())
tab_text = "## UDL list%s" % (tmpl_new_line)
tab_text += "version %s%s" % (udlfile["version"], tmpl_new_line)
try:
udlfile = json.loads(open(filename, encoding="utf8").read())
except ValueError as e:
post_error(filename + " - " + str(e))
return

tab_text = "## UDL Definitions%s%s" % (tmpl_new_line, tmpl_new_line)
# tab_text += "version %s%s" % (udlfile["version"], tmpl_new_line)
tab_text += tmpl_tab_head

ac_list = []

# UDL Name = (ij.display-name)ij.id-name.xml or repolink
# Author = ij.author
# Description = " <details> <summary> " + first_two_lines(ij.description) + " </summary> " rest_of_text(ij.description) +"</details>"
for udl in udlfile["UDLs"]:
for udl in sorted(udlfile["UDLs"], key=lambda d: d['display-name'].casefold()):
# link to either repo or local copy of XML
udl_link = udl["repository"]
if not udl_link:
udl_link = "./UDLs/" + udl["id-name"] + ".xml"
tab_line = tmpl_tr_b + "[" + udl["display-name"] +"](" + udl_link + ")" + tmpl_td + udl["author"] + tmpl_td

# author name (with optional link to homepage)
mailto = ""
if ' <mailto:' in udl["author"]:
p = udl["author"].find(' <mailto:')
m = p + 2
e = udl["author"].find('>', p)
mailto = udl["author"][m:e]
author = udl["author"][:p]
else:
author = udl["author"]

if 'homepage' in udl:
author = "[%s](%s)" % (author, udl["homepage"])
elif mailto:
author = "[%s](%s)" % (author, mailto)

# concat name and author
tab_line = tmpl_tr_b + "[" + udl["display-name"] +"](" + udl_link + ")" + tmpl_td + author + tmpl_td

# grab description, and summarize if it's long...
descr = udl["description"]
descr = descr.replace(c_line_feed, tmpl_br).replace(c_line_break, '').replace("|", tmpl_vert)
summary = first_two_lines(descr)
rest = rest_of_text(descr)

# add description to the current table row
if summary:
tab_line += " <details> <summary> %s </summary> %s </details>" % (summary, rest)
else:
tab_line += rest
tab_line += tmpl_tr_e + tmpl_new_line
tab_text += tab_line

# if this entry has autoCompletion defined, add it to the list of autoCompletions
if "autoCompletion" in udl:
if udl["autoCompletion"]:
if str(udl["autoCompletion"]) == "True":
ac_link = udl["id-name"] + ".xml"
elif udl["autoCompletion"][0:4] == "http":
ac_link = udl["autoCompletion"]
else:
ac_link = str(udl["autoCompletion"]) + ".xml"

# print(f'autoCompletion: {udl["autoCompletion"]} => {ac_link}')
# absolute path for existence testing
ac_link_abs = Path(os.path.join(os.getcwd(),"autoCompletions", ac_link))

# relative path for correct linking
ac_link = "./autoCompletions/%s" % (ac_link)

# TODO: use autoCompletionAuthor field if the autoCompletion has a different author than the UDL (like for RenderMan)
if "autoCompletionAuthor" in udl:
if udl["autoCompletionAuthor"]:
author = udl["autoCompletionAuthor"]
mailto = ""
if ' <mailto:' in udl["autoCompletionAuthor"]:
p = udl["autoCompletionAuthor"].find(' <mailto:')
m = p + 2
e = udl["autoCompletionAuthor"].find('>', p)
mailto = udl["autoCompletionAuthor"][m:e]
author = udl["autoCompletionAuthor"][:p]

# append to list if it exists, otherwise give error
if not ("http:" in ac_link or "https:" in ac_link) and not ac_link_abs.exists():
print(f'ac_link = {ac_link}')
post_error(f'{udl["display-name"]}: autoCompletion file missing from repo: JSON id-name expects it at filename="{ac_link}"')
else:
ac_list.append(tmpl_tr_b + "[" + udl["display-name"] +"](" + ac_link + ")" + tmpl_td + author + tmpl_td + udl["description"] + tmpl_tr_e)

# add the Auto-Completion Definitions in a separate table at the end
tab_text += tmpl_new_line
tab_text += "## Auto-Completion Definitions%s%s" % (tmpl_new_line, tmpl_new_line)
tab_text += tmpl_tab_head
tab_text += tmpl_new_line.join(ac_list)

# always end the file with a newline
tab_text += tmpl_new_line

return tab_text


def parse(filename):
try:
schema = json.loads(open(".validators/udl.schema").read())
Expand Down Expand Up @@ -159,6 +236,31 @@ def parse(filename):
if found == False:
repositories.append(udl["repository"])

# look at optional autoCompletion
if "autoCompletion" in udl:
# print(f'\tautoCompletion: {udl["autoCompletion"]}')
if udl["autoCompletion"]:
if str(udl["autoCompletion"]) == "True":
ac_link = udl["id-name"] + ".xml"
elif udl["autoCompletion"][0:4] == "http":
ac_link = udl["autoCompletion"]
else:
ac_link = str(udl["autoCompletion"]) + ".xml"
ac_link_abs = Path(os.path.join(os.getcwd(),"autoCompletions", ac_link))

if ac_link[0:4] == "http":
try:
response = requests.get(ac_link)
print(f'-> also confirmed autoCompletion URL: {ac_link}')
except requests.exceptions.RequestException as e:
post_error(str(e))
continue
elif not ac_link_abs.exists():
post_error(f'{udl["display-name"]}: autoCompletion file missing from repo: JSON id-name expects it at filename="autoCompletions/{ac_link}"')
else:
print(f'-> also confirmed "autoCompletions/{ac_link}"')


parse("udl-list.json")
with open("udl-list.md", "w", encoding="utf8") as md_file:
md_file.write(gen_pl_table("udl-list.json"))
Expand Down
41 changes: 21 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
The goal of this Collection is to provide a UDL center for users who need the programming languages which are not supported directly by Notepad++. Any UDL author can submit their UDL (with an explicit name - "id-name") in `UDLs` directory so users can find what they want from `UDLs` directory very easily. However, it is possible that some UDL authors prefer to keep files in their repository rather than submitting files into official User Defined Languages repository (https://github.com/notepad-plus-plus/userDefinedLanguages/UDLs/). They can still submit the URL of their UDL in question.
The goal of this Collection is to provide a UDL center for users who need the programming languages which are not supported directly by Notepad++. Any UDL author can submit their UDL (with an explicit name - "id-name") in `UDLs` directory so users can find what they want from `UDLs` directory very easily. When submitting a UDL to the Collection, the author may either upload the XML file, or just supply a link their own repository's copy of the UDL definition XML file.

In both cases you have to modify [udl-list.json](https://github.com/notepad-plus-plus/userDefinedLanguages/blob/master/udl-list.json) and [udl-list.md](https://github.com/notepad-plus-plus/userDefinedLanguages/blob/master/udl-list.md), submit a Pull Request to add it to the Collection. The team will review your submission, and either merge it into the Collection, ask for clarification or fixes, or reject the submission.
You may also optionally submit an Auto-Completion definition to go with your UDL (or to go with someone else's UDL).

To submit a UDL and/or autoCompletion definition, you have to modify [udl-list.json](https://github.com/notepad-plus-plus/userDefinedLanguages/blob/master/udl-list.json), then submit a Pull Request to add it to the Collection. The team will review your submission, and either merge it into the Collection, ask for clarification or fixes, or reject the submission. (The [udl-list.md](https://github.com/notepad-plus-plus/userDefinedLanguages/blob/master/udl-list.md), which you used to also have to edit, is now auto-generated to save effort and maintain consistency.)


## Some rules and recommendation of submission
Expand All @@ -19,36 +21,35 @@ To be accepted, your submission _must_ meet the following **requirement**s and _
4. **recommendation**: if your UDL file only contains one language, the `display-name` attribute in the JSON file (described below) should have the same value as the `<UserLang name="...">` inside your definition file. This will keep the name in the **Language** menu the same as the name that was shown in the download tool (coming soon).
5. **recommendation**: in your Pull Request, please provide a link to a public description of the language your UDL is based on (which will help to establish the general-interest nature of the UDL), as well as a link to an example file in that language (so that the UDL can be verified as functional).
* If you have an example file, you can upload it to the `UDL-samples` folder of the repository. Please have this file use the same name as your UDL definition file, but with the appropriate file extension, rather than `.xml`. Example: `UDLs\STL_udl.byPryrt.xml` would have a corresponding example file `UDL-samples\STL_udl.byPryrt.stl`.
6. **recommendation**: if you have also created an [autoCompletion file](https://npp-user-manual.org/docs/auto-completion/) for your UDL, you may add it in the `autoCompletions` folder before you submit your PR, using a similar naming scheme to the UDL's XML filename.
6. **recommendation**: if you have also created an [autoCompletion file](https://npp-user-manual.org/docs/auto-completion/) for your UDL, you may add it in the `autoCompletions` folder before you submit your PR, using a similar naming scheme to the UDL's XML filename.

## Edit `udl-list.json`

When you make a submission, you should edit the [udl-list.json](https://github.com/notepad-plus-plus/userDefinedLanguages/blob/master/udl-list.json) file, following these definitions:
* The `id-name` attribute will match the name of the UDL file, without the `.xml`.
* The `display-name` attribute will match the `<UserLang name="...">` from the submitted UDL file, if possible.
* The `version` attribute can have a `v1.00`-style version or just a last-edited date like `2020-Jan-12`.
* The `repository` attribute will be left blank for UDL files uploaded to this repository; if the UDL resides in an external repository (or if you want to add a link to the original source file, but still keep a copy in this repository), use this attribute to hold the full URL of the external file
* The `description` attribute is an optional description of the UDL language (it could be the based on the `id-name` or `display-name`, but with spaces instead of underscores, hyphens, and/or periods).
* The `author` attribute should be your name or GitHub username or email address.
* The `homepage` attribute could be a link to your GitHub repository for the UDL language or your GitHub user page.


## Edit `udl-list.md`
- The `id-name` attribute will match the name of the UDL file, without the `.xml`.
- The `display-name` attribute will match the `<UserLang name="...">` from the submitted UDL file, if possible.
- The `version` attribute can have a `v1.00`-style version or just a last-edited date like `2020-Jan-12`.
- The `repository` attribute will be left blank for UDL files uploaded to this repository; if the UDL resides in an external repository (or if you want to add a link to the original source file, but still keep a copy in this repository), use this attribute to hold the full URL of the external file
- The `description` attribute is an optional description of the UDL language (it could be the based on the `id-name` or `display-name`, but with spaces instead of underscores, hyphens, and/or periods).
- The `author` attribute should be your name or GitHub username or email address.
- The `homepage` attribute could be a link to your GitHub repository for the UDL language or your GitHub user page.
- The `autoCompletion` attribute should be included if you are supplying an autoCompletion file. It can either be a Boolean (`true` or `false`), or it can be a string.
- If it's `true`, then it will use the same file name as the UDL's .xml, but in the `autoCompletions/` directory instead of the `UDLs/` directory.
- If it's a string, it can either be the name of the autoCompletion file (without the `.xml`, similar to the `id-name` entry), or the URL to the external file (similar to the `repository` attribute).
- If it is `false` or not supplied, then it indicates there is no autoCompletion file in the submission.
- The `autoCompletionAuthor` attribute should be set to the name of the author of the autoCompletion definition, if it's a different author than the UDL.
- For example, the [RenderMan UDL](./UDLs/RenderMan-RSL_byStefanGustavson.xml) was written by Stefan Gustavson, but the [RenderMan autoCompletion](./autoCompletions/RenderMan-RSL_by-focus_gfx.xml) was supplied by focus_gfx, so `autoCompletionAuthor` is set in order to give proper credit to both.

[udl-list.md](https://github.com/notepad-plus-plus/userDefinedLanguages/blob/master/udl-list.md) is UDL user interface file which shows all available UDL files and their location (URL) so user can download needed UDL directly from it.
* `Name` : The name of the UDL (based on the `display-name` attribute from above). This should be input as a Markdown link to the main file: the text of the link should be the language name; the URL should point to the uploaded (or external) UDL XML file.
* `Description` : The details of this UDL: most likely, the same as the `description` attribute from above.
* `Author` : Author name. If the `homepage` is known, the author's name should link to the `homepage` of the author.

## Validation

The maintenance team will be checking the UDL file and both udl-list.json & udl-list.md or conformance to these requirements. By submitting the Pull Request, you are giving permission for edits to help it match the requirements. If you need help with the JSON, please ask for help in the Pull Request, and be willing and available to answer questions for clarifications so that you can be helped.
The maintenance team will be checking the UDL definition file, `udl-list.json`, and the autoCompletion definition (if supplied) for conformance to these requirements. By submitting the Pull Request, you are giving permission for edits to help it match the requirements, and you may be asked to make changes yourself. If you need help with the JSON, please ask for help in the Pull Request, and be willing and available to answer questions for clarifications so that you can be helped.

## HOW TO Submit Pull Request

Since many contributors are not GitHub experts, we have added in this section to make it easier for you to submit your files in a Pull Request (PR)

0. Create a GitHub account
0. Create a GitHub account
- Without an account, you cannot submit a PR
2. Create a **fork** of the userDefinedLanguages Collection
- Click the **Fork** label/icon from the [main UDL Collection page](https://github.com/notepad-plus-plus/userDefinedLanguages)
Expand All @@ -59,6 +60,6 @@ Since many contributors are not GitHub experts, we have added in this section to
- Edit the `udl-list.md` and `udl-list.json` _in your fork_, per the rules defined above
4. Create a PR from your fork
- from your fork's master branch, after you've made the changes above,
- click the down arrow on **Contribute**
- click the down arrow on **Contribute**
- select **Open Pull Request**
- fill out your description for the PR, and submit the PR
Loading