|
11 | 11 | import sys
|
12 | 12 | import time
|
13 | 13 | import webbrowser
|
14 |
| -from collections.abc import Iterable |
| 14 | +from collections.abc import Iterable, Sequence |
| 15 | +from typing import Any |
15 | 16 |
|
16 | 17 | import xarray as xr
|
17 | 18 | from pygmt.exceptions import GMTInvalidInput
|
@@ -315,6 +316,108 @@ def non_ascii_to_octal(argstr):
|
315 | 316 | return argstr.translate(str.maketrans(mapping))
|
316 | 317 |
|
317 | 318 |
|
| 319 | +def build_arg_list( |
| 320 | + kwdict: dict[str, Any], |
| 321 | + confdict: dict[str, str] | None = None, |
| 322 | + infile: str | pathlib.PurePath | Sequence[str | pathlib.PurePath] | None = None, |
| 323 | + outfile: str | pathlib.PurePath | None = None, |
| 324 | +) -> list[str]: |
| 325 | + r""" |
| 326 | + Convert keyword dictionaries and input/output files into a list of GMT arguments. |
| 327 | +
|
| 328 | + Make sure all values in ``kwdict`` have been previously converted to a string |
| 329 | + representation using the ``kwargs_to_strings`` decorator. The only exceptions are |
| 330 | + ``True``, ``False`` and ``None``. |
| 331 | +
|
| 332 | + Any remaining lists or tuples will be interpreted as multiple entries for the same |
| 333 | + parameter. For example, the kwargs entry ``"B": ["xa", "yaf"]`` will be |
| 334 | + converted to ``["-Bxa", "-Byaf"]``. |
| 335 | +
|
| 336 | + Parameters |
| 337 | + ---------- |
| 338 | + kwdict |
| 339 | + A dictionary containing parsed keyword arguments. |
| 340 | + confdict |
| 341 | + A dictionary containing configurable GMT parameters. |
| 342 | + infile |
| 343 | + The input file or a list of input files. |
| 344 | + outfile |
| 345 | + The output file. |
| 346 | +
|
| 347 | + Returns |
| 348 | + ------- |
| 349 | + args |
| 350 | + The list of command line arguments that will be passed to GMT modules. The |
| 351 | + keyword arguments are sorted alphabetically, followed by GMT configuration |
| 352 | + key-value pairs, with optional input file(s) at the beginning and optional |
| 353 | + output file at the end. |
| 354 | +
|
| 355 | + Examples |
| 356 | + -------- |
| 357 | + >>> build_arg_list(dict(A=True, B=False, C=None, D=0, E=200, F="", G="1/2/3/4")) |
| 358 | + ['-A', '-D0', '-E200', '-F', '-G1/2/3/4'] |
| 359 | + >>> build_arg_list(dict(A="1/2/3/4", B=["xaf", "yaf", "WSen"], C=("1p", "2p"))) |
| 360 | + ['-A1/2/3/4', '-BWSen', '-Bxaf', '-Byaf', '-C1p', '-C2p'] |
| 361 | + >>> print( |
| 362 | + ... build_arg_list( |
| 363 | + ... dict( |
| 364 | + ... B=["af", "WSne+tBlank Space"], |
| 365 | + ... F='+t"Empty Spaces"', |
| 366 | + ... l="'Void Space'", |
| 367 | + ... ) |
| 368 | + ... ) |
| 369 | + ... ) |
| 370 | + ['-BWSne+tBlank Space', '-Baf', '-F+t"Empty Spaces"', "-l'Void Space'"] |
| 371 | + >>> print( |
| 372 | + ... build_arg_list( |
| 373 | + ... dict(A="0", B=True, C="rainbow"), |
| 374 | + ... confdict=dict(FORMAT_DATE_MAP="o dd"), |
| 375 | + ... infile="input.txt", |
| 376 | + ... outfile="output.txt", |
| 377 | + ... ) |
| 378 | + ... ) |
| 379 | + ['input.txt', '-A0', '-B', '-Crainbow', '--FORMAT_DATE_MAP=o dd', '->output.txt'] |
| 380 | + >>> print( |
| 381 | + ... build_arg_list( |
| 382 | + ... dict(A="0", B=True), |
| 383 | + ... confdict=dict(FORMAT_DATE_MAP="o dd"), |
| 384 | + ... infile=["f1.txt", "f2.txt"], |
| 385 | + ... outfile="out.txt", |
| 386 | + ... ) |
| 387 | + ... ) |
| 388 | + ['f1.txt', 'f2.txt', '-A0', '-B', '--FORMAT_DATE_MAP=o dd', '->out.txt'] |
| 389 | + >>> print(build_arg_list(dict(R="1/2/3/4", J="X4i", watre=True))) |
| 390 | + Traceback (most recent call last): |
| 391 | + ... |
| 392 | + pygmt.exceptions.GMTInvalidInput: Unrecognized parameter 'watre'. |
| 393 | + """ |
| 394 | + gmt_args = [] |
| 395 | + for key, value in kwdict.items(): |
| 396 | + if len(key) > 2: # Raise an exception for unrecognized options |
| 397 | + raise GMTInvalidInput(f"Unrecognized parameter '{key}'.") |
| 398 | + if value is None or value is False: # Exclude arguments that are None or False |
| 399 | + pass |
| 400 | + elif value is True: |
| 401 | + gmt_args.append(f"-{key}") |
| 402 | + elif is_nonstr_iter(value): |
| 403 | + gmt_args.extend(non_ascii_to_octal(f"-{key}{_value}") for _value in value) |
| 404 | + else: |
| 405 | + gmt_args.append(non_ascii_to_octal(f"-{key}{value}")) |
| 406 | + gmt_args = sorted(gmt_args) |
| 407 | + |
| 408 | + if confdict: |
| 409 | + gmt_args.extend(f"--{key}={value}" for key, value in confdict.items()) |
| 410 | + |
| 411 | + if infile: # infile can be a single file or a list of files |
| 412 | + if isinstance(infile, str | pathlib.PurePath): |
| 413 | + gmt_args = [str(infile), *gmt_args] |
| 414 | + else: |
| 415 | + gmt_args = [str(_file) for _file in infile] + gmt_args |
| 416 | + if outfile: |
| 417 | + gmt_args.append(f"->{outfile}") |
| 418 | + return gmt_args |
| 419 | + |
| 420 | + |
318 | 421 | def build_arg_string(kwdict, confdict=None, infile=None, outfile=None):
|
319 | 422 | r"""
|
320 | 423 | Convert keyword dictionaries and input/output files into a GMT argument string.
|
|
0 commit comments