kernpy 1.0.0__py3-none-any.whl → 1.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
kernpy/__init__.py CHANGED
@@ -4,7 +4,7 @@
4
4
  =====
5
5
 
6
6
 
7
- Python Humdrum kern and mens utilities package.
7
+ Python Humdrum **kern and **mens utilities package.
8
8
 
9
9
 
10
10
 
@@ -13,191 +13,6 @@ Execute the following command to run **kernpy** as a module:
13
13
  python -m kernpy --help
14
14
  python -m kernpy <command> <options>
15
15
  ```
16
-
17
- Run `kernpy` from your script:
18
- ```python
19
- import kernpy
20
-
21
- help(kernpy)
22
- ```
23
-
24
- While the package is not published in `pip`, the `kernpy` module must be in the root directory.
25
-
26
- ## 🎯 **kern2ekern**: Convertir un solo archivo .krn a .ekern:
27
-
28
- ```bash
29
- python -m kernpy --kern2ekern --input_path <input_file> <v | --verbose [0-2]>
30
- ```
31
-
32
- The command has the following arguments:
33
- * **input_path**: Ruta del archivo .krn a convertir.
34
- * **output_path**: Ruta del archivo .ekern a generar (opcional). Si no se especifica, se generará en la misma ubicación.
35
- * **-r**: Recursivo (opcional).
36
- * **--verbose[0-2]**: Nivel de verbosidad (opcional).
37
-
38
-
39
- 📌 Basic usage running **kernpy** as a module:
40
- ```shell
41
- python -m kernpy --input_path /my/path/to/file.krn # New ekern generated in /my/path/to/file.ekern
42
- ```
43
-
44
- 📌 Generate an _ekrn_ file in specific location running **kernpy** as a module:
45
- ```shell
46
- python -m kernpy --input_path /my/path/to/file.krn --output_path /new/output.ekern
47
- ```
48
-
49
- 📌 Converting all the .krn files in a directory to .ekern files running **kernpy** as a module:
50
- * Every .krn file in the directory will be converted to .ekern in the same location.
51
- * Using, at least, one additional directory level is required.
52
- ```
53
- root
54
- ├─ kern-folder
55
- │   ├── 1.krn
56
- │   ├── 2.krn
57
- │   └── 3.krn
58
- ├── more-kerns
59
- │   ├── 1.krn
60
- │   ├── ...
61
- ```
62
- Run:
63
- ```shell
64
- python -m kernpy --input_path /my/path/to/directory/ -r
65
- ```
66
-
67
- ✏️ This function is also available as a python function:
68
- ```python
69
- # converter.py
70
- from kernpy import kern_to_ekern
71
-
72
- kern_to_ekern('/my/path/to/input.krn', '/to/my/output.ekrn')
73
-
74
- # Many files
75
- files = ['file1.krn', 'file2.krn', 'file3.krn']
76
- [kern_to_ekern(f) for f in files]
77
-
78
- # This function raises an exception if the conversion fails.
79
- # Handle the errors using try-except statement if many files are going to be converted in series.
80
- ```
81
-
82
- ****************************************************************************************
83
- ## 🎯 **ekern2kern**: Convertir un solo archivo .ekern a .krn:
84
-
85
- ```bash
86
- python -m kernpy --ekern2kern --input_path <input_file> <--verbose [0-2]>
87
- ```
88
-
89
- The command has the following arguments:
90
- * **input_path**: Ruta del archivo .ekern a convertir.
91
- * **output_path**: Ruta del archivo .krn a generar (opcional). Si no se especifica, se generará en la misma ubicación.
92
- * **-r**: Recursivo (opcional).
93
- * **--verbose[0-2]**: Nivel de verbosidad (opcional).
94
-
95
- * Basic usage running **kernpy** as a module:
96
- ```shell
97
- python -m kernpy --input_path /my/path/to/file.ekern # New krn generated in /my/path/to/file.krn
98
- ```
99
-
100
- 📌 Generate a _krn_ file in specific location running **kernpy** as a module:
101
- ```shell
102
- python -m kernpy --input_path /my/path/to/file.ekern --output_path /new/output.krn
103
- ```
104
-
105
- 📌 Converting **all** the .ekern files in a directory to .krn files running **kernpy** as a module:
106
-
107
- * Every .ekrn file in the directory will be converted to .krn in the same location.
108
- * Using, at least, one additional directory level is required.
109
- ```
110
- root
111
- ├─ ekern-folder
112
- │   ├── 1.ekrn
113
- │   ├── 2.ekrn
114
- │   └── 3.ekrn
115
- ├── more-ekerns
116
- │   ├── 1.ekrn
117
- │   ├── ...
118
- ```
119
- Run:
120
- ```shell
121
- python -m kernpy --input_path /my/path/to/directory/ -r
122
- ```
123
-
124
- ✏️ This function is also available as a python function:
125
- ```python
126
- # converter.py
127
- from kernpy import ekern_to_krn
128
-
129
- # Only one file
130
- ekern_to_krn('/my/path/to/input.ekrn', '/to/my/output.krn')
131
-
132
- # Many files
133
- files = ['file1.ekrn', 'file2.ekrn', 'file3.ekrn']
134
- [ekern_to_krn(f) for f in files]
135
-
136
- # This function raises an exception if the conversion fails.
137
- # Handle the errors using try-except statement if many files are going to be converted in series.
138
- ```
139
-
140
-
141
- ****************************************************************************************
142
- ## 🎯 **create fragments**
143
- Generate new valid _kern_ files from an original _kern_ file. Every new fragment will be a subset of the original file.
144
-
145
- Explore the documentation website for more information about the parameters.
146
-
147
-
148
- Use:
149
- - **create_fragments_from_kern** to generate using always the same measure length.
150
- - **create_fragments_from_directory** to generate using a Gaussian distribution for the measure length. Static measure is also available if the standard deviation is set to 0.
151
-
152
-
153
- 📌 Create new scores from one original _kern_ directory running **kernpy** as a module:
154
- ```shell
155
- python -m kernpy --generate_fragments --input_directory /from/my/kerns --output_directory /to/my/fragments --log_file log.csv --verbose 2 --mean 4.2 --std_dev 1.5 --offset 1 --num_processes 12
156
- ```
157
-
158
-
159
- ✏️ Create new scores from one original _kern_ file:
160
- ```python
161
- # generator.py
162
- from kernpy import create_fragments_from_kern
163
-
164
- # View docs:
165
- help(create_fragments_from_kern)
166
-
167
- create_fragments_from_kern('/my/path/to/input.krn', '/to/my/output_dir/',
168
- measure_length=4, offset=1,
169
- log_file='/dev/null')
170
- ```
171
-
172
- ✏️ Create new scores from one original _kern_ directory:
173
- - Using, at least, one additional directory level is required.
174
- ```
175
- root
176
- ├─ kern-folder
177
- │   ├── 1.krn
178
- │   ├── 2.krn
179
- │   └── 3.krn
180
- ├── more-kerns
181
- │   ├── 1.krn
182
- │   ├── ...
183
- ```
184
-
185
- Run:
186
- ```python
187
- # generator.py
188
- from kernpy import create_fragments_from_directory
189
-
190
- # View docs:
191
- help(create_fragments_from_directory)
192
-
193
- create_fragments_from_directory('/my/path/to/input_dir/', '/to/my/output_dir/',
194
- mean=4.1, std_dev=0.2, offset=2,
195
- log_file='/logs/fragments.csv',
196
- num_processes=12)
197
- ```
198
-
199
-
200
-
201
16
  """
202
17
 
203
18
 
kernpy/__main__.py CHANGED
@@ -1,217 +1,127 @@
1
1
  """
2
2
  This module contains the main function for the kernpy package.
3
3
 
4
- Use the following command to run `kernpy` as a module:
5
- ```bash
6
- python -m kernpy
7
- ```
8
-
4
+ Usage:
5
+ python -m kernpy
9
6
  """
10
7
 
11
8
  import argparse
12
9
  import sys
13
- import os
10
+ from pathlib import Path
14
11
 
15
- from kernpy import polish_scores, ekern_to_krn, kern_to_ekern, create_fragments_from_directory
12
+ from kernpy import polish_scores, ekern_to_krn, kern_to_ekern
16
13
 
17
14
 
18
15
  def create_parser() -> argparse.ArgumentParser:
19
- """
20
- Create a parser for the command line arguments.
21
-
22
- Examples:
23
- >>> parser = create_parser()
24
- >>> args = parser.parse_args()
25
- >>> print(args.verbose)
26
-
27
-
28
- Returns:
29
- argparse.ArgumentParser: The parser object
30
- """
31
- parser = argparse.ArgumentParser(description="kernpy")
32
-
33
- parser.add_argument('--verbose', default=1, help='Enable verbose mode')
34
-
35
-
36
- # ekern to kern
37
- kern_parser = parser.add_argument_group('Kern Parser options')
38
- kern_parser.add_argument('--ekern2kern', action='store_true', help='Convert file from ekern to kern. [-r]')
39
- kern_parser.add_argument('--kern2ekern', action='store_true', help='Convert file from kern to ekern. [-r]')
40
-
41
- if '--ekern2kern' in sys.argv:
42
- kern_parser.add_argument('--input_path', required=True, type=str,
43
- help='Input file or directory path. Employ -r to use recursive mode')
44
- kern_parser.add_argument('--output_path', required=False, type=str, help='Output file or directory path')
45
- kern_parser.add_argument('-r', '--recursive', required=False, action='store_true', help='Recursive mode')
46
-
47
- if '--kern2ekern' in sys.argv:
48
- kern_parser.add_argument('--input_path', required=True, type=str,
49
- help='Input file or directory path. Employ -r to use recursive mode')
50
- kern_parser.add_argument('--output_path', required=False, type=str, help='Output file or directory path')
51
- kern_parser.add_argument('-r', '--recursive', required=False, action='store_true', help='Recursive mode')
52
-
53
- # Polish operations
54
- # Create a group for optional arguments
55
- polish_args = parser.add_argument_group('Polish Exporter options')
56
- polish_args.add_argument('--polish', action='store_true', help='Enable Polish Exporter')
57
- # Add the required flags, but only if --polish exists
58
- if '--polish' in sys.argv:
59
- polish_args.add_argument('--input_directory', required=True, type=str, help='Input directory path')
60
- polish_args.add_argument('--output_directory', required=True, type=str, help='Output directory path')
61
- polish_args.add_argument('--instrument', required=False, type=str, help='Instrument name')
62
- polish_args.add_argument('--kern_type', required=False, type=str, help='Kern type: "krn" or "ekrn"')
63
- polish_args.add_argument('--kern_spines_filter', required=False, type=str, help='How many kern spines scores will be exported. A number greater than 0', default=None)
64
- polish_args.add_argument('--remove_empty_dirs', required=False, action='store_true', help='Remove empty directories after exporting the scores', default=True)
65
-
66
- # Generate fragments
67
- # Create a group for optional arguments
68
- generate_fragments = parser.add_argument_group('Generate Fragments options')
69
- generate_fragments.add_argument('--generate_fragments', action='store_true', help='Enable Generate Fragments')
70
- if '--generate_fragments' in sys.argv:
71
- generate_fragments.add_argument('--input_directory', required=True, type=str, help='Input directory path')
72
- generate_fragments.add_argument('--output_directory', required=True, type=str, help='Output directory path')
73
- generate_fragments.add_argument('--log_file', required=True, type=str, help='Log file path')
74
- generate_fragments.add_argument('--check_file_extension', required=False, action='store_true', help='Check file extension', default=True)
75
- generate_fragments.add_argument('--offset', required=True, type=int, help='Offset', default=1)
76
- generate_fragments.add_argument('--num_processes', required=True, type=int, help='Number of processes')
77
- generate_fragments.add_argument('--mean', required=True, type=float, help='Mean')
78
- generate_fragments.add_argument('--std_dev', required=True, type=float, help='Standard deviation')
16
+ parser = argparse.ArgumentParser(description="kernpy CLI tool")
79
17
 
80
- return parser
18
+ parser.add_argument('--verbose', type=int, default=1, help='Verbosity level')
81
19
 
20
+ group = parser.add_mutually_exclusive_group(required=True)
21
+ group.add_argument('--ekern2kern', action='store_true', help='Convert files from ekern to kern')
22
+ group.add_argument('--kern2ekern', action='store_true', help='Convert files from kern to ekern')
23
+ group.add_argument('--polish', action='store_true', help='Run Polish Exporter')
24
+ group.add_argument('--generate_fragments', action='store_true', help='Generate Fragments')
82
25
 
83
- def handle_polish_exporter(args) -> None:
84
- """
85
- Handle the Polish options.
26
+ parser.add_argument('--input_path', type=str, help='Input file or directory')
27
+ parser.add_argument('--output_path', type=str, help='Output file or directory')
28
+ parser.add_argument('-r', '--recursive', action='store_true', help='Enable recursive directory processing')
86
29
 
87
- Args:
88
- args: The parsed arguments
30
+ # Polish Exporter
31
+ parser.add_argument('--input_directory', type=str, help='Polish: Input directory')
32
+ parser.add_argument('--output_directory', type=str, help='Polish: Output directory')
33
+ parser.add_argument('--instrument', type=str, help='Polish: Instrument name')
34
+ parser.add_argument('--kern_type', type=str, help='Polish: "krn" or "ekrn"')
35
+ parser.add_argument('--kern_spines_filter', type=str, help='Polish: Filter for number of kern spines')
36
+ parser.add_argument('--remove_empty_dirs', action='store_true', help='Polish: Remove empty directories')
89
37
 
90
- Returns:
91
- None
92
- """
93
- # TODO: Add instrument argument to download_polish_dataset.main
94
- if args.instrument:
95
- print("Instrument:", args.instrument)
96
- else:
97
- print("Instrument: Not specified")
98
38
 
99
- polish_scores.download_polish_dataset.main(
100
- input_directory=args.input_directory,
101
- output_directory=args.output_directory,
102
- kern_spines_filter=args.kern_spines_filter,
103
- exporter_kern_type=args.kern_type,
104
- remove_empty_directories=args.remove_empty_dirs
105
- )
39
+ return parser
106
40
 
107
41
 
108
- def handle_ekern2kern(args) -> None:
109
- """
110
- Handle the ekern2kern options.
42
+ def find_files(directory: Path, patterns: list[str], recursive: bool = False) -> list[Path]:
43
+ files = []
44
+ for pattern in patterns:
45
+ if recursive:
46
+ files.extend(directory.rglob(pattern))
47
+ else:
48
+ files.extend(directory.glob(pattern))
49
+ return files
111
50
 
112
- Args:
113
- args: The parsed arguments
114
51
 
115
- Returns:
116
- None
117
- """
118
- if not args.output_path:
119
- args.output_path = args.input_path.replace("ekrn", "krn")
52
+ def handle_ekern2kern(args):
53
+ input_path = Path(args.input_path)
54
+ output_path = Path(args.output_path) if args.output_path else None
120
55
 
121
- if not args.recursive:
122
- ekern_to_krn(args.input_path, args.output_path)
123
- if int(args.verbose) > 0:
124
- print(f"New kern generated in {args.output_path}")
56
+ if input_path.is_file():
57
+ out = output_path or input_path.with_suffix(".krn")
58
+ ekern_to_krn(str(input_path), str(out))
59
+ if args.verbose:
60
+ print(f"Converted: {input_path} → {out}")
125
61
  return
126
62
 
127
- # Recursive mode
128
- for root, dirs, files in os.walk(args.input_path):
129
- for directory in dirs:
130
- files = os.listdir(os.path.join(root, directory))
131
- for filename in files:
132
- if filename.endswith(".ekrn"):
133
- if int(args.verbose) > 0:
134
- print("New kern: ", os.path.join(root, directory, filename))
135
- try:
136
- ekern_to_krn(os.path.join(root, directory, filename),
137
- os.path.join(root, directory, filename.replace(".ekrn", ".krn")))
138
- except Exception as e:
139
- if int(args.verbose) > 0:
140
- print(f"An error occurred converting:{filename}:{e}", file=sys.stderr)
141
-
142
-
143
- def handle_kern2ekern(args) -> None:
144
- """
145
- Handle the kern2ekern options.
146
-
147
- Args:
148
- args: The parsed arguments
149
-
150
- Returns:
151
- None
152
- """
153
- if not args.output_path:
154
- args.output_path = args.input_path.replace("krn", "ekrn")
155
-
156
- if not args.recursive:
157
- kern_to_ekern(args.input_path, args.output_path)
158
- if int(args.verbose) > 0:
159
- print(f"New ekern generated in {args.output_path}")
63
+ files = find_files(input_path, ["*.ekrn", "*.ekern"], recursive=args.recursive)
64
+ for file in files:
65
+ out = file.with_suffix(".krn")
66
+ try:
67
+ ekern_to_krn(str(file), str(out))
68
+ if args.verbose:
69
+ print(f"Converted: {file} → {out}")
70
+ except Exception as e:
71
+ print(f"Error converting {file}: {e}", file=sys.stderr)
72
+
73
+
74
+ def handle_kern2ekern(args):
75
+ input_path = Path(args.input_path)
76
+ output_path = Path(args.output_path) if args.output_path else None
77
+
78
+ if input_path.is_file():
79
+ out = output_path or input_path.with_suffix(".ekrn")
80
+ kern_to_ekern(str(input_path), str(out))
81
+ if args.verbose:
82
+ print(f"Converted: {input_path} → {out}")
160
83
  return
161
84
 
162
- # Recursive mode
163
- for root, dirs, files in os.walk(args.input_path):
164
- for directory in dirs:
165
- files = os.listdir(os.path.join(root, directory))
166
- for filename in files:
167
- if filename.endswith(".krn"):
168
- if int(args.verbose) > 0:
169
- print("New ekern: ", os.path.join(root, directory, filename))
170
- try:
171
- kern_to_ekern(os.path.join(root, directory, filename),
172
- os.path.join(root, directory, filename.replace(".krn", ".ekrn")))
173
- except Exception as e:
174
- if int(args.verbose) > 0:
175
- print(f"An error occurred converting:{filename}:{e}", file=sys.stderr)
176
-
177
-
178
- def handle_generate_fragments(args) -> None:
179
- """
180
- Handle the generate_fragments options.
181
-
182
- Args:
183
- args: The parsed arguments
184
-
185
- Returns:
186
- None
187
- """
188
- create_fragments_from_directory(args.input_directory, args.output_directory, args.log_file,
189
- check_file_extension=args.check_file_extension, offset=args.offset,
190
- verbose=args.verbose, num_processes=args.num_processes, mean=args.mean,
191
- std_dev=args.std_dev)
85
+ files = find_files(input_path, ["*.krn", "*.kern"], recursive=args.recursive)
86
+ for file in files:
87
+ out = file.with_suffix(".ekrn")
88
+ try:
89
+ kern_to_ekern(str(file), str(out))
90
+ if args.verbose:
91
+ print(f"Converted: {file} → {out}")
92
+ except Exception as e:
93
+ print(f"Error converting {file}: {e}", file=sys.stderr)
94
+
95
+
96
+ def handle_polish_exporter(args):
97
+ if args.verbose:
98
+ print(f"Running Polish Exporter on {args.input_directory}{args.output_directory}")
99
+
100
+ polish_scores.download_polish_dataset.main(
101
+ input_directory=args.input_directory,
102
+ output_directory=args.output_directory,
103
+ kern_spines_filter=args.kern_spines_filter,
104
+ exporter_kern_type=args.kern_type,
105
+ remove_empty_directories=args.remove_empty_dirs,
106
+ )
192
107
 
193
108
 
194
109
  def main():
195
110
  parser = create_parser()
196
111
  args = parser.parse_args()
197
112
 
198
- # Accessing the values of the options
199
- if int(args.verbose) > 2:
200
- print(f"All arguments: \n{50 * '*'}")
201
- for key, value in vars(args).items():
202
- print(key, value)
203
- print(f"{50 * '*'}\n")
113
+ if args.verbose > 2:
114
+ print("Arguments:")
115
+ for key, val in vars(args).items():
116
+ print(f" {key}: {val}")
204
117
 
205
- if args.polish:
206
- handle_polish_exporter(args)
207
118
  if args.ekern2kern:
208
119
  handle_ekern2kern(args)
209
- if args.kern2ekern:
120
+ elif args.kern2ekern:
210
121
  handle_kern2ekern(args)
211
- if args.generate_fragments:
212
- handle_generate_fragments(args)
122
+ elif args.polish:
123
+ handle_polish_exporter(args)
213
124
 
214
125
 
215
126
  if __name__ == "__main__":
216
127
  main()
217
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kernpy
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Python Humdrum **kern and **mens utilities
5
5
  Project-URL: Homepage, https://github.com/OMR-PRAIG-UA-ES/kernpy
6
6
  Project-URL: Documentation, https://github.com/OMR-PRAIG-UA-ES/kernpy#readme
@@ -19,9 +19,18 @@ Description-Content-Type: text/markdown
19
19
 
20
20
  # Python Humdrum **kern and **mens utilities
21
21
 
22
- ## Documentation: <a target="_blank" href="https://kernpy.pages.dev/">https://kernpy.pages.dev/</a>
22
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg?style=for-the-badge)](https://www.gnu.org/licenses/agpl-3.0)
23
+ ![Python Version](https://img.shields.io/badge/Python-3.9+-3776AB?logo=python&logoColor=white&style=for-the-badge)
24
+ [![PyPI](https://img.shields.io/pypi/v/kernpy?color=brightgreen&label=PyPI&style=for-the-badge&logo=pypi)](https://pypi.org/project/kernpy/)
25
+ [![Docs](https://img.shields.io/badge/docs-available-blue?style=for-the-badge&logo=readthedocs)](https://kernpy.pages.dev)
26
+ [![Tests](https://img.shields.io/badge/tests-passing-brightgreen?style=for-the-badge&logo=pytest)](https://github.com/kernpy/kernpy/actions)
27
+ [![Contributions welcome](https://img.shields.io/badge/contributions-welcome-orange?style=for-the-badge&logo=github)](CONTRIBUTING.md)
23
28
 
24
- ![kernpy logo](https://static.wixstatic.com/media/7a8a67_90be144dbf384480908c3327b93ba97a~mv2.jpg/v1/fill/w_461,h_354,fp_0.46_0.20,q_80,usm_0.66_1.00_0.01,enc_avif,quality_auto/mending-the-sail-1896_jpg!Large.jpg)
29
+
30
+ Python package that provides comprehensive tools for working with symbolic modern and mensural notations in Humdrum format. kernpy is a fully open-source project open to contributions.
31
+
32
+ ## Documentation
33
+ Visit the online website: <a target="_blank" href="https://kernpy.pages.dev/">https://kernpy.pages.dev/</a>
25
34
 
26
35
  ## Index:
27
36
  - [Code examples](#code-examples)
@@ -71,18 +80,74 @@ Only use the specified spines in `spine_types`.
71
80
  ```python
72
81
  import kernpy as kp
73
82
 
83
+ # only export the **kern spines
74
84
  kp.dump(document, "newfile_core.krn",
75
85
  spine_types=['**kern'])
86
+
87
+ # only export the **text spines
76
88
  kp.dump(document, "newfile_lyrics.krn",
77
89
  spine_types=['**text])
90
+
91
+ # only export **kern and **text spines
78
92
  kp.dump(document, "newfile_core_and_lyrics.krn",
79
93
  spine_types=['*+text'])
80
94
  ```
81
95
 
96
+ - The categories are hierarchically defined in the `TokenCategory` class.
97
+ See the hierarchy as a tree
98
+ ```python
99
+ import kernpy as kp
100
+
101
+
102
+ print(kp.TokenCategory.tree())
103
+ ```
104
+ Tree:
105
+ ```txt
106
+ .
107
+ ├── STRUCTURAL
108
+ │ ├── HEADER
109
+ │ └── SPINE_OPERATION
110
+ ├── CORE
111
+ │ ├── NOTE_REST
112
+ │ │ ├── DURATION
113
+ │ │ ├── NOTE
114
+ │ │ │ ├── PITCH
115
+ │ │ │ ├── DECORATION
116
+ │ │ │ └── ALTERATION
117
+ │ │ └── REST
118
+ │ ├── CHORD
119
+ │ ├── EMPTY
120
+ │ └── ERROR
121
+ ├── SIGNATURES
122
+ │ ├── CLEF
123
+ │ ├── TIME_SIGNATURE
124
+ │ ├── METER_SYMBOL
125
+ │ ├── KEY_SIGNATURE
126
+ │ └── KEY_TOKEN
127
+ ├── ENGRAVED_SYMBOLS
128
+ ├── OTHER_CONTEXTUAL
129
+ ├── BARLINES
130
+ ├── COMMENTS
131
+ │ ├── FIELD_COMMENTS
132
+ │ └── LINE_COMMENTS
133
+ ├── DYNAMICS
134
+ ├── HARMONY
135
+ ├── FINGERING
136
+ ├── LYRICS
137
+ ├── INSTRUMENTS
138
+ ├── IMAGE_ANNOTATIONS
139
+ │ ├── BOUNDING_BOXES
140
+ │ └── LINE_BREAK
141
+ ├── OTHER
142
+ ├── MHXM
143
+ └── ROOT
144
+ ```
145
+
82
146
  - Use `include` for selecting the **kern semantic categories **to use**. The output only contains what is passed. By default, all the categories are included.
83
147
  ```python
84
148
  import kernpy as kp
85
149
 
150
+
86
151
  kp.dump(document, "newfile_only_clefs.krn",
87
152
  include={kp.TokenCategory.CLEF})
88
153
  kp.dump(document, "newfile_only_durations_and_bounding_boxes.krn",
@@ -104,6 +169,9 @@ import kernpy as kp
104
169
  kp.dump(document, "newfile_custom.krn",
105
170
  include=kp.BEKERN_CATEGORIES, # Preloaded set of simple categories
106
171
  exclude={kp.TokenCategory.PITCH})
172
+
173
+ # Inspect the BEKERN preloaded categories
174
+ print(kp.BEKERN_CATEGORIES)
107
175
  ```
108
176
 
109
177
  - Use `tokenizer` to select how the categories are split. By default, the `normalizedKern` tokenizer is used.
@@ -382,8 +450,10 @@ kp.graph(document, '/tmp/graph.dot')
382
450
  ### Production version:
383
451
  Just install the last version of **kernpy** using pip:
384
452
  ```shell
385
- pip3 uninstall kernpy # Uninstall the previous version before installing the new one
386
- pip3 install git+https://github.com/OMR-PRAIG-UA-ES/kernpy.git
453
+ pip3 install kernpy
454
+
455
+ # ensure you have the latest version
456
+ pip3 install kernpy --upgrade
387
457
  ```
388
458
 
389
459
  > [!NOTE]
@@ -391,55 +461,6 @@ pip3 install git+https://github.com/OMR-PRAIG-UA-ES/kernpy.git
391
461
 
392
462
  <hr>
393
463
 
394
- ### Development version:
395
-
396
- > [!IMPORTANT]
397
- > - Add the development dependencies to the `requirements.txt` file.
398
- > - Add the production dependencies to the `pyproject.toml` file.
399
- > - After every change in the grammar, the next steps are mandatory:
400
- > - - Run the `antlr4.sh` script (JAVA required).
401
- > - - Commit & push the changes to the repository.
402
-
403
-
404
- - Generate antrl4 grammar:
405
- - For generating the Python code required for parsing the **kern files, the shell script `antlr4.sh` inside the `kernpy` package must be run.
406
-
407
- ```shell
408
- ./antlr4.sh
409
- ```
410
-
411
- Install all the dependencies using the `requirements.txt` file:
412
- ```shell
413
- pip install -r requirements.txt
414
- ```
415
-
416
- Otherwise, install the required packages manually:
417
-
418
-
419
- - It requires the `antlr4` package to be installed using:
420
- ```shell
421
- pip install antlr4-python3-runtime
422
- ```
423
-
424
-
425
- - For visualizing the bounding boxes, the library, the `Pillow` library is required:
426
- ```shell
427
- pip install Pillow
428
- ```
429
-
430
- - To parse a IIIF (International Image Interoperability Framework) manifest in Python, we use the `requests` library to fetch the manifest file:
431
- ```shell
432
- pip install requests
433
- ```
434
-
435
- - If fetching data from `https` fails, install the following version of `urllib`:
436
- ```shell
437
- pip install urllib3==1.26.6
438
- ```
439
-
440
- It has been tested with version 4.13.1 of the package.
441
-
442
-
443
464
  ## Documentation
444
465
  Documentation available at [https://kernpy.pages.dev/](https://kernpy.pages.dev/)
445
466
 
@@ -461,32 +482,7 @@ cd tests && python -m pytest
461
482
 
462
483
  We welcome contributions from the community! If you'd like to contribute to the project, please follow these steps:
463
484
 
464
- 1. Fork the Repository from GitHub.
465
- 2. Clone your own fork repository.
466
- ```bash
467
- git clone ...
468
- cd ...
469
- ```
470
- 3. Create a Branch:
471
- 4. Create a new branch for your feature or bug fix:
472
- ```bash
473
- git checkout -b feature/your-feature-name
474
- ```
475
- 5. Commit Your Changes:
476
- Commit your changes with a descriptive message:
477
- ```bash
478
- git commit -m "feat: add your feature or fix"
479
- ```
480
-
481
- 6. Push to Your Branch:
482
- Push your changes to your forked repository:
483
- ```bash
484
- git push origin feature/your-feature-name
485
- ```
486
-
487
- 7. Create a Pull Request:
488
- Open a pull request to the main repository, describing your changes.
489
-
485
+ Go to the file [CONTRIBUTING.md](CONTRIBUTING.md) for more information on how to contribute.
490
486
 
491
487
  ## Citation:
492
488
  ```bibtex
@@ -1,5 +1,5 @@
1
- kernpy/__init__.py,sha256=h1o3Z_Xk7nZdE4fBu7uLx6V6nR4M3LySi36ONj73sOo,5998
2
- kernpy/__main__.py,sha256=ayuovsnyTaTrhcyOM1kFBoSXGjT1QALwIMcJ_NOqVkM,8495
1
+ kernpy/__init__.py,sha256=HdHS0T3se8qIU0d2mULhwhgJRfgGmNA4Zhxl4YvjeVA,313
2
+ kernpy/__main__.py,sha256=ZxsPlyfgzpZjU8TdNBc1SrMyTTr-Osu4j08DXHAgpVQ,4437
3
3
  kernpy/test_grammar.sh,sha256=MP9Hav9nPxTbHeofFEuunwDsLcBoeFRtzPp4bbPnqBU,520
4
4
  kernpy/visualize_analysis.sh,sha256=z68jyZ8zj4w7v5CoC8-J7PGh7dYA_iQbuFL5T63X6qY,526
5
5
  kernpy/core/__init__.py,sha256=gIbOKMWcPcQc4c6QpslWnAw9XkcMJ6OvedHANyDABbs,2581
@@ -46,6 +46,6 @@ kernpy/polish_scores/iiif.py,sha256=yITdrQbMsGmm8qag8TSousjCjS2io148Jk9xwEKa3B4,
46
46
  kernpy/util/__init__.py,sha256=dfW3nRSMkGQS7p7YebM271_0H8_pVw4IiDKeINs_LI8,152
47
47
  kernpy/util/helpers.py,sha256=Xbj3nWNyErdOpLHYd4uVyfwleXvmC5_FlYEhxaeTtS8,1549
48
48
  kernpy/util/store_cache.py,sha256=AA7SFCGQ6ryy-c02wbLy8gIQ2C-VdM1JSWFoWIK_KLA,1186
49
- kernpy-1.0.0.dist-info/METADATA,sha256=D2maG9kcRvqxzIO02G6gjx4IecAZtUlfZDoT58rQJOo,14888
50
- kernpy-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
- kernpy-1.0.0.dist-info/RECORD,,
49
+ kernpy-1.0.1.dist-info/METADATA,sha256=1SpNbdsg1KHO4FnR7vSeabwlsueGoA8y-4RDN-v2vZk,15096
50
+ kernpy-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
+ kernpy-1.0.1.dist-info/RECORD,,
File without changes