(let ((food-path "~/SR-Leg_ASC/")
     (output-path "~/SR-Leg_ASC/out")
     (out (get-buffer-create "*out*")))
 (when (and (file-exists-p output-path)
            (directory-files output-path))
   (condition-case nil
       (delete-directory output-path t)
     (error "unable to delete the output directory %s" output-path)))
 (condition-case nil
     (mkdir output-path)
   (error "unable to create output directory %s" output-path))
 (switch-to-buffer out)
 (setq buffer-read-only nil)
 (erase-buffer)
 (goto-char (point-min))
 (let ((weight (concat food-path "WEIGHT.txt"))
       (desc (concat food-path "FOOD_DES.txt"))
       (nutr (concat food-path "NUT_DATA.txt"))
       (ndef (concat food-path "NUTR_DEF.txt")))
   (dolist (f (list weight desc nutr ndef))
     (when (not (file-exists-p f))
       (error "Could not find file %s" f)))
   (find-file desc)
   (goto-char (point-min))
   (let (name file n count)
     (setq count 0)
     ;; Loop for every type of food we find in FOOD_DES.txt:
     ;; add a section to our output file.
     (while (and (re-search-forward "^~" nil t) (> count -1))
       (when (equal 0 (mod count 100)) (message (format "%s" count)))
       (let ((items (split-string (thing-at-point 'line) "\\^")))
         (setq n (replace-regexp-in-string
                  "~" "" (elt items 0)))
         (setq name (replace-regexp-in-string
                     "~" "" (elt items 2)))
         (setq name (replace-regexp-in-string
                     "(Includes.*)" "" name))
         ;; filename has only numbers, letters,
         ;; and replace spaces with dashes
         (setq file
               (with-temp-buffer
                 (insert name)
                 (goto-char (point-min))
                 (while (< (point) (point-max))
                   (cond
                    ((= (char-after) 32)
                     (delete-char 1)
                     (insert "-"))
                    ((or
                      (= (char-after) 32)
                      (and (>= (char-after) 65)
                           (<= (char-after) 90))
                      (and (>= (char-after) 97)
                           (<= (char-after) 122))
                      (and (>= (char-after) 48)
                           (<= (char-after) 57)))
                     (forward-char))
                    (t (delete-char 1))))
                 (concat
                  (buffer-substring (point-min) (point-max))
                  (format "-%s.txt" n)))))
       (setq count (+ count 1))
       (save-excursion
         (switch-to-buffer out)
         (insert (format "* %s (%s)" name n)) (newline) (newline)
         (insert (format "%s" file)) (newline) (newline))
       ;; loop for every weight equivalent we can find
       ;; in WEIGHT.txt for this food
       (save-excursion
         (find-file weight)
         (goto-char (point-min))
         (let (all count measure grams items)
           (while (search-forward (concat "~" n "~") nil t)
             (let ((items (split-string (thing-at-point 'line) "\\^")))
               (setq count (elt items 2))
               (let ((nth (elt items 3)))
                 (when nth
                   (setq measure (replace-regexp-in-string
                                  "~" "" nth))))
               (setq grams (elt items 4))
               (when (and count measure grams)
                 (save-excursion
                   (switch-to-buffer out)
                   (insert count) (insert " ")
                   (insert measure) (insert " = ")
                   (insert grams) (insert "g")
                   (dotimes (i 1) (newline))))))
           (save-excursion
             (switch-to-buffer out)
             (dotimes (i 1) (newline)))))
       ;; Now the weights are done for this food.
       ;; Write the nutritional information for it
       ;; into the alphabet directory.
       (let  ((char1d (format "%s/%s"
                              output-path
                              (char-to-string (elt name 0)))))
         (condition-case nil
             (mkdir char1d)
           (error "could not create directory %s" char1d))
         (save-excursion
           (get-buffer-create "nutrition")
           (switch-to-buffer "nutrition")
           (setq buffer-read-only nil)
           (erase-buffer))
         (save-excursion
           (find-file nutr)
           (goto-char (point-min))
           (let (nutr-id nutr-units nutr-name nutr-amount)
             (while (re-search-forward (concat "^" "~" n "~") nil t)
               (let ((items (split-string (thing-at-point 'line) "\\^")))
                 (setq nutr-id (elt items 1))
                 (setq nutr-id (replace-regexp-in-string "~" "" nutr-id))
                 (setq nutr-amount (elt items 2))
                 (save-excursion
                   (find-file ndef)
                   (goto-char (point-min))
                   (search-forward (concat "~" nutr-id "~"))
                   (setq nutr-name
                         (elt (split-string (thing-at-point 'line) "\\^") 3))
                   (setq nutr-name  (replace-regexp-in-string "~" "" nutr-name))
                   (setq nutr-units
                         (elt (split-string (thing-at-point 'line) "\\^") 1))
                   (setq nutr-units (replace-regexp-in-string "~" "" nutr-units)))
                 ;; write nutrient line to file, except for the ones that start
                 ;; with a number. i don't know what those mean.
                 (unless (and (>= (elt nutr-name 0) 48) (<= (elt nutr-name 0) 57))
                   (save-excursion
                     (switch-to-buffer "nutrition")
                     (goto-char (point-max))
                     (newline)
                     (insert (format "%s %s %s"
                                     nutr-name
                                     (string-to-number nutr-amount)
                                     nutr-units))))))
             (let ((food-file-name file))
               (save-excursion
                 (switch-to-buffer "nutrition")
                 (sort-lines nil (point-min) (point-max))
                 (goto-char (point-min))
                 (insert (format "%s (%s)" name n)) (newline)
                 (insert "100 g") (newline)
                 (write-region (point-min) (point-max)
                               (format "%s/%s"
                                       char1d
                                       food-file-name)))))))
       )))
 (switch-to-buffer out)
 (goto-char (point-max))
 (newline)
 (goto-char (point-min))
 (org-mode)
 (goto-char (point-min))
 (mark-whole-buffer)
 (org-sort-entries nil ?a)
 (setq buffer-read-only t)
 (condition-case nil
     (write-region (point-min) (point-max)
                   (format "%s/00-food-weights.org" output-path))
   (error "could not save file 00-food-weights.org")))