diff --git a/src/wireviz/wireviz.py b/src/wireviz/wireviz.py index 032afca7..636e57a6 100755 --- a/src/wireviz/wireviz.py +++ b/src/wireviz/wireviz.py @@ -21,58 +21,17 @@ ) -def parse_text( - yaml_str: str, - file_out: (str, Path) = None, - output_formats: (None, str, Tuple[str]) = ("html", "png", "svg", "tsv"), - return_types: (None, str, Tuple[str]) = None, - image_paths: List = [], -) -> Any: - """ - Parses a YAML input string and does the high-level harness conversion - - :param yaml_input: a string containing the YAML input data - :param file_out: - :param output_formats: - :param return_types: if None, then returns None; if the value is a string, then a - corresponding data format will be returned; if the value is a tuple of strings, - then for every valid format in the `return_types` tuple, another return type - will be generated and returned in the same order; currently supports: - - "png" - will return the PNG data - - "svg" - will return the SVG data - - "harness" - will return the `Harness` instance - """ - yaml_data = yaml.safe_load(yaml_str) - return parse( - yaml_data=yaml_data, - file_out=file_out, - output_formats=output_formats, - return_types=return_types, - image_paths=image_paths, - ) - - def parse( - yaml_data: Dict, - file_out: (str, Path) = None, - output_formats: (None, str, Tuple[str]) = ("html", "png", "svg", "tsv"), + inp: (str, Path, Dict), + output_formats: (None, str, Tuple[str]) = None, + output_path: (str, Path) = None, return_types: (None, str, Tuple[str]) = None, image_paths: List = [], ) -> Any: - """ - Parses a YAML dictionary and does the high-level harness conversion - - :param yaml_data: a dictionary containing the YAML data - :param file_out: - :param output_formats: - :param return_types: if None, then returns None; if the value is a string, then a - corresponding data format will be returned; if the value is a tuple of strings, - then for every valid format in the `return_types` tuple, another return type - will be generated and returned in the same order; currently supports: - - "png" - will return the PNG data - - "svg" - will return the SVG data - - "harness" - will return the `Harness` instance - """ + + yaml_data, yaml_path = get_yaml_data_and_path(inp) + if output_formats: # need to write data to file, determine output path + output_path = get_output_path(yaml_path, output_path) # define variables ========================================================= # containers for parsed component data and connection sets @@ -91,8 +50,8 @@ def parse( # keep track of auto-generated designators to avoid duplicates autogenerated_designators = {} - if "title" not in harness.metadata: - harness.metadata["title"] = Path(file_out).stem + # if "title" not in harness.metadata: + # harness.metadata["title"] = Path(yaml_path).stem # add items # parse YAML input file ==================================================== @@ -337,10 +296,10 @@ def alternate_type(): # flip between connector and cable/arrow for line in yaml_data["additional_bom_items"]: harness.add_bom_item(line) - if file_out is not None: + if output_formats: harness.output(filename=file_out, fmt=output_formats, view=False) - if return_types is not None: + if return_types: returns = [] if isinstance(return_types, str): # only one return type speficied return_types = [return_types] @@ -358,18 +317,39 @@ def alternate_type(): # flip between connector and cable/arrow return tuple(returns) if len(returns) != 1 else returns[0] -def parse_file(yaml_file: str, file_out: (str, Path) = None) -> None: - yaml_file = Path(yaml_file) - with open_file_read(yaml_file) as file: - yaml_str = file.read() - - if file_out: - file_out = Path(file_out) +def get_yaml_data_and_path(inp: (str, Path, Dict)) -> (Dict, Path): + # determine whether inp is a file path, a YAML string, or a Dict + if not isinstance(inp, Dict): # received a str or a Path + try: + yaml_path = Path(inp).expanduser().resolve(strict=True) + # if no FileNotFoundError exception happens, get file contents + yaml_str = open_file_read(yaml_path).read() + except (FileNotFoundError, OSError) as e: + # if inp is a long YAML string, Pathlib will raise OSError: [Errno 63] + # when trying to expand and resolve it as a path. + # Catch this error, but raise any others + if type(e) is OSError and e.errno != 63: + raise e + # file does not exist; assume inp is a YAML string + yaml_str = inp + yaml_path = None + yaml_data = yaml.safe_load(yaml_str) else: - file_out = yaml_file.parent / yaml_file.stem - file_out = file_out.resolve() - - parse_text(yaml_str, file_out=file_out, image_paths=[Path(yaml_file).parent]) + # received a Dict, use as-is + yaml_data = inp + yaml_path = None + return yaml_data, yaml_path + + +def get_output_path(input_path: Path, default_output_path: Path) -> Path: + if default_output_path: # user-specified output path + output_path = Path(default_output_path) + else: # auto-determine appropriate output path + if input_path: # input comes from a file; place output in same directory + output_path = input_path.parent + else: # input comes from str or dict, fall back to cwd + output_path = Path.cwd() + return output_path.resolve() def main(): diff --git a/src/wireviz/wv_cli.py b/src/wireviz/wv_cli.py index 65a20a6f..472c0894 100644 --- a/src/wireviz/wv_cli.py +++ b/src/wireviz/wv_cli.py @@ -122,7 +122,7 @@ def wireviz(file, format, prepend, output_file, version): yaml_input = prepend_input + yaml_input - wv.parse_text( + wv.parse( yaml_input, file_out=file_out, output_formats=output_formats,