]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update x-path-walker
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Thu, 23 Nov 2023 18:43:10 +0000 (19:43 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Thu, 23 Nov 2023 19:07:18 +0000 (20:07 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
24 files changed:
elpa/x-path-walker-20160922.1835/x-path-walker-autoloads.el [deleted file]
elpa/x-path-walker-20160922.1835/x-path-walker-pkg.el [deleted file]
elpa/x-path-walker-20160922.1835/x-path-walker.el [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/__init__.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/__main__.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/args.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/json_Processor.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/json_jq_Processor.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/lxml_Processor.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/processor.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/utils.py [deleted file]
elpa/x-path-walker-20160922.1835/xpathwalker/yaml_Processor.py [deleted file]
elpa/x-path-walker-20220714.1056/x-path-walker-autoloads.el [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/x-path-walker-pkg.el [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/x-path-walker.el [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/__init__.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/__main__.py [new file with mode: 0755]
elpa/x-path-walker-20220714.1056/xpathwalker/args.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/json_Processor.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/json_jq_Processor.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/lxml_Processor.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/processor.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/utils.py [new file with mode: 0644]
elpa/x-path-walker-20220714.1056/xpathwalker/yaml_Processor.py [new file with mode: 0644]

diff --git a/elpa/x-path-walker-20160922.1835/x-path-walker-autoloads.el b/elpa/x-path-walker-20160922.1835/x-path-walker-autoloads.el
deleted file mode 100644 (file)
index 6801d5f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-;;; x-path-walker-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "x-path-walker" "x-path-walker.el" (0 0 0 0))
-;;; Generated autoloads from x-path-walker.el
-
-(autoload 'helm-x-path-walker "x-path-walker" "\
-
-
-\(fn)" t nil)
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "x-path-walker" '("x-path-")))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("x-path-walker-pkg.el") (0 0 0 0))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; x-path-walker-autoloads.el ends here
diff --git a/elpa/x-path-walker-20160922.1835/x-path-walker-pkg.el b/elpa/x-path-walker-20160922.1835/x-path-walker-pkg.el
deleted file mode 100644 (file)
index 550df4b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-(define-package "x-path-walker" "20160922.1835" "Navigation feature for JSON/XML/HTML based on path (imenu like)"
-  '((helm-core "1.9.2"))
-  :keywords
-  '("convenience")
-  :authors
-  '((nil . "<lompik@ArchOrion>"))
-  :maintainer
-  '(nil . "<lompik@ArchOrion>"))
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/x-path-walker-20160922.1835/x-path-walker.el b/elpa/x-path-walker-20160922.1835/x-path-walker.el
deleted file mode 100644 (file)
index fbec88f..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-;;; x-path-walker.el --- Navigation feature for JSON/XML/HTML based on path (imenu like)  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2015
-
-;; Author:  <lompik@ArchOrion>
-;; Keywords: convenience
-;; Package-Requires: ((helm-core "1.9.2"))
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;
-
-;;; Code:
-
-(require 'helm)
-
-(defvar x-path-walker-source-dir (concat (if load-file-name
-                                             (file-name-directory load-file-name)
-                                           default-directory)))
-
-(defvar x-path-walker-objects-separators ".")
-
-(defun x-path-walker-command ()
-  (list (concat "PYTHONPATH=" x-path-walker-source-dir)
-        (executable-find "python3")
-        "-m xpathwalker"))
-
-(defvar x-path-walker-verbose nil)
-
-(defun x-path-build-cmd-path (args)
-  (let ((cmdpython (x-path-walker-command)))
-    (mapconcat #'identity
-             (append cmdpython
-                     args)
-             " ")))
-
-(defun x-path-run-py-script (args)
-  (let ((cmd (x-path-build-cmd-path args)))
-    (shell-command-to-string cmd)))
-
-(defun x-path-get-mode ()
-  (let ((mm (pcase major-mode
-              (`json-mode "JSON")
-              (`xml-mode "XML")
-              (`nxml-mode "XML")
-              (`html-mode "HTML")
-              (`web-mode "HTML")
-              (code nil))))
-    (unless (and (buffer-file-name) mm)
-      (keyboard-quit))
-    mm))
-
-(defun x-path-walker-ask ()
-  (interactive)
-  (if (and (buffer-modified-p)
-           (yes-or-no-p "Buffer will be linted. Do you want to save the current buffer (required)?"))
-      (save-current-buffer)
-    (if (buffer-modified-p)
-        (keyboard-quit))))
-
-(defun x-path-walker-jump-path (path)
-  (let* ((mode (x-path-get-mode))
-         (path (if (not (bound-and-true-p x-path-walker-verbose))
-                   path
-                 (if (or (string= mode "HTML")
-                         (string= mode "XML"))
-                     (car (split-string path " | "))
-                   (if (and (string= mode "JSON") )
-                       (car (cdr (split-string path " | ")))
-                     ""))))
-         (line (replace-regexp-in-string
-                "\n$" ""
-                (x-path-run-py-script `("-x"
-                                        ,(shell-quote-argument path)
-                                        "-m"
-                                        ,mode
-                                        ,(buffer-file-name) )))))
-    (if (string= mode "JSON")
-        (progn  (x-path-walker-ask)
-                (erase-buffer)
-                (shell-command-on-region (point-min) (point-max)
-                                         (concat "python3 -m json.tool "
-                                                 (buffer-file-name))
-                                         (current-buffer))))
-    (unless (or (string= "" line))
-      (goto-char 0)
-      (forward-line (1- (string-to-number line)))
-      (recenter)
-      (back-to-indentation))))
-
-;;;###autoload
-(defun helm-x-path-walker()
-  (interactive)
-  (let* ((mode (x-path-get-mode))
-         (file (buffer-file-name))
-         (cmd-line `(,(if (bound-and-true-p x-path-walker-verbose)
-                          "-a"
-                        "")
-                     "-m"
-                     ,mode
-                     ,file ))
-         (cands  (split-string (x-path-run-py-script cmd-line)"\n")))
-    (helm
-     :sources (helm-build-sync-source "PATH-WALKER"
-                :keymap helm-map
-                :candidates  cands
-                :candidate-number-limit 500
-                :action (helm-make-actions
-                         "Jump to path" 'x-path-walker-jump-path))
-     :prompt "Select Path:"
-     :resume 'noresume
-     :keymap helm-map
-     :buffer "*helm path-walker*")))
-
-(provide 'x-path-walker)
-;;; x-path-walker.el ends here
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/__init__.py b/elpa/x-path-walker-20160922.1835/xpathwalker/__init__.py
deleted file mode 100644 (file)
index 894c4e7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# xpathwalker
-
-has_legs = False
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/__main__.py b/elpa/x-path-walker-20160922.1835/xpathwalker/__main__.py
deleted file mode 100755 (executable)
index 745fbe7..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-import sys
-
-from xpathwalker.args import parse_args
-
-
-##########################################################################
-# Main                                                                   #
-##########################################################################
-
-def main(argv):
-    parse_args(argv)
-
-
-if __name__ == "__main__":
-    main(sys.argv[1:])
-
-# Bench:
-# wc -l
-# 21302 /mnt/VM/home/lompik/Programmation/Web/d3_Map_GOM/Data/fldunit.json
-# with multiproc:
-# # string | .features[99].properties.UNIT_AGT_N
-# # string | .features[99].properties.VERSION_DA
-# # string | .features[99].type
-# # string | .features[9].geometry.type
-# # string | .features[9].properties.OUTLINE_TY
-# # string | .features[9].properties.SDE_TEXT_L
-# # string | .features[9].properties.UNIT_AGT_1
-# # string | .features[9].properties.UNIT_AGT_N
-# # string | .features[9].properties.VERSION_DA
-# # string | .features[9].type
-# # string | .type
-# # ./xmlxpath.py  -a -M  374.99s user 29.73s system 569% cpu 1:11.05 total
-
-# without multiproc:
-# #  array | .features[9].geometry.coordinates[1][0][7]
-# # number | .features[9].geometry.coordinates[1][0][7][0]
-# # number | .features[9].geometry.coordinates[1][0][7][1]
-# #  array | .features[9].geometry.coordinates[1][0][8]
-# # number | .features[9].geometry.coordinates[1][0][8][0]
-# # number | .features[9].geometry.coordinates[1][0][8][1]
-# #  array | .features[9].geometry.coordinates[1][0][9]
-# # number | .features[9].geometry.coordinates[1][0][9][0]
-# # number | .features[9].geometry.coordinates[1][0][9][1]
-# # string | .features[9].geometry.type
-# # object | .features[9].properties
-# # string | .features[9].properties.OUTLINE_TY
-# # string | .features[9].properties.SDE_TEXT_L
-# # number | .features[9].properties.SEQUENCE_N
-# # number | .features[9].properties.SHAPE_Area
-# # number | .features[9].properties.SHAPE_Leng
-# # number | .features[9].properties.SN_UNIT_AL
-# # number | .features[9].properties.SN_UNIT_OU
-# # string | .features[9].properties.UNIT_AGT_1
-# # string | .features[9].properties.UNIT_AGT_N
-# # string | .features[9].properties.VERSION_DA
-# # string | .features[9].type
-# # string | .type
-# # ./xmlxpath.py  -a  241.04s user 13.05s system 93% cpu 4:31.48 total
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/args.py b/elpa/x-path-walker-20160922.1835/xpathwalker/args.py
deleted file mode 100644 (file)
index 85b02cf..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-from argparse import ArgumentParser
-import os
-import sys
-
-exts_mode = {'.html': "HTML", '.html': 'HTML', '.xml': 'XML', '.json': 'JSON', '.yaml': 'YAML'}
-
-def parse_args(argv):
-    """parse command line arguments
-
-    :param argv:
-    :returns: Processor class
-    :rtype:
-
-    """
-    default_separator = "."
-
-    parser = ArgumentParser(description="Xpath helper")
-    parser.add_argument("inputfile",
-                        help="Input FILE", type=str)
-    parser.add_argument("-x", "--xpath", dest='xpath',
-                        help="Returns line number corresponding to xpath from FILE", type=str)
-    parser.add_argument("-m", "--mode", dest='mode',
-                        help="Language type", type=str, choices=('XML', 'HTML', 'JSON'))
-    parser.add_argument("-a", dest='verbosity', action="store_true", default=False,
-                        help="Increase verbosity")
-    parser.add_argument("-M", dest='multiproc', action="store_true", default=False,
-                        help="Use multiple process when possible")
-    parser.add_argument("-j", dest='use_jq', action="store_true", default=False,
-                        help="JSON: Use jq for processing")
-    parser.add_argument("-F", dest='separator', default=default_separator, type=str,
-                        help="Path elements separator")
-    args = parser.parse_args(argv)
-
-    inputfile = args.inputfile
-    proc = False
-    if(not os.path.isfile(inputfile)):
-        sys.exit(1)
-
-    ext = os.path.splitext(inputfile)[1].lower()
-
-    if(args.mode is None):
-        if ext not in exts_mode.keys():
-            print("Unrecognized file format.")
-            sys.exit(1)
-        else:
-            args.mode = exts_mode[ext]
-
-    if(args.mode == 'HTML'):
-        from xpathwalker.lxml_Processor import HTML_Processor
-        proc = HTML_Processor()
-        if args.xpath:
-            args.xpath = "/"+args.xpath
-    elif(args.mode == 'XML'):
-        from xpathwalker.lxml_Processor import XML_Processor
-        proc = XML_Processor()
-        if args.xpath:
-            args.xpath = "/"+args.xpath
-    elif(args.mode == 'JSON'):
-        if(args.use_jq):
-            from xpathwalker.json_jq_Processor import JSON_jq_Processor
-            proc = JSON_jq_Processor()
-        else:
-            from xpathwalker.json_Processor import JSON_Processor
-            proc = JSON_Processor()
-    else:
-        print("Error in arg parsing")
-        sys.exit(2)
-
-    proc.separator = args.separator
-    proc.parse_file(inputfile)
-
-    if(args.xpath is not None):
-        print(proc.get_path_line_number(args.xpath, args.verbosity))
-    else:
-        print("\n".join(proc.list_paths(args.verbosity)))
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/json_Processor.py b/elpa/x-path-walker-20160922.1835/xpathwalker/json_Processor.py
deleted file mode 100644 (file)
index 1a4de78..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-from xpathwalker.utils import list_compare_idx
-from xpathwalker.processor import Processor
-from xpathwalker.utils import traverse_and_remove_path,\
-    get_dict_from_path, get_class
-import json
-from collections import MutableSequence, MutableMapping
-from collections import OrderedDict
-
-##########################################################################
-# JSON / Python                                                          #
-##########################################################################
-
-
-class JSON_Processor(Processor):
-    file_line_number = 0
-
-    def isValidJsonShorthandPropertyName(self, key):
-        if not key[0].isalpha() or not key.isalnum():
-            return('["' + key + '"]')
-        else:
-            return(self.separator + key)
-
-
-    def paths(self, obj, dirs=True, leaves=True, path='', skip=False, allow_empty_string_keys=False):
-        """Yield all paths of the object.
-        Arguments:
-        obj -- An object to get paths from.
-        Keyword Arguments:
-        dirs -- Yield intermediate paths.
-        leaves -- Yield the paths with leaf objects.
-        path -- A list of keys representing the path.
-        skip -- Skip special keys beginning with '+'.
-        """
-        if isinstance(obj, MutableMapping):
-            # Python 3 support
-            # if PY3:
-            iteritems = obj.items()
-
-            for (k, v) in iteritems:
-                if issubclass(k.__class__, (str)):
-                    if (not k) and (not allow_empty_string_keys):
-                        print("Empty string keys not allowed without "
-                              "dpath.options.ALLOW_EMPTY_STRING_KEYS=True")
-                    elif (skip and k[0] == '+'):
-                        continue
-                newpath = path + self.isValidJsonShorthandPropertyName(str(k))
-                # validate(newpath)
-                if dirs:
-                    yield {newpath: {"class": v.__class__}}
-                for child in self.paths(v, dirs, leaves, newpath, skip):
-                    yield child
-
-        elif isinstance(obj, MutableSequence):
-            for (i, v) in enumerate(obj):
-                newpath = path + "[%s]" % i
-                if issubclass(i.__class__, int):
-                    newpath = path + "[%d]" % i
-                if dirs:
-                    yield {newpath: {"class": v.__class__}}
-                for child in self.paths(obj[i], dirs, leaves, newpath, skip):
-                    yield child
-        elif leaves:
-            yield path + [[obj, obj.__class__]]
-        elif not dirs:
-            yield path
-
-    def serialize_json(self):
-        res = OrderedDict()
-        for x in self.paths(self.parsed, leaves=False):
-            res.update(x)
-        return(res)
-
-    def list_paths(self, with_attrs=True):
-        json_paths = self.serialize_json()
-        if(with_attrs):
-            return(["%6s | %s" % (get_class(json_paths[x]["class"]), x) for x in json_paths.keys()])
-        else:
-            return([x for x in json_paths.keys()])
-
-    def get_path_line_number(self, path, with_attrs=False):
-        path = path.split("| ")[1] if (with_attrs is True) else path
-
-        orig = self.parsed
-        path = get_dict_from_path(path, self.separator)
-        res = traverse_and_remove_path(orig, path)
-        orig = json.dumps(orig, indent=4).split("\n")
-
-        if(len(orig) != self.file_line_number):
-            raise ValueError("This json file formatting is not compatible. Please run `python -m json.tool file`")
-
-        with_del = json.dumps(res, indent=4).split("\n")
-        return(list_compare_idx(orig, with_del) + 1)
-
-    def parse_file(self, file):
-        with open(file) as f:
-            self.file_line_number = len(f.readlines())
-            f.seek(0)
-            self.parsed = json.load(f, object_pairs_hook=OrderedDict)
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/json_jq_Processor.py b/elpa/x-path-walker-20160922.1835/xpathwalker/json_jq_Processor.py
deleted file mode 100644 (file)
index cb5b5bf..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-import subprocess
-import sys
-import os
-from tempfile import NamedTemporaryFile
-from xpathwalker.utils import list_compare_idx
-from xpathwalker.processor import Processor
-
-##########################################################################
-# JSON                                                                   #
-##########################################################################
-
-jq_command = """def safeLookupValue:
-        if type != "string" then
-                tostring
-        else
-                .
-        end;
-\
-def arrayToLookup:
-        map(safeLookupValue)
-        | reduce .[] as $exists (
-                {};
-                . + {
-                        ($exists): null
-                }
-        );
-\
-def lookup(value):
-        (value | safeLookupValue) as $value
-        | has($value);
-\
-def isWhitelisted(whitelist):
-        whitelist as $whitelist
-        | explode
-        | map(
-                . as $charCode
-                | $whitelist
-                | lookup($charCode)
-        )
-        | all;
-\
-def isNumeric:
-        ("0123456789" | explode | arrayToLookup) as $digits
-        | isWhitelisted($digits);
-\
-def isAlpha:
-        ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | explode | arrayToLookup) as $letters
-        | isWhitelisted($letters);
-\
-def isAlphanumeric:
-        ("0123456789" | explode | arrayToLookup) as $digits
-        | ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | explode | arrayToLookup) as $letters
-        | ("_" | explode | arrayToLookup) as $special
-        | ($digits + $letters + $special) as $alphanumeric
-        | isWhitelisted($alphanumeric);
-\
-def isValidJsonShorthandPropertyName:
-        (.[0:1] | isAlpha | not) or (isAlphanumeric | not);
-\
-[
-        path(..)
-        | map(
-                if type == "number" then
-                        ["[",(.|tostring),"]"]|join("")
-                else
-                        tostring
-                        | if isValidJsonShorthandPropertyName then
-                                "[\\"\\(.)\\"]"
-                        else
-                                .
-                        end
-                end
-        )
-        | join(".")
-        | split("." + "[")
-        | join("[")
-]
-| unique
-| map("." + .)
-| .[]"""
-
-jq_exec = ["jq", "--raw-output"]
-
-def jq_proc(args):
-    with NamedTemporaryFile() as f:
-        try:
-            proc = subprocess.check_call(args,
-                                         stdout=f,
-                                         stderr=subprocess.STDOUT)
-        except subprocess.CalledProcessError:
-            print(proc.stderr.fseek(0).read().decode('utf-8'))
-            sys.exit(1)
-        f.seek(0)
-        return f.read().decode('utf-8').split('\n')
-
-
-class JSON_jq_Processor(Processor):
-    file = ""
-
-    def list_paths(self, with_attrs=True, multiproc=False):
-        if(not os.path.isfile(self.file)):
-            sys.exit(1)
-        proc = jq_proc(args=jq_exec + [jq_command,
-                                       self.file])
-        paths = [x for x in proc if x != '']
-        res = []
-        if(with_attrs is False):
-            res = paths
-        elif with_attrs is True:
-            if multiproc is False:
-                for x in paths:
-                    proc = jq_proc(args=jq_exec + ["%s|type" % x,
-                                                   self.file])
-                    type = proc[0]
-                    res.append("%6s | %s" % (type[0:6], x))
-            else:
-                def get_types(q, x, file):
-                    proc = jq_proc(args=jq_exec + ["%s|type" % x,
-                                                   self.file])
-                    type = proc[0]
-                    q.put("%6s | %s" % (type[0:6], x))
-                import queue
-                import threading
-                q = queue.PriorityQueue()
-                for x in paths:
-                    t = threading.Thread(target=get_types, args=(q, x, self.file))
-                    t. start()
-                while(q.qsize() > 0):
-                    res.append(q.get())
-        return(res)
-
-    def get_path_line_number(self, path, with_attrs=False):
-        path = path.split("| ")[1] if (with_attrs is True) else path
-        proc = jq_proc(args=jq_exec + ['.',
-                                       self.file])
-        orig = proc
-        proc = jq_proc(args=jq_exec + ['del(%s)' % path,
-                                       self.file])
-        with_del = proc
-        return(list_compare_idx(orig, with_del) + 1)
-
-    def parse_file(self, file):
-        if(not os.path.isfile(file)):
-            print("File %s: Not Found" % (file))
-            sys.exit(1)
-        self.file = file
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/lxml_Processor.py b/elpa/x-path-walker-20160922.1835/xpathwalker/lxml_Processor.py
deleted file mode 100644 (file)
index 342e048..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-from xpathwalker.processor import Processor
-import os
-import sys
-import lxml.etree
-import lxml.html
-
-
-class lxmlProcessor(Processor):
-    """ [X/HT]ML processor
-    """
-    def list_paths(self, with_attrs=False):
-        if(not self.parsed):
-            raise ValueError("No data in parsed")
-        parsed = self.parsed
-        res = []
-        for el in parsed.xpath("//*"):
-            if(with_attrs):
-                if el.keys() is None:
-                    res.append("/%s | %s | %s" % (parsed.getelementpath(el), ",".join(el.keys())))
-                else:
-                    res.append("/%s | %s" % (parsed.getelementpath(el),
-                                             ",".join(["%s: %s" % (attr, el.get(key=attr)) for attr in el.keys()])))
-            else:
-                res.append("/%s" % (parsed.getelementpath(el)))
-        return(res)
-
-    def handle_namespace_in_xpath(self, xpath):
-        closinp = len(xpath.split("}"))
-        if(closinp > 1 and closinp != len(xpath.split("}"))):
-            return xpath
-        import re
-        import string
-        insidep = r"(?<={)[^}]*"
-        namesspaces = re.findall(insidep, xpath)
-        nsdict = {}
-
-        def get_letters(matchobj):
-            get_letters.counter += 1
-            id = string.ascii_letters[get_letters.counter]
-            nsdict.update({id: namesspaces[get_letters.counter]})
-            return id + ":"
-        get_letters.counter = -1
-        par = re.compile(r"{"+insidep+r"}")
-        xpath = par.sub(get_letters, xpath)
-        return (xpath, {"namespaces": nsdict})
-
-    def get_path_line_number(self, xpath, with_attrs=False):
-        if(not self.parsed):
-            raise ValueError("No data in parsed")
-
-        parsed = self.parsed
-        xpath = xpath.split(" | ")[0] if (with_attrs is True or xpath.find(" | ") > -1) else xpath
-        res = 0
-        matchs = []
-
-        if(xpath.find("{") > -1):  # Handle namespace cases
-            xpath, args = self.handle_namespace_in_xpath(xpath)
-            matchs = parsed.xpath(xpath, **args)
-        else:
-            matchs = parsed.xpath(xpath)
-        if(len(matchs) > 0):
-            res = matchs[0].sourceline
-        return(res)
-
-class HTML_Processor(lxmlProcessor):
-    def parse_file(self, file):
-        """HTML file parse from lxml
-
-        :param file: file path (string)
-        :returns: null
-        :rtype:
-
-        """
-        self.parsed = lxml.html.parse(file)
-
-class XML_Processor(lxmlProcessor):
-    def parse_file(self, file):
-        """HTML file parse from lxml
-
-        :param file: file path (string)
-        :returns: null
-        :rtype:
-
-        """
-        self.parsed = lxml.etree.parse(file)
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/processor.py b/elpa/x-path-walker-20160922.1835/xpathwalker/processor.py
deleted file mode 100644 (file)
index 9cda9e6..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-class Processor:
-    """An abstract object class to handle the parsing/procesing of files
-
-    """
-    separator = "."
-
-    def __init__(self):
-        super(Processor, self).__init__()
-
-    def list_paths(self, parsed, with_attrs=False):
-        """Return array of path separated by the separator
-
-        :param parsed: A python type object
-        :param with_attrs: List additional attributes
-        :returns: array of paths
-        :rtype: array
-
-        """
-        pass
-
-    def get_path_line_number(self, path, with_attrs=False):
-        """Returns the line number from the file corresponding `path`
-
-        :param path: Path seeked
-        :param with_attrs: `True` if `path` is formatted with additional attributes
-        :returns: line numer corresponding to path
-        :rtype: int
-
-        """
-        pass
-
-    def parse_file(self, file):
-        """Translate the `file` into python object
-
-        :param file: File path
-        :returns: Nothing. insternal variable updated.
-        :rtype:
-
-        """
-        pass
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/utils.py b/elpa/x-path-walker-20160922.1835/xpathwalker/utils.py
deleted file mode 100644 (file)
index be6b8e2..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-from collections import OrderedDict
-
-##########################################################################
-# Utils                                                                  #
-##########################################################################
-
-def get_class(obj):
-    name = obj.__name__
-    if(name == "OrderedDict"):
-        return("object")
-    elif(name == "NoneType"):
-        return("null")
-    return(name)
-
-def list_compare_idx(list1, list2):
-    index = 0
-    for idx, origline in enumerate(list1):
-        if(list2[idx] != origline):
-            if((list2[idx]+",") != origline):
-                index = idx
-                break
-    return(index)
-
-def split_path(path, separator, inside_special=False):
-    first_match = '"]' if inside_special else '["'
-    i = path.find(first_match)
-    if i != -1 and inside_special is False:
-        if(path[0:i] != ''):
-            return (split_path(path[0:i],
-                               separator=separator,
-                               inside_special=False) +
-                    split_path(path[i+len('["'):],
-                               separator=separator,
-                               inside_special=True))
-        else:
-            return (split_path(path[i+len('["'):],
-                               separator=separator,
-                               inside_special=True))
-    if i != -1 and inside_special is True:
-        if(path[i+len('["'):] != ''):
-            return ([path[:i], "special"],) + split_path(path[i+len('["'):],
-                                                         separator=separator,
-                                                         inside_special=False)
-        else:
-            return ([path[:i], "special"],)
-    else:
-        i = path.find(separator)
-        if i == -1:
-            return (path,)
-        else:
-            if(i != 0):
-                return (path[:i],) + split_path(path[i+1:], separator)
-            else:
-                return split_path(path[i+1:], separator)
-
-
-def get_dict_from_path(path, separator):
-    path = split_path(path, separator)
-
-    res = []
-    for x in path:
-        if not isinstance(x, list):
-            pos = x.find("[")
-            while pos != -1:
-                if pos == 0:
-                    i1 = x.find("]")
-                    x1 = int(x[0:i1].replace("[", "", 1).replace("]", "", 1))
-                    x = x[i1+1:]
-                    res.append(x1)
-                else:
-                    res.append(x[0:pos])
-                    x = x[pos:]
-                pos = x.find("[")
-        else:
-            res.append(x[0])
-    return(res)
-
-def traverse_and_remove_path(obj, path=None, match="First"):
-    if path is None:
-        path = []
-    if isinstance(obj, dict):
-        res = OrderedDict()
-        for k, v in obj.items():
-            cmatch = False
-            if(match and len(path) > 0 and path[0] == k):
-                cmatch = True
-            res.update({k: traverse_and_remove_path(v, path=path[1:], match=cmatch)})
-        if(len(path) == 1 and path[0] in res.keys() and match):
-            del res[path[0]]
-        return res
-    elif isinstance(obj, list):
-        res = []
-        for i, elem in enumerate(obj):
-            cmatch = False
-            if(match and len(path) >= 1 and isinstance(path[0], int) and path[0] < len(obj) and i == path[0]):
-                cmatch = True
-            res.append(traverse_and_remove_path(elem, path=path[1:], match=cmatch))
-        if(len(path) == 1 and isinstance(path[0], int) and path[0] < len(res) and match):
-            res.pop(path[0])
-        return res
-    else:
-        return obj  # no container, just values (str, int, float)
diff --git a/elpa/x-path-walker-20160922.1835/xpathwalker/yaml_Processor.py b/elpa/x-path-walker-20160922.1835/xpathwalker/yaml_Processor.py
deleted file mode 100644 (file)
index fd28d37..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-##########################################################################
-# YAML                                                                   #
-##########################################################################
-import yaml
-from xpathwalker.utils import list_compare_idx
-from xpathwalker.utils import traverse_and_remove_path, get_dict_from_path, get_class, paths
-from collections import OrderedDict
-import os
-
-def parse_yaml(file):
-    with open(file) as f:
-        yaml_data = yaml.load(f)
-        res = OrderedDict()
-        for x in paths(yaml_data, leaves=False):
-            res.update(x)
-        return(res)
-
-def get_yaml_paths(file, include_type=True):  # XXX: ordering is lost
-    yaml_paths = parse_yaml(file)
-    if(include_type is True):
-        return(["%s | %s" % (get_class(yaml_paths[x]['class']), x) for x in yaml_paths.keys()])
-    else:
-        return(yaml_paths.keys())
-
-def get_yaml_path_line_python(file, path, include_type=False):
-    if(not os.path.isfile(file)):
-        sys.exit(1)
-    path = path.split("| ")[1] if (include_type is True) else path
-    orig = ""
-    with open(file) as f:
-        orig = yaml.load(f)
-    path = get_dict_from_path(path)
-    res = traverse_and_remove_path(orig, path)
-    yaml_dump_options = {"indent": 4, "default_flow_style": False, "explicit_start": False}
-    orig = yaml.dump(orig, **yaml_dump_options).split("\n")
-    with_del = yaml.dump(dict(res), **yaml_dump_options).split("\n")
-    return(list_compare_idx(orig, with_del) + 1)
diff --git a/elpa/x-path-walker-20220714.1056/x-path-walker-autoloads.el b/elpa/x-path-walker-20220714.1056/x-path-walker-autoloads.el
new file mode 100644 (file)
index 0000000..9790c43
--- /dev/null
@@ -0,0 +1,28 @@
+;;; x-path-walker-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "x-path-walker" "x-path-walker.el" (0 0 0 0))
+;;; Generated autoloads from x-path-walker.el
+
+(autoload 'helm-x-path-walker "x-path-walker" nil t nil)
+
+(register-definition-prefixes "x-path-walker" '("x-path-"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("x-path-walker-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; x-path-walker-autoloads.el ends here
diff --git a/elpa/x-path-walker-20220714.1056/x-path-walker-pkg.el b/elpa/x-path-walker-20220714.1056/x-path-walker-pkg.el
new file mode 100644 (file)
index 0000000..15b837f
--- /dev/null
@@ -0,0 +1,13 @@
+(define-package "x-path-walker" "20220714.1056" "Navigation feature for JSON/XML/HTML based on path (imenu like)"
+  '((helm-core "3.6.0"))
+  :commit "c91deaaba0d5cc9018008a39c96222deacba3868" :authors
+  '((nil . "<lompik@ArchOrion>"))
+  :maintainers
+  '((nil . "<lompik@ArchOrion>"))
+  :maintainer
+  '(nil . "<lompik@ArchOrion>")
+  :keywords
+  '("convenience"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/x-path-walker-20220714.1056/x-path-walker.el b/elpa/x-path-walker-20220714.1056/x-path-walker.el
new file mode 100644 (file)
index 0000000..1a62745
--- /dev/null
@@ -0,0 +1,130 @@
+;;; x-path-walker.el --- Navigation feature for JSON/XML/HTML based on path (imenu like)  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015
+
+;; Author:  <lompik@ArchOrion>
+;; Keywords: convenience
+;; Package-Requires: ((helm-core "3.6.0"))
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'helm-core)
+
+(defvar x-path-walker-source-dir (concat (if load-file-name
+                                             (file-name-directory load-file-name)
+                                           default-directory)))
+
+(defvar x-path-walker-objects-separators ".")
+
+(defun x-path-walker-command ()
+  (list (concat "PYTHONPATH=" x-path-walker-source-dir)
+        (executable-find "python3")
+        "-m xpathwalker"))
+
+(defvar x-path-walker-verbose nil)
+
+(defun x-path-build-cmd-path (args)
+  (let ((cmdpython (x-path-walker-command)))
+    (mapconcat #'identity
+               (append cmdpython
+                       args)
+               " ")))
+
+(defun x-path-run-py-script (args)
+  (let ((cmd (x-path-build-cmd-path args)))
+    (shell-command-to-string cmd)))
+
+(defun x-path-get-mode ()
+  (let ((mm (pcase major-mode
+              (`json-mode "JSON")
+              (`xml-mode "XML")
+              (`nxml-mode "XML")
+              (`html-mode "HTML")
+              (`web-mode "HTML")
+              (code nil))))
+    (unless (and (buffer-file-name) mm)
+      (keyboard-quit))
+    mm))
+
+(defun x-path-walker-ask ()
+  (interactive)
+  (if (and (buffer-modified-p)
+           (yes-or-no-p "Buffer will be linted. Do you want to save the current buffer (required)?"))
+      (save-current-buffer)
+    (if (buffer-modified-p)
+        (keyboard-quit))))
+
+(defun x-path-walker-jump-path (path)
+  (let* ((mode (x-path-get-mode))
+         (path (if (not (bound-and-true-p x-path-walker-verbose))
+                   path
+                 (if (or (string= mode "HTML")
+                         (string= mode "XML"))
+                     (car (split-string path " | "))
+                   (if (and (string= mode "JSON") )
+                       (car (cdr (split-string path " | ")))
+                     ""))))
+         (line (replace-regexp-in-string
+                "\n$" ""
+                (x-path-run-py-script `("-x"
+                                        ,(shell-quote-argument path)
+                                        "-m"
+                                        ,mode
+                                        ,(buffer-file-name) )))))
+    (if (string= mode "JSON")
+        (progn  (x-path-walker-ask)
+                (erase-buffer)
+                (shell-command-on-region (point-min) (point-max)
+                                         (concat "python3 -m json.tool "
+                                                 (buffer-file-name))
+                                         (current-buffer) t
+                                         "*x-path-walker-json-error*" t)))
+    (unless (or (string= "" line))
+      (goto-char 0)
+      (forward-line (1- (string-to-number line)))
+      (recenter)
+      (back-to-indentation))))
+
+;;;###autoload
+(defun helm-x-path-walker()
+  (interactive)
+  (let* ((mode (x-path-get-mode))
+         (file (buffer-file-name))
+         (cmd-line `(,(if (bound-and-true-p x-path-walker-verbose)
+                          "-a"
+                        "")
+                     "-m"
+                     ,mode
+                     ,file ))
+         (cands  (split-string (x-path-run-py-script cmd-line)"\n")))
+    (helm
+     :sources (helm-build-sync-source "PATH-WALKER"
+                :keymap helm-map
+                :candidates  cands
+                :candidate-number-limit 500
+                :action (helm-make-actions
+                         "Jump to path" 'x-path-walker-jump-path))
+     :prompt "Select Path:"
+     :resume 'noresume
+     :keymap helm-map
+     :buffer "*helm path-walker*")))
+
+(provide 'x-path-walker)
+;;; x-path-walker.el ends here
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/__init__.py b/elpa/x-path-walker-20220714.1056/xpathwalker/__init__.py
new file mode 100644 (file)
index 0000000..894c4e7
--- /dev/null
@@ -0,0 +1,3 @@
+# xpathwalker
+
+has_legs = False
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/__main__.py b/elpa/x-path-walker-20220714.1056/xpathwalker/__main__.py
new file mode 100755 (executable)
index 0000000..745fbe7
--- /dev/null
@@ -0,0 +1,58 @@
+import sys
+
+from xpathwalker.args import parse_args
+
+
+##########################################################################
+# Main                                                                   #
+##########################################################################
+
+def main(argv):
+    parse_args(argv)
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
+
+# Bench:
+# wc -l
+# 21302 /mnt/VM/home/lompik/Programmation/Web/d3_Map_GOM/Data/fldunit.json
+# with multiproc:
+# # string | .features[99].properties.UNIT_AGT_N
+# # string | .features[99].properties.VERSION_DA
+# # string | .features[99].type
+# # string | .features[9].geometry.type
+# # string | .features[9].properties.OUTLINE_TY
+# # string | .features[9].properties.SDE_TEXT_L
+# # string | .features[9].properties.UNIT_AGT_1
+# # string | .features[9].properties.UNIT_AGT_N
+# # string | .features[9].properties.VERSION_DA
+# # string | .features[9].type
+# # string | .type
+# # ./xmlxpath.py  -a -M  374.99s user 29.73s system 569% cpu 1:11.05 total
+
+# without multiproc:
+# #  array | .features[9].geometry.coordinates[1][0][7]
+# # number | .features[9].geometry.coordinates[1][0][7][0]
+# # number | .features[9].geometry.coordinates[1][0][7][1]
+# #  array | .features[9].geometry.coordinates[1][0][8]
+# # number | .features[9].geometry.coordinates[1][0][8][0]
+# # number | .features[9].geometry.coordinates[1][0][8][1]
+# #  array | .features[9].geometry.coordinates[1][0][9]
+# # number | .features[9].geometry.coordinates[1][0][9][0]
+# # number | .features[9].geometry.coordinates[1][0][9][1]
+# # string | .features[9].geometry.type
+# # object | .features[9].properties
+# # string | .features[9].properties.OUTLINE_TY
+# # string | .features[9].properties.SDE_TEXT_L
+# # number | .features[9].properties.SEQUENCE_N
+# # number | .features[9].properties.SHAPE_Area
+# # number | .features[9].properties.SHAPE_Leng
+# # number | .features[9].properties.SN_UNIT_AL
+# # number | .features[9].properties.SN_UNIT_OU
+# # string | .features[9].properties.UNIT_AGT_1
+# # string | .features[9].properties.UNIT_AGT_N
+# # string | .features[9].properties.VERSION_DA
+# # string | .features[9].type
+# # string | .type
+# # ./xmlxpath.py  -a  241.04s user 13.05s system 93% cpu 4:31.48 total
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/args.py b/elpa/x-path-walker-20220714.1056/xpathwalker/args.py
new file mode 100644 (file)
index 0000000..85b02cf
--- /dev/null
@@ -0,0 +1,75 @@
+from argparse import ArgumentParser
+import os
+import sys
+
+exts_mode = {'.html': "HTML", '.html': 'HTML', '.xml': 'XML', '.json': 'JSON', '.yaml': 'YAML'}
+
+def parse_args(argv):
+    """parse command line arguments
+
+    :param argv:
+    :returns: Processor class
+    :rtype:
+
+    """
+    default_separator = "."
+
+    parser = ArgumentParser(description="Xpath helper")
+    parser.add_argument("inputfile",
+                        help="Input FILE", type=str)
+    parser.add_argument("-x", "--xpath", dest='xpath',
+                        help="Returns line number corresponding to xpath from FILE", type=str)
+    parser.add_argument("-m", "--mode", dest='mode',
+                        help="Language type", type=str, choices=('XML', 'HTML', 'JSON'))
+    parser.add_argument("-a", dest='verbosity', action="store_true", default=False,
+                        help="Increase verbosity")
+    parser.add_argument("-M", dest='multiproc', action="store_true", default=False,
+                        help="Use multiple process when possible")
+    parser.add_argument("-j", dest='use_jq', action="store_true", default=False,
+                        help="JSON: Use jq for processing")
+    parser.add_argument("-F", dest='separator', default=default_separator, type=str,
+                        help="Path elements separator")
+    args = parser.parse_args(argv)
+
+    inputfile = args.inputfile
+    proc = False
+    if(not os.path.isfile(inputfile)):
+        sys.exit(1)
+
+    ext = os.path.splitext(inputfile)[1].lower()
+
+    if(args.mode is None):
+        if ext not in exts_mode.keys():
+            print("Unrecognized file format.")
+            sys.exit(1)
+        else:
+            args.mode = exts_mode[ext]
+
+    if(args.mode == 'HTML'):
+        from xpathwalker.lxml_Processor import HTML_Processor
+        proc = HTML_Processor()
+        if args.xpath:
+            args.xpath = "/"+args.xpath
+    elif(args.mode == 'XML'):
+        from xpathwalker.lxml_Processor import XML_Processor
+        proc = XML_Processor()
+        if args.xpath:
+            args.xpath = "/"+args.xpath
+    elif(args.mode == 'JSON'):
+        if(args.use_jq):
+            from xpathwalker.json_jq_Processor import JSON_jq_Processor
+            proc = JSON_jq_Processor()
+        else:
+            from xpathwalker.json_Processor import JSON_Processor
+            proc = JSON_Processor()
+    else:
+        print("Error in arg parsing")
+        sys.exit(2)
+
+    proc.separator = args.separator
+    proc.parse_file(inputfile)
+
+    if(args.xpath is not None):
+        print(proc.get_path_line_number(args.xpath, args.verbosity))
+    else:
+        print("\n".join(proc.list_paths(args.verbosity)))
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/json_Processor.py b/elpa/x-path-walker-20220714.1056/xpathwalker/json_Processor.py
new file mode 100644 (file)
index 0000000..df55a32
--- /dev/null
@@ -0,0 +1,98 @@
+import json
+from collections.abc import MutableSequence, MutableMapping
+from collections import OrderedDict
+from xpathwalker.utils import list_compare_idx
+from xpathwalker.processor import Processor
+from xpathwalker.utils import traverse_and_remove_path,\
+    get_dict_from_path, get_class
+
+##########################################################################
+# JSON / Python                                                          #
+##########################################################################
+
+
+class JSON_Processor(Processor):
+    file_line_number = 0
+
+    def isValidJsonShorthandPropertyName(self, key):
+        if not key[0].isalpha() or not key.isalnum():
+            return('["' + key + '"]')
+        else:
+            return(self.separator + key)
+
+
+    def paths(self, obj, dirs=True, leaves=True, path='', skip=False, allow_empty_string_keys=False):
+        """Yield all paths of the object.
+        Arguments:
+        obj -- An object to get paths from.
+        Keyword Arguments:
+        dirs -- Yield intermediate paths.
+        leaves -- Yield the paths with leaf objects.
+        path -- A list of keys representing the path.
+        skip -- Skip special keys beginning with '+'.
+        """
+        if isinstance(obj, MutableMapping):
+            # Python 3 support
+            # if PY3:
+            iteritems = obj.items()
+
+            for (k, v) in iteritems:
+                if issubclass(k.__class__, (str)):
+                    if (not k) and (not allow_empty_string_keys):
+                        print("Empty string keys not allowed without "
+                              "dpath.options.ALLOW_EMPTY_STRING_KEYS=True")
+                    elif (skip and k[0] == '+'):
+                        continue
+                newpath = path + self.isValidJsonShorthandPropertyName(str(k))
+                # validate(newpath)
+                if dirs:
+                    yield {newpath: {"class": v.__class__}}
+                for child in self.paths(v, dirs, leaves, newpath, skip):
+                    yield child
+
+        elif isinstance(obj, MutableSequence):
+            for (i, v) in enumerate(obj):
+                newpath = path + "[%s]" % i
+                if issubclass(i.__class__, int):
+                    newpath = path + "[%d]" % i
+                if dirs:
+                    yield {newpath: {"class": v.__class__}}
+                for child in self.paths(obj[i], dirs, leaves, newpath, skip):
+                    yield child
+        elif leaves:
+            yield path + [[obj, obj.__class__]]
+        elif not dirs:
+            yield path
+
+    def serialize_json(self):
+        res = OrderedDict()
+        for x in self.paths(self.parsed, leaves=False):
+            res.update(x)
+        return(res)
+
+    def list_paths(self, with_attrs=True):
+        json_paths = self.serialize_json()
+        if(with_attrs):
+            return(["%6s | %s" % (get_class(json_paths[x]["class"]), x) for x in json_paths.keys()])
+        else:
+            return([x for x in json_paths.keys()])
+
+    def get_path_line_number(self, path, with_attrs=False):
+        path = path.split("| ")[1] if (with_attrs is True) else path
+
+        orig = self.parsed
+        path = get_dict_from_path(path, self.separator)
+        res = traverse_and_remove_path(orig, path)
+        orig = json.dumps(orig, indent=4).split("\n")
+
+        if(len(orig) != self.file_line_number):
+            raise ValueError("This json file formatting is not compatible. Please run `python -m json.tool file`")
+
+        with_del = json.dumps(res, indent=4).split("\n")
+        return(list_compare_idx(orig, with_del) + 1)
+
+    def parse_file(self, file):
+        with open(file) as f:
+            self.file_line_number = len(f.readlines())
+            f.seek(0)
+            self.parsed = json.load(f, object_pairs_hook=OrderedDict)
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/json_jq_Processor.py b/elpa/x-path-walker-20220714.1056/xpathwalker/json_jq_Processor.py
new file mode 100644 (file)
index 0000000..cb5b5bf
--- /dev/null
@@ -0,0 +1,146 @@
+import subprocess
+import sys
+import os
+from tempfile import NamedTemporaryFile
+from xpathwalker.utils import list_compare_idx
+from xpathwalker.processor import Processor
+
+##########################################################################
+# JSON                                                                   #
+##########################################################################
+
+jq_command = """def safeLookupValue:
+        if type != "string" then
+                tostring
+        else
+                .
+        end;
+\
+def arrayToLookup:
+        map(safeLookupValue)
+        | reduce .[] as $exists (
+                {};
+                . + {
+                        ($exists): null
+                }
+        );
+\
+def lookup(value):
+        (value | safeLookupValue) as $value
+        | has($value);
+\
+def isWhitelisted(whitelist):
+        whitelist as $whitelist
+        | explode
+        | map(
+                . as $charCode
+                | $whitelist
+                | lookup($charCode)
+        )
+        | all;
+\
+def isNumeric:
+        ("0123456789" | explode | arrayToLookup) as $digits
+        | isWhitelisted($digits);
+\
+def isAlpha:
+        ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | explode | arrayToLookup) as $letters
+        | isWhitelisted($letters);
+\
+def isAlphanumeric:
+        ("0123456789" | explode | arrayToLookup) as $digits
+        | ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | explode | arrayToLookup) as $letters
+        | ("_" | explode | arrayToLookup) as $special
+        | ($digits + $letters + $special) as $alphanumeric
+        | isWhitelisted($alphanumeric);
+\
+def isValidJsonShorthandPropertyName:
+        (.[0:1] | isAlpha | not) or (isAlphanumeric | not);
+\
+[
+        path(..)
+        | map(
+                if type == "number" then
+                        ["[",(.|tostring),"]"]|join("")
+                else
+                        tostring
+                        | if isValidJsonShorthandPropertyName then
+                                "[\\"\\(.)\\"]"
+                        else
+                                .
+                        end
+                end
+        )
+        | join(".")
+        | split("." + "[")
+        | join("[")
+]
+| unique
+| map("." + .)
+| .[]"""
+
+jq_exec = ["jq", "--raw-output"]
+
+def jq_proc(args):
+    with NamedTemporaryFile() as f:
+        try:
+            proc = subprocess.check_call(args,
+                                         stdout=f,
+                                         stderr=subprocess.STDOUT)
+        except subprocess.CalledProcessError:
+            print(proc.stderr.fseek(0).read().decode('utf-8'))
+            sys.exit(1)
+        f.seek(0)
+        return f.read().decode('utf-8').split('\n')
+
+
+class JSON_jq_Processor(Processor):
+    file = ""
+
+    def list_paths(self, with_attrs=True, multiproc=False):
+        if(not os.path.isfile(self.file)):
+            sys.exit(1)
+        proc = jq_proc(args=jq_exec + [jq_command,
+                                       self.file])
+        paths = [x for x in proc if x != '']
+        res = []
+        if(with_attrs is False):
+            res = paths
+        elif with_attrs is True:
+            if multiproc is False:
+                for x in paths:
+                    proc = jq_proc(args=jq_exec + ["%s|type" % x,
+                                                   self.file])
+                    type = proc[0]
+                    res.append("%6s | %s" % (type[0:6], x))
+            else:
+                def get_types(q, x, file):
+                    proc = jq_proc(args=jq_exec + ["%s|type" % x,
+                                                   self.file])
+                    type = proc[0]
+                    q.put("%6s | %s" % (type[0:6], x))
+                import queue
+                import threading
+                q = queue.PriorityQueue()
+                for x in paths:
+                    t = threading.Thread(target=get_types, args=(q, x, self.file))
+                    t. start()
+                while(q.qsize() > 0):
+                    res.append(q.get())
+        return(res)
+
+    def get_path_line_number(self, path, with_attrs=False):
+        path = path.split("| ")[1] if (with_attrs is True) else path
+        proc = jq_proc(args=jq_exec + ['.',
+                                       self.file])
+        orig = proc
+        proc = jq_proc(args=jq_exec + ['del(%s)' % path,
+                                       self.file])
+        with_del = proc
+        return(list_compare_idx(orig, with_del) + 1)
+
+    def parse_file(self, file):
+        if(not os.path.isfile(file)):
+            print("File %s: Not Found" % (file))
+            sys.exit(1)
+        self.file = file
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/lxml_Processor.py b/elpa/x-path-walker-20220714.1056/xpathwalker/lxml_Processor.py
new file mode 100644 (file)
index 0000000..342e048
--- /dev/null
@@ -0,0 +1,85 @@
+from xpathwalker.processor import Processor
+import os
+import sys
+import lxml.etree
+import lxml.html
+
+
+class lxmlProcessor(Processor):
+    """ [X/HT]ML processor
+    """
+    def list_paths(self, with_attrs=False):
+        if(not self.parsed):
+            raise ValueError("No data in parsed")
+        parsed = self.parsed
+        res = []
+        for el in parsed.xpath("//*"):
+            if(with_attrs):
+                if el.keys() is None:
+                    res.append("/%s | %s | %s" % (parsed.getelementpath(el), ",".join(el.keys())))
+                else:
+                    res.append("/%s | %s" % (parsed.getelementpath(el),
+                                             ",".join(["%s: %s" % (attr, el.get(key=attr)) for attr in el.keys()])))
+            else:
+                res.append("/%s" % (parsed.getelementpath(el)))
+        return(res)
+
+    def handle_namespace_in_xpath(self, xpath):
+        closinp = len(xpath.split("}"))
+        if(closinp > 1 and closinp != len(xpath.split("}"))):
+            return xpath
+        import re
+        import string
+        insidep = r"(?<={)[^}]*"
+        namesspaces = re.findall(insidep, xpath)
+        nsdict = {}
+
+        def get_letters(matchobj):
+            get_letters.counter += 1
+            id = string.ascii_letters[get_letters.counter]
+            nsdict.update({id: namesspaces[get_letters.counter]})
+            return id + ":"
+        get_letters.counter = -1
+        par = re.compile(r"{"+insidep+r"}")
+        xpath = par.sub(get_letters, xpath)
+        return (xpath, {"namespaces": nsdict})
+
+    def get_path_line_number(self, xpath, with_attrs=False):
+        if(not self.parsed):
+            raise ValueError("No data in parsed")
+
+        parsed = self.parsed
+        xpath = xpath.split(" | ")[0] if (with_attrs is True or xpath.find(" | ") > -1) else xpath
+        res = 0
+        matchs = []
+
+        if(xpath.find("{") > -1):  # Handle namespace cases
+            xpath, args = self.handle_namespace_in_xpath(xpath)
+            matchs = parsed.xpath(xpath, **args)
+        else:
+            matchs = parsed.xpath(xpath)
+        if(len(matchs) > 0):
+            res = matchs[0].sourceline
+        return(res)
+
+class HTML_Processor(lxmlProcessor):
+    def parse_file(self, file):
+        """HTML file parse from lxml
+
+        :param file: file path (string)
+        :returns: null
+        :rtype:
+
+        """
+        self.parsed = lxml.html.parse(file)
+
+class XML_Processor(lxmlProcessor):
+    def parse_file(self, file):
+        """HTML file parse from lxml
+
+        :param file: file path (string)
+        :returns: null
+        :rtype:
+
+        """
+        self.parsed = lxml.etree.parse(file)
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/processor.py b/elpa/x-path-walker-20220714.1056/xpathwalker/processor.py
new file mode 100644 (file)
index 0000000..9cda9e6
--- /dev/null
@@ -0,0 +1,42 @@
+
+
+class Processor:
+    """An abstract object class to handle the parsing/procesing of files
+
+    """
+    separator = "."
+
+    def __init__(self):
+        super(Processor, self).__init__()
+
+    def list_paths(self, parsed, with_attrs=False):
+        """Return array of path separated by the separator
+
+        :param parsed: A python type object
+        :param with_attrs: List additional attributes
+        :returns: array of paths
+        :rtype: array
+
+        """
+        pass
+
+    def get_path_line_number(self, path, with_attrs=False):
+        """Returns the line number from the file corresponding `path`
+
+        :param path: Path seeked
+        :param with_attrs: `True` if `path` is formatted with additional attributes
+        :returns: line numer corresponding to path
+        :rtype: int
+
+        """
+        pass
+
+    def parse_file(self, file):
+        """Translate the `file` into python object
+
+        :param file: File path
+        :returns: Nothing. insternal variable updated.
+        :rtype:
+
+        """
+        pass
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/utils.py b/elpa/x-path-walker-20220714.1056/xpathwalker/utils.py
new file mode 100644 (file)
index 0000000..b06c010
--- /dev/null
@@ -0,0 +1,104 @@
+from collections import OrderedDict
+
+##########################################################################
+# Utils                                                                  #
+##########################################################################
+
+def get_class(obj):
+    name = obj.__name__
+    if(name == "OrderedDict"):
+        return("object")
+    elif(name == "NoneType"):
+        return("null")
+    return(name)
+
+def list_compare_idx(list1, list2):
+    index = 0
+    for idx, origline in enumerate(list1):
+        if(list2[idx] != origline):
+            if((list2[idx]+",") != origline):
+                index = idx
+                break
+    return(index)
+
+def split_path(path, separator, inside_special=False):
+    first_match = '"]' if inside_special else '["'
+    i = path.find(first_match)
+    if i != -1 and inside_special is False:
+        if(path[0:i] != ''):
+            return (split_path(path[0:i],
+                               separator=separator,
+                               inside_special=False) +
+                    split_path(path[i+len('["'):],
+                               separator=separator,
+                               inside_special=True))
+        else:
+            return (split_path(path[i+len('["'):],
+                               separator=separator,
+                               inside_special=True))
+    if i != -1 and inside_special is True:
+        if(path[i+len('["'):] != ''):
+            return ([path[:i], "special"],) + split_path(path[i+len('["'):],
+                                                         separator=separator,
+                                                         inside_special=False)
+        else:
+            return ([path[:i], "special"],)
+    else:
+        i = path.find(separator)
+        if i == -1:
+            return (path,)
+        else:
+            if(i != 0):
+                return (path[:i],) + split_path(path[i+1:], separator)
+            else:
+                return split_path(path[i+1:], separator)
+
+
+def get_dict_from_path(path, separator):
+    path = split_path(path, separator)
+
+    res = []
+    for x in path:
+        if isinstance(x, str) and x.find("[") == -1:
+            res.append(x)
+        elif not isinstance(x, list):
+            pos = x.find("[")
+            while pos != -1:
+                if pos == 0:
+                    i1 = x.find("]")
+                    x1 = int(x[0:i1].replace("[", "", 1).replace("]", "", 1))
+                    x = x[i1+1:]
+                    res.append(x1)
+                else:
+                    res.append(x[0:pos])
+                    x = x[pos:]
+                pos = x.find("[")
+        else:
+            res.append(x[0])
+    return(res)
+
+def traverse_and_remove_path(obj, path=None, match="First"):
+    if path is None:
+        path = []
+    if isinstance(obj, dict):
+        res = OrderedDict()
+        for k, v in obj.items():
+            cmatch = False
+            if(match and len(path) > 0 and path[0] == k):
+                cmatch = True
+            res.update({k: traverse_and_remove_path(v, path=path[1:], match=cmatch)})
+        if(len(path) == 1 and path[0] in res.keys() and match):
+            del res[path[0]]
+        return res
+    elif isinstance(obj, list):
+        res = []
+        for i, elem in enumerate(obj):
+            cmatch = False
+            if(match and len(path) >= 1 and isinstance(path[0], int) and path[0] < len(obj) and i == path[0]):
+                cmatch = True
+            res.append(traverse_and_remove_path(elem, path=path[1:], match=cmatch))
+        if(len(path) == 1 and isinstance(path[0], int) and path[0] < len(res) and match):
+            res.pop(path[0])
+        return res
+    else:
+        return obj  # no container, just values (str, int, float)
diff --git a/elpa/x-path-walker-20220714.1056/xpathwalker/yaml_Processor.py b/elpa/x-path-walker-20220714.1056/xpathwalker/yaml_Processor.py
new file mode 100644 (file)
index 0000000..fd28d37
--- /dev/null
@@ -0,0 +1,37 @@
+##########################################################################
+# YAML                                                                   #
+##########################################################################
+import yaml
+from xpathwalker.utils import list_compare_idx
+from xpathwalker.utils import traverse_and_remove_path, get_dict_from_path, get_class, paths
+from collections import OrderedDict
+import os
+
+def parse_yaml(file):
+    with open(file) as f:
+        yaml_data = yaml.load(f)
+        res = OrderedDict()
+        for x in paths(yaml_data, leaves=False):
+            res.update(x)
+        return(res)
+
+def get_yaml_paths(file, include_type=True):  # XXX: ordering is lost
+    yaml_paths = parse_yaml(file)
+    if(include_type is True):
+        return(["%s | %s" % (get_class(yaml_paths[x]['class']), x) for x in yaml_paths.keys()])
+    else:
+        return(yaml_paths.keys())
+
+def get_yaml_path_line_python(file, path, include_type=False):
+    if(not os.path.isfile(file)):
+        sys.exit(1)
+    path = path.split("| ")[1] if (include_type is True) else path
+    orig = ""
+    with open(file) as f:
+        orig = yaml.load(f)
+    path = get_dict_from_path(path)
+    res = traverse_and_remove_path(orig, path)
+    yaml_dump_options = {"indent": 4, "default_flow_style": False, "explicit_start": False}
+    orig = yaml.dump(orig, **yaml_dump_options).split("\n")
+    with_del = yaml.dump(dict(res), **yaml_dump_options).split("\n")
+    return(list_compare_idx(orig, with_del) + 1)