Live data from Hacker News

Show HN: I wrote a program to convert lines of text into trees

github.com

21–30 of 58 posts

Re: Show HN: I wrote a program to convert lines of text into trees

#21

I've been thinking about making something like this for a while, this is great! I always thought it was weird that "do one thing and one thing well" stopped short of dealing with tree representations on the commandline.

What do you mean? The only reason this didn't exist is nobody did it yet. It doesn't contradict "do one thing and do it well".

For me, the problem isn’t that it doesn’t do one thing well, which is clearly does, it’s that there are no other tools to process trees.

So it fits well with the UNIX ethos of a small tool doing one thing well, but not so much the concept of pipelines, which is closely related.

Obviously not this tool’s fault.

Re: Show HN: I wrote a program to convert lines of text into trees

#23
post #16

Whoa, he wrote a parser. This only happens every other decade or so.

> Be kind. Don't be snarky. Have curious conversation; don't cross-examine. Please don't fulminate. Please don't sneer, including at the rest of the community.

https://news.ycombinator.com/newsguidelines.html

Re: Show HN: I wrote a program to convert lines of text into trees

#24

  $ find /etc/network | ./frangi.tl
  etc:
      network:
          if-post-down.d:
              wireless-tools wpasupplicant avahi-daemon 
          if-down.d:
              resolvconf wpasupplicant avahi-autoipd 
          interfaces.d interfaces if-pre-up.d:
              wireless-tools wpasupplicant ethtool 
          if-up.d:
              ntpdate wpasupplicant 000resolvconf openssh-server ethtool avahi-autoipd slrn avahi-daemon 

  $ find /etc/network | ./frangi-cheat.tl 
  /etc/network
              /if-post-down.d
                             /wireless-tools
                             /wpasupplicant
                             /avahi-daemon
              /if-down.d
                        /resolvconf
                        /wpasupplicant
                        /avahi-autoipd
              /interfaces.d
              /interfaces
              /if-pre-up.d
                          /wireless-tools
                          /wpasupplicant
                          /ethtool
              /if-up.d
                      /ntpdate
                      /wpasupplicant
                      /000resolvconf
                      /openssh-server
                      /ethtool
                      /avahi-autoipd
                      /slrn
                      /avahi-daemon

  $ cat frangi-cheat.tl
  #!/usr/bin/env txr
  (let (old-path)
    (whilet ((line (get-line)))
      (whenlet ((path (tok #/[^\/]*/ line))
                (canon `@{path "/"}`)
                (pos (mismatch path old-path)))
        (let ((cpos (max 0 (+ pos -1 [sum [path 0..pos] len]))))
          (put-line `@{"" cpos}@{canon [cpos..:]}`))
        (set old-path path))))


  $ cat frangi.tl
  #!/usr/bin/env txr

  (defstruct (node name) list-builder
    name

    (:method equal (me) me.name)

    (:method ensure-child (me child-name)
      (let ((children me.(get)))
        (or (find child-name me.(get))
            (let ((new-child (new (node child-name))))
              me.(add new-child)
              new-child))))

    (:method print (me stream : pretty-p)
      (let* ((old-im (set-indent-mode stream indent-code))
             (old-id (get-indent stream))
             (children me.(get))
             (is-bottom (none children .(get))))
        (unwind-protect
          (cond
            (children
              (put-line `@{me.name}:` stream)
              (set-indent stream (+ old-id 4))
              [mapdo (op print @1 stream) children]
              (when is-bottom
                (put-char #\newline stream)))
            (t (put-string `@{me.name} `) stream))
          (set-indent-mode stream old-im)
          (set-indent stream old-id)))))

  (let ((supernode (new (node :root))))
    (whilet ((line (get-line)))
      (let ((path (tok #/[^\/]+/ line))
            (node supernode))
        (each ((comp path))
          (set node node.(ensure-child comp)))))
    (each ((top-child supernode.(get)))
      (pprinl top-child)))

Re: Show HN: I wrote a program to convert lines of text into trees

#27

$ find /etc/network | ./frangi.tl etc: network: if-post-down.d: wireless-tools wpasupplicant avahi-daemon if-down.d: resolvconf wpasupplicant avahi-autoipd interfaces.d interfaces if-pre-up.d: wireless-tools wpasupplicant ethtool if-up.d: ntpdate wpasupplicant 000resolvconf openssh-server ethtool avahi-autoipd slrn avahi-daemon $ find /etc/network | ./frangi-cheat.tl /etc/network /if-post-down.d /wireless-tools /wpas…

C version. Maybe this logic should be built into GNU find as an option!

  $ find /etc/network | ./frangi-cheat 
  /etc/network
              /if-post-down.d
                             /wireless-tools
                             /wpasupplicant
                             /avahi-daemon
              /if-down.d
                        /resolvconf
                        /wpasupplicant
                        /avahi-autoipd
              /interfaces.d
              /interfaces
              /if-pre-up.d
                          /wireless-tools
                          /wpasupplicant
                          /ethtool
              /if-up.d
                      /ntpdate
                      /wpasupplicant
                      /000resolvconf
                      /openssh-server
                      /ethtool
                      /avahi-autoipd
                      /slrn
                      /avahi-daemon

  $ cat frangi-cheat.c
  #include 
  #include 
  #include 

  int main(void)
  {
    char old_line[FILENAME_MAX] = "", line[FILENAME_MAX];

    while (fgets(line, sizeof line, stdin)) {
      char *p = line, *o = old_line, *nl = strchr(line, '\n');

      if (nl)
        *nl = 0;

      while (*p && *o) {
        char *op = p;

        if (*o == '/' && *p == '/')
          o++, p++;

        size_t lp = strcspn(p, "/");
        size_t lo = strcspn(o, "/");

        if (lp == lo && !strncmp(p, o, lp)) {
          p += lp;
          o += lp;
          printf("%*s", (int) (p - op), "");
          continue;
        }

        p = op;
        break;
      }

      puts(p);
      strcpy(old_line, line);
    }

    return feof(stdin) ? EXIT_SUCCESS : EXIT_FAILURE;
  }
Note: yes, we could swap pointers between two buffers instead of strcpy.

Re: Show HN: I wrote a program to convert lines of text into trees

#28
post #12

Awesome. You really nailed it. In my experience the output for spreadsheets turns out to be key so good job highlighting that ( https://github.com/birchb1024/frangipanni#output-for-spreads... ). One suggestion: it may help to generalize the newline as the node separator. You may already be doing this (my go is rusty) but instead of https://github.com/birchb1024/frangipanni/blob/7543b4ee15ae7... be able to override th…

really cool! But I think you should have called it "birch"! :)

Any way you could add build instructions to the README?

Post reply on HN