Skip to content

Commit

Permalink
Add FileNameDrop[] (#1141)
Browse files Browse the repository at this point in the history
Left to do are changes with mixed negative and positive to integer arg
values. I don't understand the behavior though.

And this isn't needed for the ChemTools loader anyway. (But ChemTools
has other bugs that still need work).
  • Loading branch information
rocky authored Oct 22, 2024
1 parent 8c472bd commit 744cbe0
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ New Builtins
++++++++++++

* ``CheckAbort``
* ``FileNameDrop``
* ``SetEnvironment``

``mathics`` command line
Expand Down
1 change: 1 addition & 0 deletions SYMBOLS_MANIFEST.txt
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ System`FileFormat
System`FileHash
System`FileInformation
System`FileNameDepth
System`FileNameDrop
System`FileNameJoin
System`FileNameSplit
System`FileNameTake
Expand Down
2 changes: 2 additions & 0 deletions mathics/builtin/file_operations/file_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
from mathics.core.systemsymbols import SymbolAbsoluteTime, SymbolFailed, SymbolNone
from mathics.eval.nevaluator import eval_N

sort_order = "mathics.builtin.file-operations.file_properties"


class FileDate(Builtin):
"""
Expand Down
2 changes: 2 additions & 0 deletions mathics/builtin/file_operations/file_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from mathics.core.evaluation import Evaluation
from mathics.core.systemsymbols import SymbolFailed

sort_order = "mathics.builtin.file-operations.file_utilities"


class FindList(Builtin):
"""
Expand Down
103 changes: 103 additions & 0 deletions mathics/builtin/file_operations/path_operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"""
File Path Manipulation
"""

import os.path as osp
from pathlib import Path
from typing import Optional

from mathics.core.atoms import Integer, String
from mathics.core.builtin import Builtin
from mathics.core.evaluation import Evaluation

# This tells documentation how to sort this module
sort_order = "mathics.builtin.file-operations.file_path_operations"


class FileNameDrop(Builtin):
"""
<url>
:WMA link:
https://reference.wolfram.com/language/ref/FileNameDrop.html</url>
<dl>
<dt>'FileNameDrop["$path$", $n$]'
<dd>drops the first $n$ path elements in the file name $path$.
<dt>'FileNameDrop["$path$", -$n$]'
<dd>drops the last $n$ path elements in the file name $path$.
<dt>'FileNameDrop["$path$", {$m$, $n$}]'
<dd>drops elements $m$ through $n$ path elements in the file name $path$.
<dt>'FileNameDrop["$path$"]'
<dd>drops the last path elements in the file name $path$.
</dl>
>> path = FileNameJoin{"a","b","c"}
= ...
>> FileNameDrop[path, -1]
= ...
A shorthand for the above:
>> FileNameDrop[path]
= ...
"""

messages = {
"notfinished": "m-n handling is not complete.",
}
rules = {
"FileNameDrop[name_]": "FileNameDrop[name, -1]",
"FileNameDrop[list_List, parms___]": "FileNameDrop[#1,parms]&/@list",
}
summary_text = "drop a part of a file path"

def eval_with_n(self, path: String, n: Integer, evaluation: Evaluation) -> String:
"FileNameDrop[path_String, n_Integer]"
pos = n.value
if pos == 0:
return path
path_elts = Path(path.value).parts
path_len = len(path_elts)
if pos >= path_len or pos <= -path_len:
return String("")

new_elts = path_elts[pos:] if pos > 0 else path_elts[:pos]
return String(osp.join(*new_elts) if new_elts else "")

def eval_with_n_to_m(
self, path: String, n: Integer, m: Integer, evaluation: Evaluation
) -> Optional[String]:
"FileNameDrop[path_String, {n_Integer, m_Integer}]"
n_pos = n.value
m_pos = m.value
path_elts = Path(path.value).parts
path_len = len(path_elts)
if n_pos > path_len:
return path

if n_pos == path_len:
if n_pos == m_pos or n_pos + m_pos == -1:
# Not sure why this is so.
return String(osp.join(*path_elts[:-1]))
return path

if n_pos > m_pos:
return path

new_elts = None
if 0 < n_pos < m_pos:
new_elts = path_elts[: n_pos - 1] + path_elts[m_pos:]
elif n_pos <= m_pos <= 0:
new_elts = path_elts[:n_pos] + path_elts[m_pos + 1 :]
else:
evaluation.message("FindNameDrop", "notfinished")
return None

if new_elts:
return String(osp.join(*new_elts))
else:
return String("")

0 comments on commit 744cbe0

Please sign in to comment.