grammar for inspirations and developers lists
This commit is contained in:
parent
0d208dbdf7
commit
881f0c77c5
@ -5,14 +5,21 @@ http://cdetect.sourceforge.net/
|
|||||||
http://circularstudios.com/
|
http://circularstudios.com/
|
||||||
http://cyxdown.free.fr/bs/
|
http://cyxdown.free.fr/bs/
|
||||||
http://cyxdown.free.fr/f2b/
|
http://cyxdown.free.fr/f2b/
|
||||||
|
https://github.com/nfprojects/nfengine
|
||||||
http://dead-code.org/home/
|
http://dead-code.org/home/
|
||||||
http://e-adventure.e-ucm.es/login/index.php (games of eAdventure)
|
http://e-adventure.e-ucm.es/login/index.php (games of eAdventure)
|
||||||
http://ethernet.wasted.ch/
|
http://ethernet.wasted.ch/
|
||||||
http://evolonline.org/about
|
http://evolonline.org/about
|
||||||
http://game-editor.com/Main_Page
|
http://game-editor.com/Main_Page
|
||||||
http://giderosmobile.com/
|
http://giderosmobile.com/
|
||||||
|
https://github.com/skylicht-lab/skylicht-engine
|
||||||
|
https://github.com/etlegacy/etlegacy
|
||||||
|
https://github.com/Soldat/soldat
|
||||||
|
https://github.com/guillaumechereau/goxel
|
||||||
http://haxepunk.com/
|
http://haxepunk.com/
|
||||||
http://hcsoftware.sourceforge.net/jason-rohrer/ (various games there)
|
http://hcsoftware.sourceforge.net/jason-rohrer/ (various games there)
|
||||||
|
https://github.com/cxong/cdogs-sdl
|
||||||
|
https://github.com/terrafx/terrafx
|
||||||
http://hgm.nubati.net/
|
http://hgm.nubati.net/
|
||||||
http://icculus.org/
|
http://icculus.org/
|
||||||
http://icculus.org/asciiroth/
|
http://icculus.org/asciiroth/
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
start: header entry*
|
start: entry*
|
||||||
|
entry: "##" name "(" _NUMBER ")\n" property+
|
||||||
|
property: "-" _key ":" _values "\n"
|
||||||
|
_key: /(?! ).+?(?=:)(?<! )/ // key: everything until next ":", not beginning or ending with a space
|
||||||
|
_values: [_value ("," _value)*]
|
||||||
|
_value: quoted_value | unquoted_value
|
||||||
|
quoted_value: /\".+?\"/ // with quotation marks, can contain commas
|
||||||
|
unquoted_value: /(?![ \"])[^,\n]+(?<![ \"])/ // cannot contain commas, cannot start or end with quotation mark
|
||||||
|
|
||||||
header: "# " name " (" number ")\n" _E
|
name: /(?! ).+?(?= \()/ // developer name: everything until " ("
|
||||||
|
|
||||||
entry: "## " name " (" number ")\n" _E property+ _E
|
_NUMBER: /[0-9]+/
|
||||||
|
|
||||||
property: "- " _key ": " _value "\n"
|
%import common.WS
|
||||||
_key: /(?! ).+?(?=:)(?<! )/ // key: everything until next ":", not beginning or ending with a space
|
%ignore WS
|
||||||
_value: /.+(?<! )/ // everything until the end of the line, not ending with a space
|
%ignore /^\[comment\]: #.*$\n/m // [comment]: # xxx
|
||||||
|
%ignore /^# .+$\n/m // the line starting with "# "
|
||||||
name: /.+?(?= \()/ // developer name: everything until " ("
|
%ignore /^$\n/m // empty lines
|
||||||
number: /[0-9]+/
|
|
||||||
|
|
||||||
COMMENT: /^\[comment\]: #.*$\n/m // [comment]: # xxx
|
|
||||||
_E: /^$\n/m // empty new line
|
|
||||||
|
|
||||||
%ignore COMMENT
|
|
||||||
|
@ -14,6 +14,8 @@ import json
|
|||||||
import textwrap
|
import textwrap
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import utils.constants
|
||||||
from utils import constants as c, utils, osg
|
from utils import constants as c, utils, osg
|
||||||
|
|
||||||
|
|
||||||
@ -76,7 +78,7 @@ def update_readme_and_tocs(infos):
|
|||||||
|
|
||||||
# create by category
|
# create by category
|
||||||
categories_text = []
|
categories_text = []
|
||||||
for keyword in osg.recommended_keywords:
|
for keyword in utils.constants.recommended_keywords:
|
||||||
infos_filtered = [x for x in infos if keyword in x['keywords']]
|
infos_filtered = [x for x in infos if keyword in x['keywords']]
|
||||||
title = keyword.capitalize()
|
title = keyword.capitalize()
|
||||||
name = keyword.replace(' ', '-')
|
name = keyword.replace(' ', '-')
|
||||||
@ -88,7 +90,7 @@ def update_readme_and_tocs(infos):
|
|||||||
|
|
||||||
# create by platform
|
# create by platform
|
||||||
platforms_text = []
|
platforms_text = []
|
||||||
for platform in osg.valid_platforms:
|
for platform in utils.constants.valid_platforms:
|
||||||
infos_filtered = [x for x in infos if platform in x.get('platform', [])]
|
infos_filtered = [x for x in infos if platform in x.get('platform', [])]
|
||||||
title = platform
|
title = platform
|
||||||
name = platform.lower()
|
name = platform.lower()
|
||||||
@ -271,7 +273,7 @@ def fix_entries():
|
|||||||
elements = list(set(elements))
|
elements = list(set(elements))
|
||||||
|
|
||||||
# get category out
|
# get category out
|
||||||
for keyword in osg.recommended_keywords:
|
for keyword in utils.constants.recommended_keywords:
|
||||||
if keyword in elements:
|
if keyword in elements:
|
||||||
elements.remove(keyword)
|
elements.remove(keyword)
|
||||||
category = keyword
|
category = keyword
|
||||||
@ -949,12 +951,12 @@ def check_code_dependencies(infos):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# get all names of frameworks and library also using osg.code_dependencies_aliases
|
# get all names of frameworks and library also using osg.code_dependencies_aliases
|
||||||
valid_dependencies = list(osg.code_dependencies_without_entry.keys())
|
valid_dependencies = list(utils.constants.general_code_dependencies_without_entry.keys())
|
||||||
for info in infos:
|
for info in infos:
|
||||||
if any((x in ('framework', 'library', 'game engine') for x in info['keywords'])):
|
if any((x in ('framework', 'library', 'game engine') for x in info['keywords'])):
|
||||||
name = info['name']
|
name = info['name']
|
||||||
if name in osg.code_dependencies_aliases:
|
if name in utils.constants.code_dependencies_aliases:
|
||||||
valid_dependencies.extend(osg.code_dependencies_aliases[name])
|
valid_dependencies.extend(utils.constants.code_dependencies_aliases[name])
|
||||||
else:
|
else:
|
||||||
valid_dependencies.append(name)
|
valid_dependencies.append(name)
|
||||||
|
|
||||||
|
@ -6,4 +6,4 @@ if __name__ == "__main__":
|
|||||||
osg.write_inspirations_info(inspirations) # write again just to check integrity
|
osg.write_inspirations_info(inspirations) # write again just to check integrity
|
||||||
|
|
||||||
# assemble info
|
# assemble info
|
||||||
entries = osg.assemble_infos()
|
# entries = osg.assemble_infos()
|
||||||
|
@ -11,6 +11,10 @@ entries_path = os.path.join(root_path, 'entries')
|
|||||||
tocs_path = os.path.join(entries_path, 'tocs')
|
tocs_path = os.path.join(entries_path, 'tocs')
|
||||||
code_path = os.path.join(root_path, 'code')
|
code_path = os.path.join(root_path, 'code')
|
||||||
|
|
||||||
|
inspirations_file = os.path.join(root_path, 'inspirations.md')
|
||||||
|
developer_file = os.path.join(root_path, 'developer.md')
|
||||||
|
|
||||||
|
# local config
|
||||||
local_config_file = os.path.join(root_path, 'local-config.ini')
|
local_config_file = os.path.join(root_path, 'local-config.ini')
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@ -24,3 +28,68 @@ def get_config(key):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return config['general'][key]
|
return config['general'][key]
|
||||||
|
|
||||||
|
# database entry constants
|
||||||
|
generic_comment_string = '[comment]: # (partly autogenerated content, edit with care, read the manual before)'
|
||||||
|
|
||||||
|
# these fields have to be present in each entry (in this order)
|
||||||
|
essential_fields = ('Home', 'State', 'Keywords', 'Code repository', 'Code language', 'Code license')
|
||||||
|
|
||||||
|
# only these fields can be used currently (in this order)
|
||||||
|
valid_fields = (
|
||||||
|
'Home', 'Media', 'State', 'Play', 'Download', 'Platform', 'Keywords', 'Code repository', 'Code language',
|
||||||
|
'Code license', 'Code dependencies', 'Assets license', 'Developer', 'Build system', 'Build instructions')
|
||||||
|
|
||||||
|
# these are the only valid platforms currently (and must be given in this order)
|
||||||
|
valid_platforms = ('Windows', 'Linux', 'macOS', 'Android', 'iOS', 'Web')
|
||||||
|
|
||||||
|
# at least one of these must be used for every entry, this gives the principal categories and the order of the categories
|
||||||
|
recommended_keywords = (
|
||||||
|
'action', 'arcade', 'adventure', 'visual novel', 'sports', 'platform', 'puzzle', 'role playing', 'simulation',
|
||||||
|
'strategy', 'cards', 'board', 'music', 'educational', 'tool', 'game engine', 'framework', 'library', 'remake')
|
||||||
|
|
||||||
|
# known programming languages, anything else will result in a warning during a maintenance operation
|
||||||
|
# only these will be used when gathering statistics
|
||||||
|
known_languages = (
|
||||||
|
'AGS Script', 'ActionScript', 'Ada', 'AngelScript', 'Assembly', 'Basic', 'Blender Script', 'BlitzMax', 'C', 'C#',
|
||||||
|
'C++', 'Clojure', 'CoffeeScript', 'ColdFusion', 'D', 'DM', 'Dart', 'Dia', 'Elm', 'Emacs Lisp', 'F#', 'GDScript',
|
||||||
|
'Game Maker Script', 'Go', 'Groovy', 'Haskell', 'Haxe', 'Io', 'Java', 'JavaScript', 'Kotlin', 'Lisp', 'Lua',
|
||||||
|
'MegaGlest Script', 'MoonScript', 'None', 'OCaml', 'Objective-C', 'PHP', 'Pascal', 'Perl', 'Python', 'QuakeC', 'R',
|
||||||
|
"Ren'py", 'Ruby', 'Rust', 'Scala', 'Scheme', 'Script', 'Shell', 'Swift', 'TorqueScript', 'TypeScript', 'Vala',
|
||||||
|
'Visual Basic', 'XUL', 'ZenScript', 'ooc')
|
||||||
|
|
||||||
|
# known licenses, anything outside of this will result in a warning during a maintenance operation
|
||||||
|
# only these will be used when gathering statistics
|
||||||
|
known_licenses = (
|
||||||
|
'2-clause BSD', '3-clause BSD', 'AFL-3.0', 'AGPL-3.0', 'Apache-2.0', 'Artistic License-1.0', 'Artistic License-2.0',
|
||||||
|
'Boost-1.0', 'CC-BY-NC-3.0', 'CC-BY-NC-SA-2.0', 'CC-BY-NC-SA-3.0', 'CC-BY-SA-3.0', 'CC-BY-NC-SA-4.0',
|
||||||
|
'CC-BY-SA-4.0', 'CC0', 'Custom', 'EPL-2.0', 'GPL-2.0', 'GPL-3.0', 'IJG', 'ISC', 'Java Research License', 'LGPL-2.0',
|
||||||
|
'LGPL-2.1', 'LGPL-3.0', 'MAME', 'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NetHack General Public License',
|
||||||
|
'None', 'Proprietary', 'Public domain', 'SWIG license', 'Unlicense', 'WTFPL', 'wxWindows license', 'zlib')
|
||||||
|
|
||||||
|
# valid multiplayer modes (can be combined with "+" )
|
||||||
|
valid_multiplayer_modes = (
|
||||||
|
'competitive', 'co-op', 'hotseat', 'LAN', 'local', 'massive', 'matchmaking', 'online', 'split-screen')
|
||||||
|
|
||||||
|
# TODO put the abbreviations directly in the name line (parenthesis maybe), that is more natural
|
||||||
|
# this is a mapping of entry name to abbreviation and the abbreviations are used when specifying code dependencies
|
||||||
|
code_dependencies_aliases = {'Simple DirectMedia Layer': ('SDL', 'SDL2'), 'Simple and Fast Multimedia Library': ('SFML',),
|
||||||
|
'Boost (C++ Libraries)': ('Boost',), 'SGE Game Engine': ('SGE',), 'MegaGlest': ('MegaGlest Engine',)}
|
||||||
|
|
||||||
|
# these are code dependencies that won't get their own entry, because they are not centered on gaming
|
||||||
|
general_code_dependencies_without_entry = {'OpenGL': 'https://www.opengl.org/',
|
||||||
|
'GLUT': 'https://www.opengl.org/resources/libraries/',
|
||||||
|
'WebGL': 'https://www.khronos.org/webgl/',
|
||||||
|
'Unity': 'https://unity.com/solutions/game',
|
||||||
|
'.NET': 'https://dotnet.microsoft.com/', 'Vulkan': 'https://www.khronos.org/vulkan/',
|
||||||
|
'KDE Frameworks': 'https://kde.org/products/frameworks/',
|
||||||
|
'jQuery': 'https://jquery.com/',
|
||||||
|
'node.js': 'https://nodejs.org/en/',
|
||||||
|
'GNU Guile': 'https://www.gnu.org/software/guile/',
|
||||||
|
'tkinter': 'https://docs.python.org/3/library/tk.html'}
|
||||||
|
|
||||||
|
# developer information (in the file all fields will be capitalized)
|
||||||
|
valid_developer_fields = ('name', 'games', 'contact', 'organization', 'home')
|
||||||
|
|
||||||
|
# inspiration/original game information (in the file all fields will be capitalized)
|
||||||
|
valid_inspiration_fields = ('name', 'inspired entries')
|
@ -3,32 +3,54 @@ Specific functions working on the games.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
from utils import utils, constants as c
|
from utils import utils
|
||||||
import lark
|
import lark
|
||||||
|
|
||||||
|
from utils.constants import *
|
||||||
|
|
||||||
|
|
||||||
class ListingTransformer(lark.Transformer):
|
class ListingTransformer(lark.Transformer):
|
||||||
|
"""
|
||||||
|
Transforms content parsed by grammar_listing.lark further.
|
||||||
|
Used for the developer and inspirations list.
|
||||||
|
"""
|
||||||
|
|
||||||
def number(self, x):
|
def unquoted_value(self, x):
|
||||||
raise lark.Discard
|
return x[0].value
|
||||||
|
|
||||||
|
def quoted_value(self, x):
|
||||||
|
return x[0].value[1:-1] # remove quotation marks
|
||||||
|
|
||||||
def property(self, x):
|
def property(self, x):
|
||||||
return x[0].value.lower(), x[1].value
|
"""
|
||||||
|
The key of a property will be converted to lower case and the value part is the second part
|
||||||
|
:param x:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return x[0].lower(), x[1:]
|
||||||
|
|
||||||
def name(self, x):
|
def name(self, x):
|
||||||
|
"""
|
||||||
|
The name part is treated as a property with key "name"
|
||||||
|
:param x:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
return 'name', x[0].value
|
return 'name', x[0].value
|
||||||
|
|
||||||
def entry(self, x):
|
def entry(self, x):
|
||||||
|
"""
|
||||||
|
All (key, value) tuples are inserted into a dictionary.
|
||||||
|
:param x:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
d = {}
|
d = {}
|
||||||
for key, value in x:
|
for key, value in x:
|
||||||
|
if key in d:
|
||||||
|
raise RuntimeError('Key in entry appears twice')
|
||||||
d[key] = value
|
d[key] = value
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def header(self, x):
|
|
||||||
raise lark.Discard
|
|
||||||
|
|
||||||
def start(self, x):
|
def start(self, x):
|
||||||
return x
|
return x
|
||||||
|
|
||||||
@ -61,53 +83,9 @@ class EntryTransformer(lark.Transformer):
|
|||||||
return 'building', d
|
return 'building', d
|
||||||
|
|
||||||
|
|
||||||
essential_fields = ('Home', 'State', 'Keywords', 'Code repository', 'Code language', 'Code license')
|
|
||||||
valid_fields = (
|
|
||||||
'Home', 'Media', 'State', 'Play', 'Download', 'Platform', 'Keywords', 'Code repository', 'Code language',
|
|
||||||
'Code license', 'Code dependencies', 'Assets license', 'Developer', 'Build system', 'Build instructions')
|
|
||||||
valid_platforms = ('Windows', 'Linux', 'macOS', 'Android', 'iOS', 'Web')
|
|
||||||
recommended_keywords = (
|
|
||||||
'action', 'arcade', 'adventure', 'visual novel', 'sports', 'platform', 'puzzle', 'role playing', 'simulation',
|
|
||||||
'strategy', 'cards', 'board', 'music', 'educational', 'tool', 'game engine', 'framework', 'library', 'remake')
|
|
||||||
known_languages = (
|
|
||||||
'AGS Script', 'ActionScript', 'Ada', 'AngelScript', 'Assembly', 'Basic', 'Blender Script', 'BlitzMax', 'C', 'C#',
|
|
||||||
'C++', 'Clojure', 'CoffeeScript', 'ColdFusion', 'D', 'DM', 'Dart', 'Dia', 'Elm', 'Emacs Lisp', 'F#', 'GDScript',
|
|
||||||
'Game Maker Script', 'Go', 'Groovy', 'Haskell', 'Haxe', 'Io', 'Java', 'JavaScript', 'Kotlin', 'Lisp', 'Lua',
|
|
||||||
'MegaGlest Script', 'MoonScript', 'None', 'OCaml', 'Objective-C', 'PHP', 'Pascal', 'Perl', 'Python', 'QuakeC', 'R',
|
|
||||||
"Ren'py", 'Ruby', 'Rust', 'Scala', 'Scheme', 'Script', 'Shell', 'Swift', 'TorqueScript', 'TypeScript', 'Vala',
|
|
||||||
'Visual Basic', 'XUL', 'ZenScript', 'ooc')
|
|
||||||
known_licenses = (
|
|
||||||
'2-clause BSD', '3-clause BSD', 'AFL-3.0', 'AGPL-3.0', 'Apache-2.0', 'Artistic License-1.0', 'Artistic License-2.0',
|
|
||||||
'Boost-1.0', 'CC-BY-NC-3.0', 'CC-BY-NC-SA-2.0', 'CC-BY-NC-SA-3.0', 'CC-BY-SA-3.0', 'CC-BY-NC-SA-4.0',
|
|
||||||
'CC-BY-SA-4.0',
|
|
||||||
'CC0', 'Custom', 'EPL-2.0', 'GPL-2.0', 'GPL-3.0', 'IJG', 'ISC', 'Java Research License', 'LGPL-2.0', 'LGPL-2.1',
|
|
||||||
'LGPL-3.0', 'MAME', 'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NetHack General Public License', 'None',
|
|
||||||
'Proprietary', 'Public domain', 'SWIG license', 'Unlicense', 'WTFPL', 'wxWindows license', 'zlib')
|
|
||||||
known_multiplayer_modes = (
|
|
||||||
'competitive', 'co-op', 'hotseat', 'LAN', 'local', 'massive', 'matchmaking', 'online', 'split-screen')
|
|
||||||
|
|
||||||
# TODO put the abbreviations directly in the name line (parenthesis maybe), that is more natural
|
|
||||||
code_dependencies_aliases = {'Simple DirectMedia Layer': ('SDL', 'SDL2'), 'Simple and Fast Multimedia Library': ('SFML',),
|
|
||||||
'Boost (C++ Libraries)': ('Boost',), 'SGE Game Engine': ('SGE',), 'MegaGlest': ('MegaGlest Engine',)}
|
|
||||||
code_dependencies_without_entry = {'OpenGL': 'https://www.opengl.org/',
|
|
||||||
'GLUT': 'https://www.opengl.org/resources/libraries/',
|
|
||||||
'WebGL': 'https://www.khronos.org/webgl/',
|
|
||||||
'Unity': 'https://unity.com/solutions/game',
|
|
||||||
'.NET': 'https://dotnet.microsoft.com/', 'Vulkan': 'https://www.khronos.org/vulkan/',
|
|
||||||
'KDE Frameworks': 'https://kde.org/products/frameworks/',
|
|
||||||
'jQuery': 'https://jquery.com/',
|
|
||||||
'node.js': 'https://nodejs.org/en/',
|
|
||||||
'GNU Guile': 'https://www.gnu.org/software/guile/',
|
|
||||||
'tkinter': 'https://docs.python.org/3/library/tk.html'}
|
|
||||||
|
|
||||||
regex_sanitize_name = re.compile(r"[^A-Za-z 0-9-+]+")
|
regex_sanitize_name = re.compile(r"[^A-Za-z 0-9-+]+")
|
||||||
regex_sanitize_name_space_eater = re.compile(r" +")
|
regex_sanitize_name_space_eater = re.compile(r" +")
|
||||||
|
|
||||||
valid_developer_fields = ('name', 'games', 'contact', 'organization', 'home')
|
|
||||||
valid_inspiration_fields = ('name', 'inspired entries')
|
|
||||||
|
|
||||||
comment_string = '[comment]: # (partly autogenerated content, edit with care, read the manual before)'
|
|
||||||
|
|
||||||
|
|
||||||
def name_similarity(a, b):
|
def name_similarity(a, b):
|
||||||
return SequenceMatcher(None, str.casefold(a), str.casefold(b)).ratio()
|
return SequenceMatcher(None, str.casefold(a), str.casefold(b)).ratio()
|
||||||
@ -130,11 +108,11 @@ def entry_iterator():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# get all entries (ignore everything starting with underscore)
|
# get all entries (ignore everything starting with underscore)
|
||||||
entries = os.listdir(c.entries_path)
|
entries = os.listdir(entries_path)
|
||||||
|
|
||||||
# iterate over all entries
|
# iterate over all entries
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
entry_path = os.path.join(c.entries_path, entry)
|
entry_path = os.path.join(entries_path, entry)
|
||||||
|
|
||||||
# ignore directories ("tocs" for example)
|
# ignore directories ("tocs" for example)
|
||||||
if os.path.isdir(entry_path):
|
if os.path.isdir(entry_path):
|
||||||
@ -350,8 +328,8 @@ def assemble_infos():
|
|||||||
# we also allow -X with X =2..9 as possible extension (because of duplicate canonical file names)
|
# we also allow -X with X =2..9 as possible extension (because of duplicate canonical file names)
|
||||||
if canonical_file_name != entry and canonical_file_name != entry[:-5] + '.md':
|
if canonical_file_name != entry and canonical_file_name != entry[:-5] + '.md':
|
||||||
print('Warning: file {} should be {}'.format(entry, canonical_file_name))
|
print('Warning: file {} should be {}'.format(entry, canonical_file_name))
|
||||||
source_file = os.path.join(c.entries_path, entry)
|
source_file = os.path.join(entries_path, entry)
|
||||||
target_file = os.path.join(c.entries_path, canonical_file_name)
|
target_file = os.path.join(entries_path, canonical_file_name)
|
||||||
if not os.path.isfile(target_file):
|
if not os.path.isfile(target_file):
|
||||||
pass
|
pass
|
||||||
# os.rename(source_file, target_file)
|
# os.rename(source_file, target_file)
|
||||||
@ -390,9 +368,10 @@ def extract_links():
|
|||||||
return urls
|
return urls
|
||||||
|
|
||||||
|
|
||||||
def read_and_parse(content_file, grammar_file, transformer):
|
def read_and_parse(content_file: str, grammar_file: str, transformer: lark.Transformer):
|
||||||
"""
|
"""
|
||||||
|
Reads a content file and a grammar file and parses the content with the grammar following by
|
||||||
|
transforming the parsed output and returning the transformed result.
|
||||||
:param content_file:
|
:param content_file:
|
||||||
:param grammar_file:
|
:param grammar_file:
|
||||||
:param transformer:
|
:param transformer:
|
||||||
@ -410,8 +389,7 @@ def read_developer_info():
|
|||||||
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
developer_file = os.path.join(c.root_path, 'developer.md')
|
grammar_file = os.path.join(code_path, 'grammar_listing.lark')
|
||||||
grammar_file = os.path.join(c.code_path, 'grammar_listing.lark')
|
|
||||||
transformer = ListingTransformer()
|
transformer = ListingTransformer()
|
||||||
developers = read_and_parse(developer_file, grammar_file, transformer)
|
developers = read_and_parse(developer_file, grammar_file, transformer)
|
||||||
# now transform a bit more
|
# now transform a bit more
|
||||||
@ -446,7 +424,7 @@ def write_developer_info(developers):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# comment
|
# comment
|
||||||
content = '{}\n'.format(comment_string)
|
content = '{}\n'.format(generic_comment_string)
|
||||||
|
|
||||||
# number of developer
|
# number of developer
|
||||||
content += '# Developer ({})\n\n'.format(len(developers))
|
content += '# Developer ({})\n\n'.format(len(developers))
|
||||||
@ -474,22 +452,26 @@ def write_developer_info(developers):
|
|||||||
content += '\n'
|
content += '\n'
|
||||||
|
|
||||||
# write
|
# write
|
||||||
developer_file = os.path.join(c.root_path, 'developer.md')
|
|
||||||
utils.write_text(developer_file, content)
|
utils.write_text(developer_file, content)
|
||||||
|
|
||||||
|
|
||||||
def read_inspirations_info():
|
def read_inspirations_info():
|
||||||
"""
|
"""
|
||||||
|
Reads the info list about the games originals/inspirations from inspirations.md using the Lark parser grammar
|
||||||
|
in grammar_listing.lark
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
inspirations_file = os.path.join(c.root_path, 'inspirations.md')
|
# read inspirations
|
||||||
grammar_file = os.path.join(c.code_path, 'grammar_listing.lark')
|
|
||||||
|
grammar_file = os.path.join(code_path, 'grammar_listing.lark')
|
||||||
transformer = ListingTransformer()
|
transformer = ListingTransformer()
|
||||||
inspirations = read_and_parse(inspirations_file, grammar_file, transformer)
|
inspirations = read_and_parse(inspirations_file, grammar_file, transformer)
|
||||||
|
|
||||||
|
# now inspirations is a list of dictionaries for every entry with keys (valid_developers_fields)
|
||||||
|
|
||||||
# now transform a bit more
|
# now transform a bit more
|
||||||
for index, inspiration in enumerate(inspirations):
|
for index, inspiration in enumerate(inspirations):
|
||||||
# check for valid keys
|
# check that keys are valid keys
|
||||||
for field in inspiration.keys():
|
for field in inspiration.keys():
|
||||||
if field not in valid_inspiration_fields:
|
if field not in valid_inspiration_fields:
|
||||||
raise RuntimeError('Unknown field "{}" for inspiration: {}.'.format(field, inspiration['name']))
|
raise RuntimeError('Unknown field "{}" for inspiration: {}.'.format(field, inspiration['name']))
|
||||||
@ -497,26 +479,27 @@ def read_inspirations_info():
|
|||||||
for field in ('inspired entries',):
|
for field in ('inspired entries',):
|
||||||
if field in inspiration:
|
if field in inspiration:
|
||||||
content = inspiration[field]
|
content = inspiration[field]
|
||||||
content = content.split(',')
|
|
||||||
content = [x.strip() for x in content]
|
content = [x.strip() for x in content]
|
||||||
inspiration[field] = content
|
inspiration[field] = content
|
||||||
|
|
||||||
# check for duplicate names entries
|
# check for duplicate names entries
|
||||||
names = [inspiration['name'] for inspiration in inspirations]
|
names = [inspiration['name'] for inspiration in inspirations]
|
||||||
duplicate_names = (name for name in names if names.count(name) > 1)
|
duplicate_names = (name for name in names if names.count(name) > 1)
|
||||||
duplicate_names = set(duplicate_names) # to avoid duplicates in duplicate_names
|
duplicate_names = set(duplicate_names) # to avoid duplicates in duplicate_names
|
||||||
if duplicate_names:
|
if duplicate_names:
|
||||||
print('Warning: duplicate inspiration names: {}'.format(', '.join(duplicate_names)))
|
print('Warning: duplicate inspiration names: {}'.format(', '.join(duplicate_names)))
|
||||||
|
|
||||||
return inspirations
|
return inspirations
|
||||||
|
|
||||||
|
|
||||||
def write_inspirations_info(inspirations):
|
def write_inspirations_info(inspirations):
|
||||||
"""
|
"""
|
||||||
|
Given an internal list of inspirations, write it into the inspirations file
|
||||||
:param inspirations:
|
:param inspirations:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
# comment
|
# comment
|
||||||
content = '{}\n'.format(comment_string)
|
content = '{}\n'.format(generic_comment_string)
|
||||||
|
|
||||||
# number of developer
|
# number of developer
|
||||||
content += '# Inspirations ({})\n\n'.format(len(inspirations))
|
content += '# Inspirations ({})\n\n'.format(len(inspirations))
|
||||||
@ -545,7 +528,6 @@ def write_inspirations_info(inspirations):
|
|||||||
content += '\n'
|
content += '\n'
|
||||||
|
|
||||||
# write
|
# write
|
||||||
inspirations_file = os.path.join(c.root_path, 'inspirations2.md')
|
|
||||||
utils.write_text(inspirations_file, content)
|
utils.write_text(inspirations_file, content)
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
## Achtung die Kurve! (3)
|
## Achtung die Kurve! (3)
|
||||||
|
|
||||||
- Inspired entries: Achtung, die Kurve!, Netacka, Zatacka X
|
- Inspired entries: "Achtung, die Kurve!", Netacka, Zatacka X
|
||||||
|
|
||||||
## Advance Wars (1)
|
## Advance Wars (1)
|
||||||
|
|
||||||
@ -1311,7 +1311,7 @@
|
|||||||
|
|
||||||
## RARS (1)
|
## RARS (1)
|
||||||
|
|
||||||
- Inspired entries: TORCS, The Open Racing Car Simulator
|
- Inspired entries: "The Open Racing Car Simulator, TORCS"
|
||||||
|
|
||||||
## Redneck Rampage (1)
|
## Redneck Rampage (1)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user