#! /usr/local/bin/apl --script
 ⍝ ********************************************************************
 ⍝   $Id: $
 ⍝ $desc: Routine to import arrays from text files $
 ⍝ ********************************************************************
⍝ Copyright (C) 2018 Bill Daly

⍝ 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/>.


)copy_once 5 DALY/utf8
)copy_once 5 DALY/utl
)copy_once 3 DALY/lex
)copy_once 3 DALY/date

∇ home←import∆homeDir
  ⍝ Function queries the unix environment for the user's home directory.
  home←2⊃,⎕env 'HOME'
∇

∇array←import∆file fname;txt;lines
  ⍝ Base function to read a text file and return an array based on
  ⍝ that file.
go1:
  ⎕es (utl∆numberp txt←utf8∆read fname)/'ERROR READING ',fname
guess:
  lines←+/txt=⎕tc[3]
  →(import∆delimThreshold>(+/txt=⎕av[10])÷lines)/guess2
  array←import∆file∆tab txt
  →go2
guess2:
  →(import∆delimThreshold>(+/txt=',')÷lines)/ohNo
  array←import∆file∆comma txt
  →go2
go2:
  array←utl∆convertStringToNumber ¨ ⊃array
  →0
ohNo:
  ⎕es fname,' IS NOT A DELIMITED FILE'
∇

∇array← locale import∆file∆withDates fname;txt;lines
  ⍝ Function returns an array from a delimited file.  Each cell is
  ⍝ tested first to see if it is date and second if it a number. This
  ⍝ may be too slow for thee. Use import∆file and hope the dates don't
  ⍝ cause errors.
go1:
  ⎕es (utl∆numberp txt←utf8∆read fname)/'ERROR READING ',fname
guess:
  lines←+/txt=⎕tc[3]
  →(import∆delimThreshold>(+/txt=⎕av[10])÷lines)/guess2
  array←import∆file∆tab txt
  →go2
guess2:
  →(import∆delimThreshold>(+/txt=',')÷lines)/ohNo
  array←import∆file∆comma txt
  →go2
go2:
  array←locale import∆convertingDates ⊃array
  →0
ohNo:
  ⎕es fname,' IS NOT A DELIMITED FILE'
∇

∇array←import∆file∆tab txt
 ⍝ Function converts the text in filea fname to an vector of vectors
 ⍝ using delimiters line feed and tab (⎕av[11 10])
 →(0=+/⎕av[11]=txt←utl∆rm_trailing_lf (txt≠⎕av[14])/txt)/no_lf
 array←⎕av[10] utl∆split_with_quotes ¨ ⎕av[11] utl∆split txt
 →0
 no_lf:
 array←,⊂⎕av[10] utl∆split_with_quotes txt
 →0
∇

∇array←import∆file∆comma txt
 ⍝ Function converts the text in filea fname to an vector of vectors
 ⍝ using delimiters line feed and comma
 →(0=+/⎕av[11]=txt←utl∆rm_trailing_lf (txt≠⎕av[14])/txt)/no_lf
  array←',' utl∆split_with_quotes ¨ ⎕av[11] utl∆split txt
  →0
no_lf:
  array←,⎕av[10] utl∆split_with_quotes txt
∇

∇array←locale import∆convertingDates txt;shape;dt;nt;ix
  ⍝ Function examines an array generated by import∆file∆withDates
  ⍝ converting any dates to a three element vector of year, month and
  ⍝ day and converting any numbers to numbers. Locale is a lexicon
  ⍝ describing the local date conventions (see workspace date).
  shape←⍴txt
  txt←,txt
  dt←(⊂locale) date∆parse ¨ txt
  txt[ix]←dt[ix←(∊3=⍴¨dt)/⍳⍴txt]
  ix←(utl∆numberis ¨ txt)/⍳⍴txt
  txt[ix]←⍎¨txt[ix]
  array←shape⍴txt
∇

∇new←import∆table array;nos;cols
  ⍝ function finds the table in an array generated by import∆file.  It
  ⍝ removes blank columns and rows at the begining and end of the file
  ⍝ which lack data.
  nos←utl∆numberp ¨ array
  cols←(0<+⌿nos)/⍳1↓⍴nos
  nos←∨/nos
  nos←~(∧\~nos)∨⌽∧\⌽~nos
  new←nos⌿array
  new←cols import∆table∆cols new
∇

∇new←cols import∆table∆cols array;c;b
  ⍝ Function inserts zeros into numeric columns of array
  ⍎(0=⍴cols)/'new←array ◊ →0'
  new←(1↓cols) import∆table∆cols array
  c←''⍴cols
  b←utl∆numberp ¨ new[;c]
  new[;c]←b\b/new[;c]
∇

∇fname import∆table∆save array;shape;ix;fh
  ⍝ Function writes array to file fname as a tab delimited array.
  →(scalar,vector,matrix)[1+⍴shape←⍴array]
scalar:
  array←(⍕array),⎕av[11]
  →write
vector:
  array[ix]←⍕¨array[ix←(utl∆numberp array)/⍳⍴array]
  array←(⎕av[10] utl∆join array),⎕av[11]
  →write
matrix:
  array←,array
  array[ix]←⍕¨array[ix←(utl∆numberp array)/⍳⍴array]
  array←⎕av[10] utl∆join ¨ ⊂[2]shape⍴array
  array←⎕av[11] utl∆join array
write:
  fh←'w' FIO∆fopen fname
  (⎕ucs array) FIO∆fwrite fh
  FIO∆fclose fh
∇
  
∇Z←import⍙metadata
  Z←0 2⍴⍬
  Z←Z⍪'Author'          'Bill Daly'
  Z←Z⍪'BugEmail'        'bugs@dalywebandedit.com'
  Z←Z⍪'Documentation'   'doc/apl-library.info'
  Z←Z⍪'Download'        'https://sourceforge.net/p/apl-library/code/ci/master/tree/import.apl'
  Z←Z⍪'License'         'GPL v3.0'
  Z←Z⍪'Portability'     'L2'
  Z←Z⍪'Provides'        ''
  Z←Z⍪'Requires'        'lex, util, FILE_IO'
  Z←Z⍪'Version'         '0 1 6'
  Z←Z⍪'Last update'     '2022-02-15'
∇


⍝ Threshold for ratio of a delimiter to text
∇t←import∆delimThreshold
  t←1		⍝ per line of text
∇

