Check-in by ben on 2025-04-11 21:03:07

Initial import

 INSERTED    DELETED
       49          0 data/density.txt
      119          0 data/elements.csv
       11          0 data/families.csv
      143          0 data/periodic.txt
        5          0 data/shells.csv
        9          0 data/sources.csv
      923          0 periodic.awk
     1259          0 TOTAL over 7 changed files

ADDED   data/density.txt
Index: data/density.txt
==================================================================
--- /dev/null
+++ data/density.txt
@@ -0,0 +1,49 @@
+This table gives the density of selected elements in their pure state.
+Unless otherwise stated, all are under standard conditions.
+
+                  Density / g cm^-3
+Lithium            0.53
+Carbon (graphite)  2.27
+Carbon (diamond)   3.52
+Sodium             0.97
+Magnesium          1.74
+Aluminium          2.70
+Silicon            2.33
+Potassium          0.86
+Calcium            1.55
+Titanium           4.51
+Chromium           7.15
+Manganese          7.21
+Iron               7.87
+Cobalt             8.90
+Nickel             8.91
+Copper             8.94
+Zinc               7.14
+Gallium            5.91
+Gallium (liquid)   6.10
+Rubidium           1.53
+Niobium            8.57
+Molybdenum        10.28
+Palladium         12.02
+Silver            10.49
+Cadmium            8.65
+Indium             7.31
+Tin (white, beta)  7.27
+Antimony           6.70
+Iodine             4.93
+Barium             3.51
+Lanthanum          6.16
+Tantalum          16.69
+Tungsten          19.25
+Osmium            22.59
+Iridium           22.56
+Platinum          21.45
+Gold              19.3
+Mercury           13.53
+Lead              11.34
+Bismuth            9.79
+Thorium           11.7
+Uranium           19.1
+
+From: <gopher://gopher.srcf.net/0/users/amr66/b_scientific/
+density_elements.txt>

ADDED   data/elements.csv
Index: data/elements.csv
==================================================================
--- /dev/null
+++ data/elements.csv
@@ -0,0 +1,119 @@
+Atomic Number,Symbol,Name,Atomic Mass,Electron Configuration,Electronegativity,Atomic Radius,Ionization Energy,Electron Affinity,Oxidation States,Standard State,Melting Point,Boiling Point,Density,Family,Year Discovered,Number of Neutrons,Number of Protons,Number of Electrons,Number of Valence,Valency,Group,Period,Shell,Specific Heat,Radioactive,Occurrence,Source,Table Row,Table Column
+1,H,Hydrogen,1.0080 u,1s1,2.2,120 pm,13.598 eV,0.754 eV,"+1, -1",Gas,13.81 K,20.28 K,0.00008988 g/cm3,Nonmetal,1766,0,1,1,1,1,1,1,s-shell,14.304 J/g K,0,Natural,bigbang,1,1
+2,He,Helium,4.00260 u,1s2,,140 pm,24.587 eV,,0,Gas,0.95 K,4.22 K,0.0001785 g/cm3,Noble gas,1868,2,2,2,2,0,18,1,s-shell,5.193 J/g K,0,Natural,bigbang,1,18
+3,Li,Lithium,7.0 u,[He]2s1,0.98,182 pm,5.392 eV,0.618 eV,1,Solid,453.65 K,1615 K,0.534 g/cm3,Alkali metal,1817,4,3,3,1,1,1,2,s-shell,3.582 J/g K,0,Natural,dyinglow,2,1
+4,Be,Beryllium,9.012183 u,[He]2s2,1.57,153 pm,9.323 eV,,2,Solid,1560 K,2744 K,1.85 g/cm3,Alkaline earth metal,1798,5,4,4,2,2,2,2,s-shell,1.825 J/g K,0,Natural,rays,2,2
+5,B,Boron,10.81 u,[He]2s2 2p1,2.04,192 pm,8.298 eV,0.277 eV,3,Solid,2348 K,4273 K,2.37 g/cm3,Metalloid,1808,6,5,5,3,3,13,2,p-shell,1.026 J/g K,0,Natural,rays,2,13
+6,C,Carbon,12.011 u,[He]2s2 2p2,2.55,170 pm,11.260 eV,1.263 eV,"+4, +2, -4",Solid,3823 K,4098 K,2.2670 g/cm3,Nonmetal,Ancient,6,6,6,4,4,14,2,p-shell,0.709 J/g K,0,Natural,dyinglow,2,14
+7,N,Nitrogen,14.007 u,[He] 2s2 2p3,3.04,155 pm,14.534 eV,,"+5, +4, +3, +2, +1, -1, -2, -3",Gas,63.15 K,77.36 K,0.0012506 g/cm3,Nonmetal,1772,7,7,7,5,3,15,2,p-shell,1.040 J/g K,0,Natural,dyinglow,2,15
+8,O,Oxygen,15.999 u,[He]2s2 2p4,3.44,152 pm,13.618 eV,1.461 eV,-2,Gas,54.36 K,90.2 K,0.001429 g/cm3,Nonmetal,1774,8,8,8,6,2,16,2,p-shell,0.918 J/g K,0,Natural,dyinghigh,2,16
+9,F,Fluorine,18.99840316 u,[He]2s2 2p5,3.98,135 pm,17.423 eV,3.339 eV,-1,Gas,53.53 K,85.03 K,0.001696 g/cm3,Halogen,1670,10,9,9,7,1,17,2,p-shell,0.824 J/g K,0,Natural,dyinghigh,2,17
+10,Ne,Neon,20.180 u,[He]2s2 2p6,,154 pm,21.565 eV,,0,Gas,24.56 K,27.07 K,0.0008999 g/cm3,Noble gas,1898,10,10,10,8,0,18,2,p-shell,1.030 J/g K,0,Natural,dyinghigh,2,18
+11,Na,Sodium,22.9897693 u,[Ne]3s1,0.93,227 pm,5.139 eV,0.548 eV,1,Solid,370.95 K,1156 K,0.97 g/cm3,Alkali metal,1807,12,11,11,1,1,1,3,s-shell,1.228 J/g K,0,Natural,dyinghigh,3,1
+12,Mg,Magnesium,24.305 u,[Ne]3s2,1.31,173 pm,7.646 eV,,2,Solid,923 K,1363 K,1.74 g/cm3,Alkaline earth metal,1808,12,12,12,2,2,2,3,s-shell,1.023 J/g K,0,Natural,dyinghigh,3,2
+13,Al,Aluminum,26.981538 u,[Ne]3s2 3p1,1.61,184 pm,5.986 eV,0.441 eV,3,Solid,933.437 K,2792 K,2.70 g/cm3,Post-transition metal,Ancient,14,13,13,3,3,13,3,p-shell,0.897 J/g K,0,Natural,dyinghigh,3,13
+14,Si,Silicon,28.085 u,[Ne]3s2 3p2,1.9,210 pm,8.152 eV,1.385 eV,"+4, +2, -4",Solid,1687 K,3538 K,2.3296 g/cm3,Metalloid,1854,14,14,14,4,4,14,3,p-shell,0.705 J/g K,0,Natural,dyinghigh,3,14
+15,P,Phosphorus,30.97376200 u,[Ne]3s2 3p3,2.19,180 pm,10.487 eV,0.746 eV,"+5, +3, -3",Solid,317.3 K,553.65 K,1.82 g/cm3,Nonmetal,1669,16,15,15,5,3,15,3,p-shell,0.769 J/g K,0,Natural,dyinghigh,3,15
+16,S,Sulfur,32.07 u,[Ne]3s2 3p4,2.58,180 pm,10.360 eV,2.077 eV,"+6, +4, -2",Solid,388.36 K,717.75 K,2.067 g/cm3,Nonmetal,Ancient,16,16,16,6,2,16,3,p-shell,0.710 J/g K,0,Natural,dyinghigh supernova,3,16
+17,Cl,Chlorine,35.45 u,[Ne]3s2 3p5,3.16,175 pm,12.968 eV,3.617 eV,"+7, +5, +1, -1",Gas,171.65 K,239.11 K,0.003214 g/cm3,Halogen,1774,18,17,17,7,1,17,3,p-shell,0.479 J/g K,0,Natural,dyinghigh,3,17
+18,Ar,Argon,39.9 u,[Ne]3s2 3p6,,188 pm,15.760 eV,,0,Gas,83.8 K,87.3 K,0.0017837 g/cm3,Noble gas,1894,22,18,18,8,0,18,3,p-shell,0.520 J/g K,0,Natural,dyinghigh supernova,3,18
+19,K,Potassium,39.0983 u,[Ar]4s1,0.82,275 pm,4.341 eV,0.501 eV,1,Solid,336.53 K,1032 K,0.89 g/cm3,Alkali metal,1807,20,19,19,1,1,1,4,s-shell,0.757 J/g K,0,Natural,dyinghigh,4,1
+20,Ca,Calcium,40.08 u,[Ar]4s2,1,231 pm,6.113 eV,,2,Solid,1115 K,1757 K,1.54 g/cm3,Alkaline earth metal,Ancient,20,20,20,2,2,2,4,s-shell,0.647 J/g K,0,Natural,dyinghigh supernova,4,2
+21,Sc,Scandium,44.95591 u,[Ar]4s2 3d1,1.36,211 pm,6.561 eV,0.188 eV,3,Solid,1814 K,3109 K,2.99 g/cm3,Transition metal,1879,24,21,21,,,3,4,d-shell,0.568 J/g K,0,Natural,dyinghigh,4,3
+22,Ti,Titanium,47.867 u,[Ar]4s2 3d2,1.54,187 pm,6.828 eV,0.079 eV,"+4, +3, +2",Solid,1941 K,3560 K,4.5 g/cm3,Transition metal,1791,26,22,22,,,4,4,d-shell,0.523 J/g K,0,Natural,supernova,4,4
+23,V,Vanadium,50.9415 u,[Ar]4s2 3d3,1.63,179 pm,6.746 eV,0.525 eV,"+5, +4, +3, +2",Solid,2183 K,3680 K,6.0 g/cm3,Transition metal,1801,28 23,23,,,,5,4,d-shell,0.489 J/g K,0,Natural,supernova,4,5
+24,Cr,Chromium,51.996 u,[Ar]3d5 4s1,1.66,189 pm,6.767 eV,0.666 eV,"+6, +3, +2",Solid,2180 K,2944 K,7.15 g/cm3,Transition metal,1797,28,24,24,,,6,4,d-shell,0.449 J/g K,0,Natural,supernova,4,6
+25,Mn,Manganese,54.93804 u,[Ar]4s2 3d5,1.55,197 pm,7.434 eV,,"+7, +4, +3, +2",Solid,1519 K,2334 K,7.3 g/cm3,Transition metal,1774,30,25,25,,,7,4,d-shell,0.479 J/g K,0,Natural,supernova,4,7
+26,Fe,Iron,55.84 u,[Ar]4s2 3d6,1.83,194 pm,7.902 eV,0.163 eV,"+3, +2",Solid,1811 K,3134 K,7.874 g/cm3,Transition metal,Ancient,30,26,26,,,8,4,d-shell,0.449 J/g K,0,Natural,supernova,4,8
+27,Co,Cobalt,58.93319 u,[Ar]4s2 3d7,1.88,192 pm,7.881 eV,0.661 eV,"+3, +2",Solid,1768 K,3200 K,8.86 g/cm3,Transition metal,1735,32,27,27,,,9,4,d-shell,0.421 J/g K,0,Natural,supernova,4,9
+28,Ni,Nickel,58.693 u,[Ar]4s2 3d8,1.91,163 pm,7.640 eV,1.156 eV,"+3, +2",Solid,1728 K,3186 K,8.912 g/cm3,Transition metal,1751,31,28,28,,,10,4,d-shell,0.444 J/g K,0,Natural,supernova,4,10
+29,Cu,Copper,63.55 u,[Ar]4s1 3d10,1.9,140 pm,7.726 eV,1.228 eV,"+2, +1",Solid,1357.77 K,2835 K,8.933 g/cm3,Transition metal,Ancient,35,29,29,,,11,4,d-shell,0.385 J/g K,0,Natural,dyinghigh supernova,4,11
+30,Zn,Zinc,65.4 u,[Ar]4s2 3d10,1.65,139 pm,9.394 eV,,2,Solid,692.68 K,1180 K,7.134 g/cm3,Transition metal,1746,35,30,30,,,12,4,d-shell,0.388 J/g K,0,Natural,dyinghigh supernova,4,12
+31,Ga,Gallium,69.723 u,[Ar]4s2 3d10 4p1,1.81,187 pm,5.999 eV,0.3 eV,3,Solid,302.91 K,2477 K,5.91 g/cm3,Post-transition metal,1875,39,31,31,3,3,13,4,p-shell,0.371 J/g K,0,Natural,dyinghigh,4,13
+32,Ge,Germanium,72.63 u,[Ar]4s2 3d10 4p2,2.01,211 pm,7.900 eV,1.35 eV,"+4, +2",Solid,1211.4 K,3106 K,5.323 g/cm3,Metalloid,1886,41,32,32,4,4,14,4,p-shell,0.320 J/g K,0,Natural,dyinghigh,4,14
+33,As,Arsenic,74.92159 u,[Ar]4s2 3d10 4p3,2.18,185 pm,9.815 eV,0.81 eV,"+5, +3, -3",Solid,1090 K,887 K,5.776 g/cm3,Metalloid,Ancient,42,33,33,5,3,15,4,p-shell,0.329 J/g K,0,Natural,dyinghigh,4,15
+34,Se,Selenium,78.97 u,[Ar]4s2 3d10 4p4,2.55,190 pm,9.752 eV,2.021 eV,"+6, +4, -2",Solid,493.65 K,958 K,4.809 g/cm3,Nonmetal,1817,45,34,34,6,2,16,4,p-shell,0.321 J/g K,0,Natural,dyinghigh,4,16
+35,Br,Bromine,79.90 u,[Ar]4s2 3d10 4p5,2.96,183 pm,11.814 eV,3.365 eV,"+5, +1, -1",Liquid,265.95 K,331.95 K,3.11 g/cm3,Halogen,1826,45,35,35,7,1,17,4,p-shell,0.474 J/g K,0,Natural,dyinghigh,4,17
+36,Kr,Krypton,83.80 u,[Ar]4s2 3d10 4p6,3,202 pm,14.000 eV,,0,Gas,115.79 K,119.93 K,0.003733 g/cm3,Noble gas,1898,48,36,36,8,0,18,4,p-shell,0.248 J/g K,0,Natural,dyinghigh,4,18
+37,Rb,Rubidium,85.468 u,[Kr]5s1,0.82,303 pm,4.177 eV,0.468 eV,1,Solid,312.46 K,961 K,1.53 g/cm3,Alkali metal,1861,48,37,37,1,1,1,5,s-shell,0.363 J/g K,0,Natural,dyinghigh,5,1
+38,Sr,Strontium,87.62 u,[Kr]5s2,0.95,249 pm,5.695 eV,,2,Solid,1050 K,1655 K,2.64 g/cm3,Alkaline earth metal,1790,50,38,38,2,2,2,5,s-shell,0.301 J/g K,0,Natural,dyinglow,5,2
+39,Y,Yttrium,88.90584 u,[Kr]5s2 4d1,1.22,219 pm,6.217 eV,0.307 eV,3,Solid,1795 K,3618 K,4.47 g/cm3,Transition metal,1794,50,39,39,,,3,5,d-shell,0.298 J/g K,0,Natural,dyinglow,5,3
+40,Zr,Zirconium,91.22 u,[Kr]5s2 4d2,1.33,186 pm,6.634 eV,0.426 eV,4,Solid,2128 K,4682 K,6.52 g/cm3,Transition metal,1789,51,40,40,,,4,5,d-shell,0.278 J/g K,0,Natural,dyinglow,5,4
+41,Nb,Niobium,92.90637 u,[Kr]5s1 4d4,1.6,207 pm,6.759 eV,0.893 eV,"+5, +3",Solid,2750 K,5017 K,8.57 g/cm3,Transition metal,1801,52,41,41,,,5,5,d-shell,0.265 J/g K,0,Natural,dyinglow,5,5
+42,Mo,Molybdenum,95.95 u,[Kr]5s1 4d5,2.16,209 pm,7.092 eV,0.746 eV,6,Solid,2896 K,4912 K,10.2 g/cm3,Transition metal,1778,54,42,42,,,6,5,d-shell,0.251 J/g K,0,Natural,dyinglow neutron,5,6
+43,Tc,Technetium,96.90636 u,[Kr]5s2 4d5,1.9,209 pm,7.28 eV,0.55 eV,"+7, +6, +4",Solid,2430 K,4538 K,11 g/cm3,Transition metal,1937,55,43,43,,,7,5,d-shell,,1,Rare,decay,5,7
+44,Ru,Ruthenium,101.1 u,[Kr]5s1 4d7,2.2,207 pm,7.361 eV,1.05 eV,3,Solid,2607 K,4423 K,12.1 g/cm3,Transition metal,1827,57,44,44,,,8,5,d-shell,0.238 J/g K,0,Natural,neutron,5,8
+45,Rh,Rhodium,102.9055 u,[Kr]5s1 4d8,2.28,195 pm,7.459 eV,1.137 eV,3,Solid,2237 K,3968 K,12.4 g/cm3,Transition metal,1803,58,45,45,,,9,5,d-shell,0.243 J/g K,0,Natural,neutron,5,9
+46,Pd,Palladium,106.42 u,[Kr]4d10,2.2,202 pm,8.337 eV,0.557 eV,"+3, +2",Solid,1828.05 K,3236 K,12.0 g/cm3,Transition metal,1803,60,46,46,,,10,5,d-shell,0.244 J/g K,0,Natural,dyinglow neutron,5,10
+47,Ag,Silver,107.868 u,[Kr]5s1 4d10,1.93,172 pm,7.576 eV,1.302 eV,1,Solid,1234.93 K,2435 K,10.501 g/cm3,Transition metal,Ancient,61,47,47,,,11,5,d-shell,0.235 J/g K,0,Natural,neutron,5,11
+48,Cd,Cadmium,112.41 u,[Kr]5s2 4d10,1.69,158 pm,8.994 eV,,2,Solid,594.22 K,1040 K,8.69 g/cm3,Transition metal,1817,64,48,48,,,12,5,d-shell,0.232 J/g K,0,Natural,dyinglow neutron,5,12
+49,In,Indium,114.818 u,[Kr]5s2 4d10 5p1,1.78,193 pm,5.786 eV,0.3 eV,3,Solid,429.75 K,2345 K,7.31 g/cm3,Post-transition metal,1863,66,49,49,3,3,13,5,p-shell,0.233 J/g K,0,Natural,neutron,5,13
+50,Sn,Tin,118.71 u,[Kr]5s2 4d10 5p2,1.96,217 pm,7.344 eV,1.2 eV,"+4, +2",Solid,505.08 K,2875 K,7.287 g/cm3,Post-transition metal,Ancient,69,50,50,4,4,14,5,p-shell,0.228 J/g K,0,Natural,dyinglow neutron,5,14
+51,Sb,Antimony,121.760 u,[Kr]5s2 4d10 5p3,2.05,206 pm,8.64 eV,1.07 eV,"+5, +3, -3",Solid,903.78 K,1860 K,6.685 g/cm3,Metalloid,Ancient,71,51,51,5,3,15,5,p-shell,0.207 J/g K,0,Natural,neutron,5,15
+52,Te,Tellurium,127.6 u,[Kr]5s2 4d10 5p4,2.1,206 pm,9.010 eV,1.971 eV,"+6, +4, -2",Solid,722.66 K,1261 K,6.232 g/cm3,Metalloid,1782,76,52,52,6,2,16,5,p-shell,0.202 J/g K,0,Natural,dyinglow neutron,5,16
+53,I,Iodine,126.9045 u,[Kr]5s2 4d10 5p5,2.66,198 pm,10.451 eV,3.059 eV,"+7, +5, +1, -1",Solid,386.85 K,457.55 K,4.93 g/cm3,Halogen,1811,74,53,53,7,1,17,5,p-shell,0.214 J/g K,0,Natural,neutron,5,17
+54,Xe,Xenon,131.29 u,[Kr]5s2 4d10 5p6,2.6,216 pm,12.130 eV,,0,Gas,161.36 K,165.03 K,0.005887 g/cm3,Noble gas,1898,77,54,54,8,0,18,5,p-shell,0.158 J/g K,0,Natural,neutron,5,18
+55,Cs,Cesium,132.9054520 u,[Xe]6s1,0.79,343 pm,3.894 eV,0.472 eV,1,Solid,301.59 K,944 K,1.93 g/cm3,Alkali metal,1860,78,55,55,1,1,1,6,s-shell,0.242 J/g K,0,Natural,neutron,6,1
+56,Ba,Barium,137.33 u,[Xe]6s2,0.89,268 pm,5.212 eV,,2,Solid,1000 K,2170 K,3.62 g/cm3,Alkaline earth metal,1808,81,56,56,2,2,2,6,s-shell,0.204 J/g K,0,Natural,dyinglow,6,2
+57,La,Lanthanum,138.9055 u,[Xe]6s2 5d1,1.1,240 pm,5.577 eV,0.5 eV,3,Solid,1191 K,3737 K,6.15 g/cm3,Lanthanide,1839,82,57,57,,,3,6,f-shell,0.195 J/g K,0,Natural,dyinglow neutron,6,3
+58,Ce,Cerium,140.116 u,[Xe]6s2 4f1 5d1,1.12,235 pm,5.539 eV,0.5 eV,"+4, +3",Solid,1071 K,3697 K,6.770 g/cm3,Lanthanide,1803,82,58,58,,,,6,f-shell,0.192 J/g K,0,Natural,dyinglow,9,3
+59,Pr,Praseodymium,140.90766 u,[Xe]6s2 4f3,1.13,239 pm,5.464 eV,,3,Solid,1204 K,3793 K,6.77 g/cm3,Lanthanide,1885,82,59,59,,,,6,f-shell,0.193 J/g K,0,Natural,dyinglow neutron,9,4
+60,Nd,Neodymium,144.24 u,[Xe]6s2 4f4,1.14,229 pm,5.525 eV,,3,Solid,1294 K,3347 K,7.01 g/cm3,Lanthanide,1885,84,60,60,,,,6,f-shell,0.190 J/g K,0,Natural,dyinglow neutron,9,5
+61,Pm,Promethium,144.91276 u,[Xe]6s2 4f5,,236 pm,5.55 eV,,3,Solid,1315 K,3273 K,7.26 g/cm3,Lanthanide,1945,84,61,61,,,,6,f-shell,,1,Rare,decay,9,6
+62,Sm,Samarium,150.4 u,[Xe]6s2 4f6,1.17,229 pm,5.644 eV,,"+3, +2",Solid,1347 K,2067 K,7.52 g/cm3,Lanthanide,1879,88,62,62,,,,6,f-shell,0.197 J/g K,0,Natural,neutron,9,7
+63,Eu,Europium,151.964 u,[Xe]6s2 4f7,,233 pm,5.670 eV,,"+3, +2",Solid,1095 K,1802 K,5.24 g/cm3,Lanthanide,1901,89,63,63,,,,6,f-shell,0.182 J/g K,0,Natural,neutron,9,8
+64,Gd,Gadolinium,157.2 u,[Xe]6s2 4f7 5d1,1.2,237 pm,6.150 eV,,3,Solid,1586 K,3546 K,7.90 g/cm3,Lanthanide,1880,93,64,64,,,,6,f-shell,0.236 J/g K,0,Natural,neutron,9,9
+65,Tb,Terbium,158.92535 u,[Xe]6s2 4f9,,221 pm,5.864 eV,,3,Solid,1629 K,3503 K,8.23 g/cm3,Lanthanide,1843,94,65,65,,,,6,f-shell,0.182 J/g K,0,Natural,neutron,9,10
+66,Dy,Dysprosium,162.500 u,[Xe]6s2 4f10,1.22,229 pm,5.939 eV,,3,Solid,1685 K,2840 K,8.55 g/cm3,Lanthanide,1886,97,66,66,,,,6,f-shell,0.170 J/g K,0,Natural,neutron,9,11
+67,Ho,Holmium,164.93033 u,[Xe]6s2 4f11,1.23,216 pm,6.022 eV,,3,Solid,1747 K,2973 K,8.80 g/cm3,Lanthanide,1878,98,67,67,,,,6,f-shell,0.165 J/g K,0,Natural,neutron,9,12
+68,Er,Erbium,167.26 u,[Xe]6s2 4f12,1.24,235 pm,6.108 eV,,3,Solid,1802 K,3141 K,9.07 g/cm3,Lanthanide,1843,99,68,68,,,,6,f-shell,0.168 J/g K,0,Natural,neutron,9,13
+69,Tm,Thulium,168.93422 u,[Xe]6s2 4f13,1.25,227 pm,6.184 eV,,3,Solid,1818 K,2223 K,9.32 g/cm3,Lanthanide,1879,100,69,69,,,,6,f-shell,0.160 J/g K,0,Natural,neutron,9,14
+70,Yb,Ytterbium,173.05 u,[Xe]6s2 4f14,,242 pm,6.254 eV,,"+3, +2",Solid,1092 K,1469 K,6.90 g/cm3,Lanthanide,1878,103,70,70,,,,6,f-shell,0.155 J/g K,0,Natural,neutron,9,15
+71,Lu,Lutetium,174.9668 u,[Xe]6s2 4f14 5d1,1.27,221 pm,5.426 eV,,3,Solid,1936 K,3675 K,9.84 g/cm3,Lanthanide,1907,104,71,71,,,,6,f-shell,0.154 J/g K,0,Natural,neutron,9,16
+72,Hf,Hafnium,178.49 u,[Xe]6s2 4f14 5d2,1.3,212 pm,6.825 eV,,4,Solid,2506 K,4876 K,13.3 g/cm3,Transition metal,1923,106,72,72,,,4,6,d-shell,0.144 J/g K,0,Natural,dyinglow neutron,6,4
+73,Ta,Tantalum,180.9479 u,[Xe]6s2 4f14 5d3,1.5,217 pm,7.89 eV,0.322 eV,5,Solid,3290 K,5731 K,16.4 g/cm3,Transition metal,1802,108,73,73,,,5,6,d-shell,0.140 J/g K,0,Natural,dyinglow neutron,6,5
+74,W,Tungsten,183.84 u,[Xe]6s2 4f14 5d4,2.36,210 pm,7.98 eV,0.815 eV,6,Solid,3695 K,5828 K,19.3 g/cm3,Transition metal,1783,110,74,74,,,6,6,d-shell,0.132 J/g K,0,Natural,dyinglow neutron,6,6
+75,Re,Rhenium,186.207 u,[Xe]6s2 4f14 5d5,1.9,217 pm,7.88 eV,0.15 eV,"+7, +6, +4",Solid,3459 K,5869 K,20.8 g/cm3,Transition metal,1925,111,75,75,,,7,6,d-shell,0.137 J/g K,0,Natural,neutron,6,7
+76,Os,Osmium,190.2 u,[Xe]6s2 4f14 5d6,2.2,216 pm,8.7 eV,1.1 eV,"+4, +3",Solid,3306 K,5285 K,22.57 g/cm3,Transition metal,1803,114,76,76,,,8,6,d-shell,0.130 J/g K,0,Natural,neutron,6,8
+77,Ir,Iridium,192.22 u,[Xe]6s2 4f14 5d7,2.2,202 pm,9.1 eV,1.565 eV,"+4, +3",Solid,2719 K,4701 K,22.42 g/cm3,Transition metal,1803,115,77,77,,,9,6,d-shell,0.131 J/g K,0,Natural,neutron,6,9
+78,Pt,Platinum,195.08 u,[Xe]6s1 4f14 5d9,2.28,209 pm,9 eV,2.128 eV,"+4, +2",Solid,2041.55 K,4098 K,21.46 g/cm3,Transition metal,1735,117,78,78,,,10,6,d-shell,0.133 J/g K,0,Natural,neutron,6,10
+79,Au,Gold,196.96657 u,[Xe]6s1 4f14 5d10,2.54,166 pm,9.226 eV,2.309 eV,"+3, +1",Solid,1337.33 K,3129 K,19.282 g/cm3,Transition metal,Ancient,118,79,79,,,11,6,d-shell,0.129 J/g K,0,Natural,neutron,6,11
+80,Hg,Mercury,200.59 u,[Xe]6s2 4f14 5d10,2,209 pm,10.438 eV,,"+2, +1",Liquid,234.32 K,629.88 K,13.5336 g/cm3,Transition metal,Ancient,121,80,80,,,12,6,d-shell,0.140 J/g K,0,Natural,dyinglow neutron,6,12
+81,Tl,Thallium,204.383 u,[Xe]6s2 4f14 5d10 6p1,1.62,196 pm,6.108 eV,0.2 eV,"+3, +1",Solid,577 K,1746 K,11.8 g/cm3,Post-transition metal,1861,123,81,81,3,3,13,6,p-shell,0.129 J/g K,0,Natural,dyinglow,6,13
+82,Pb,Lead,207 u,[Xe]6s2 4f14 5d10 6p2,2.33,202 pm,7.417 eV,0.36 eV,"+4, +2",Solid,600.61 K,2022 K,11.342 g/cm3,Post-transition metal,Ancient,125,82,82,4,4,14,6,p-shell,0.129 J/g K,0,Natural,dyinglow neutron,6,14
+83,Bi,Bismuth,208.98040 u,[Xe]6s2 4f14 5d10 6p3,2.02,207 pm,7.289 eV,0.946 eV,"+5, +3",Solid,544.55 K,1837 K,9.807 g/cm3,Post-transition metal,1753,126,83,83,5,3,15,6,p-shell,0.122 J/g K,0,Natural,neutron,6,15
+84,Po,Polonium,208.98243 u,[Xe]6s2 4f14 5d10 6p4,2,197 pm,8.417 eV,1.9 eV,"+4, +2",Solid,527 K,1235 K,9.32 g/cm3,Metalloid,1898,126,84,84,6,2,16,6,p-shell,,1,Natural,decay,6,16
+85,At,Astatine,209.98715 u,[Xe]6s2 4f14 5d10 6p5,2.2,202 pm,9.5 eV,2.8 eV,"7, 5, 3, 1, -1",Solid,575 K,,7 g/cm3,Halogen,1940,125,85,85,7,1,17,6,p-shell,,1,Rare,decay,6,17
+86,Rn,Radon,222.01758 u,[Xe]6s2 4f14 5d10 6p6,,220 pm,10.745 eV,,0,Gas,202 K,211.45 K,0.00973 g/cm3,Noble gas,1900,136,86,86,8,0,18,6,p-shell,0.094 J/g K,1,Natural,decay,6,18
+87,Fr,Francium,223.01973 u,[Rn]7s1,0.7,348 pm,3.9 eV,0.47 eV,1,Solid,300 K,,,Alkali metal,1939,136,87,87,1,1,1,7,s-shell,,1,Rare,decay,7,1
+88,Ra,Radium,226.02541 u,[Rn]7s2,0.9,283 pm,5.279 eV,,2,Solid,973 K,1413 K,5 g/cm3,Alkaline earth metal,1898,138,88,88,2,2,2,7,s-shell,,1,Natural,decay,7,2
+89,Ac,Actinium,227.02775 u,[Rn]7s2 6d1,1.1,260 pm,5.17 eV,,3,Solid,1324 K,3471 K,10.07 g/cm3,Actinide,1899,138,89,89,,,3,7,f-shell,0.120 J/g K,1,Natural,decay,7,3
+90,Th,Thorium,232.038 u,[Rn]7s2 6d2,1.3,237 pm,6.08 eV,,4,Solid,2023 K,5061 K,11.72 g/cm3,Actinide,1828,142,90,90,,,,7,f-shell,0.113 J/g K,1,Natural,neutron,10,3
+91,Pa,Protactinium,231.03588 u,[Rn]7s2 5f2 6d1,1.5,243 pm,5.89 eV,,"+5, +4",Solid,1845 K,,15.37 g/cm3,Actinide,1913,140,91,91,,,,7,f-shell,,1,Natural,decay,10,4
+92,U,Uranium,238.0289 u,[Rn]7s2 5f3 6d1,1.38,240 pm,6.194 eV,,"+6, +5, +4, +3",Solid,1408 K,4404 K,18.95 g/cm3,Actinide,1789,146,92,92,,,,7,f-shell,0.116 J/g K,1,Natural,neutron,10,5
+93,Np,Neptunium,237.048172 u,[Rn]7s2 5f4 6d1,1.36,221 pm,6.266 eV,,"+6, +5, +4, +3",Solid,917 K,4175 K,20.25 g/cm3,Actinide,1940,144,93,93,,,,7,f-shell,,1,Rare,decay,10,6
+94,Pu,Plutonium,244.06420 u,[Rn]7s2 5f6,1.28,243 pm,6.06 eV,,"+6, +5, +4, +3",Solid,913 K,3501 K,19.84 g/cm3,Actinide,1940,150,94,94,,,,7,f-shell,,1,Rare,neutron,10,7
+95,Am,Americium,243.061380 u,[Rn]7s2 5f7,1.3,244 pm,5.993 eV,,"+6, +5, +4, +3",Solid,1449 K,2284 K,13.69 g/cm3,Actinide,1944,148,95,95,,,,7,f-shell,,1,Rare,human,10,8
+96,Cm,Curium,247.07035 u,[Rn]7s2 5f7 6d1,1.3,245 pm,6.02 eV,,3,Solid,1618 K,3400 K,13.51 g/cm3,Actinide,1944,151,96,96,,,,7,f-shell,,1,Rare,human,10,9
+97,Bk,Berkelium,247.07031 u,[Rn]7s2 5f9,1.3,244 pm,6.23 eV,,"+4, +3",Solid,1323 K,,14 g/cm3,Actinide,1949,150,97,97,,,,7,f-shell,,1,Rare,human,10,10
+98,Cf,Californium,251.07959 u,[Rn]7s2 5f10,1.3,245 pm,6.30 eV,,3,Solid,1173 K,,,Actinide,1950,153,98,98,,,,7,f-shell,,1,Rare,human,10,11
+99,Es,Einsteinium,252.0830 u,[Rn]7s2 5f11,1.3,245 pm,6.42 eV,,3,Solid,1133 K,,,Actinide,1952,153,99,99,,,,7,f-shell,,1,Synthetic,human,10,12
+100,Fm,Fermium,257.09511 u,[Rn] 5f12 7s2,1.3,,6.50 eV,,3,Solid,1800 K,,,Actinide,1952,157,100,100,,,,7,f-shell,,1,Synthetic,human,10,13
+101,Md,Mendelevium,258.09843 u,[Rn]7s2 5f13,1.3,,6.58 eV,,"+3, +2",Solid,1100 K,,,Actinide,1955,157,101,101,,,,7,f-shell,,1,Synthetic,human,10,14
+102,No,Nobelium,259.10100 u,[Rn]7s2 5f14,1.3,,6.65 eV,,"+3, +2",Solid,1100 K,,,Actinide,1957,157,102,102,,,,7,f-shell,,1,Synthetic,human,10,15
+103,Lr,Lawrencium,266.120 u,[Rn]7s2 5f14 6d1,,,,,3,Solid,1900 K,,,Actinide,1961,159,103,103,,,,7,f-shell,,1,Synthetic,human,10,16
+104,Rf,Rutherfordium,267.122 u,[Rn]7s2 5f14 6d2,,,,,4,Solid,,,,Transition metal,1964,157,104,104,,,4,7,d-shell,,1,Synthetic,human,7,4
+105,Db,Dubnium,268.126 u,[Rn]7s2 5f14 6d3,,,,,"5, 4, 3",Solid,,,,Transition metal,1967,157,105,105,,,5,7,d-shell,,1,Synthetic,human,7,5
+106,Sg,Seaborgium,269.128 u,[Rn]7s2 5f14 6d4,,,,,"6, 5, 4, 3, 0",Solid,,,,Transition metal,1974,160,106,106,,,6,7,d-shell,,1,Synthetic,human,7,6
+107,Bh,Bohrium,270.133 u,[Rn]7s2 5f14 6d5,,,,,"7, 5, 4, 3",Solid,,,,Transition metal,1976,157,107,107,,,7,7,d-shell,,1,Synthetic,human,7,7
+108,Hs,Hassium,269.1336 u,[Rn]7s2 5f14 6d6,,,,,"8, 6, 5, 4, 3, 2",Solid,,,,Transition metal,1984,159,108,108,,,8,7,d-shell,,1,Synthetic,human,7,8
+109,Mt,Meitnerium,277.154 u,[Rn]7s2 5f14 6d7 **,,,,,"9, 8, 6, 4, 3, 1",Solid,,,,Transition metal,1982,159,109,109,,,9,7,d-shell,,1,Synthetic,human,7,9
+110,Ds,Darmstadtium,282.166 u,[Rn]7s2 5f14 6d8 **,,,,,"8, 6, 4, 2, 0",Solid **,,,,Transition metal,1994,161,110,110,,,10,7,d-shell,,1,Synthetic,human,7,10
+111,Rg,Roentgenium,282.169 u,[Rn]7s2 5f14 6d9 **,,,,,"5, 3, 1, -1",Solid **,,,,Transition metal,1994,161,111,111,,,11,7,d-shell,,1,Synthetic,human,7,11
+112,Cn,Copernicium,286.179 u,[Rn]7s2 5f14 6d10 **,,,,,"2, 1, 0",Solid **,,,,Transition metal,1996,173,112,112,,,12,7,d-shell,,1,Synthetic,human,7,12
+113,Nh,Nihonium,286.182 u,[Rn]5f14 6d10 7s2 7p1 **,,,,,,Solid **,,,,Post-transition metal,2004,171,113,113,3,3,13,7,p-shell,,1,Synthetic,human,7,13
+114,Fl,Flerovium,290.192 u,[Rn]7s2 7p2 5f14 6d10 **,,,,,"6, 4, 2, 1, 0",Solid **,,,,Post-transition metal,1998,175,114,114,4,4,14,7,p-shell,,1,Synthetic,human,7,14
+115,Mc,Moscovium,290.196 u,[Rn]7s2 7p3 5f14 6d10 **,,,,,"3, 1",Solid **,,,,Post-transition metal,2003,173,115,115,5,3,15,7,p-shell,,1,Synthetic,human,7,15
+116,Lv,Livermorium,293.205 u,[Rn]7s2 7p4 5f14 6d10 **,,,,,"+4, +2, -2",Solid **,,,,Post-transition metal,2000,176,116,116,6,2,16,7,p-shell,,1,Synthetic,human,7,16
+117,Ts,Tennessine,294.211 u,[Rn]7s2 7p5 5f14 6d10 **,,,,,"+5, +3, +1, -1",Solid **,,,,Halogen,2010,178,117,117,7,1,17,7,p-shell,,1,Synthetic,human,7,17
+118,Og,Oganesson,295.216 u,[Rn]7s2 7p6 5f14 6d10 **,,,,,"+6, +4, +2, +1, 0, -1",Gas **,,,,Noble gas,2006,176,118,118,8,0,18,7,p-shell,,1,Synthetic,human,7,18

ADDED   data/families.csv
Index: data/families.csv
==================================================================
--- /dev/null
+++ data/families.csv
@@ -0,0 +1,11 @@
+Family,Name,Description
+"Alkali metal","Alkali Metals","The Alkali Metals, found in Group 1 of the Periodic Table, are highly reactive metals that do not occur freely in nature. These metals have only one electron in their outer shell. Therefore, they are ready to lose that one electron in ionic bonding with other elements. The Alkali Metals are malleable, ductile, silvery, good conductors of heat and electricity, and have low melting points, boiling points, and densities. They also react violently with water and therefore must be stored in oil."
+"Alkaline earth metal","Alkaline Earth Metals","The Alkaline Earth Metals are metallic elements found in Group 2 of the Periodic Table. All Alkaline Earth Metals are strong reducing agents, and have an oxidation number of +2, making them very reactive. These metals are also shiny, lustrous, and good conductors of heat and electricity. They have low melting points, boiling points, and densities (but higher than those of Alkali Metals)."
+"Transition metal","Transition Metals","The 38 elements in Groups 3 through 12 of the Periodic Table are called Transition Metals. As with all metals, the Transition elements are both ductile and malleable, and good conductors of heat and electricity. Their valence electrons are present in more than one shell. This is why they often exhibit several common oxidation states. They also have high melting points, boiling points, and densities."
+"Post-transition metal","Post-Transition Metals","While Post-Transition Metals are ductile and malleable, they are not the same as the Transition Metals. These elements, unlike the Transition Metals, do not exhibit variable oxidation states, and their valence electrons are only present in their outer shell. All of these elements are solid, have a relatively high density, and are opaque."
+"Metalloid","Metalloids","Metalloids are the elements found between the boundary that distinguishes metals from non-metals. Metalloids have properties of both metals and non-metals. For example, they can be shiny or dull, and are more brittle than metals but less brittle than non-metals. Some of the Metalloids, such as Silicon and Germanium, are semi-conductors because they partially conduct electricity."
+"Nonmetal","Nonmetals","Non-metals are the elements in Groups 14-16 of the Periodic Table. Non-metals are not able to conduct electricity or heat very well. As opposed to metals, non-metallic elements are very brittle. The Non-metals can be gases such as oxygen, and solids such as carbon. The Non-metals have no metallic luster, and do not reflect light."
+"Halogen","Halogens","The Halogens are non-metallic elements found in Group 17 of the Periodic Table. All Halogens have 7 electrons in their outer shells, giving them an oxidation number of -1. The members of the Halogen family are highly reactive, toxic to humans, and go from gas to liquid to solid at room temperature as you descend the group. The word ""halogen"" means ""salt former"" or ""salt maker"". When Halogens react with metals, they produce a wide range of salts. Halogens also have a high electronegativity and electron affinity."
+"Noble gas","Noble Gases","The Noble Gases are found in Group 18 of the Periodic Table. These elements have an oxidation number of 0. This prevents them from forming compounds readily. All Noble Gases also have 8 electrons in their outer shell, making them stable, inert, and highly non-reactive. They are all odorless, colorless, monatomic, have low melting points, low boiling points, and high ionization energies."
+"Lanthanide","Lanthanides","The Lanthanides consist of the elements in the f-block in Period 6 of the Periodic Table. They are soft, silvery, bright metals that all naturally occur except for Promethium. They are also highly reactive and strong reducing agents. Rare earth elements which are useful for their metallurgical properties in alloy form are composed of the Lanthanide family plus Scandium and Yttrium. They also have high melting points and boiling points."
+"Actinide","Actinides","The Actinides consist of the elements in the f-block in Period 7 of the Periodic Table. All the elements of the Actinides family are radioactive and most are synthetic, that is, human-made. All have a silvery or silvery-white luster in metallic form, and are soft, ductile, and paramagnetic."

ADDED   data/periodic.txt
Index: data/periodic.txt
==================================================================
--- /dev/null
+++ data/periodic.txt
@@ -0,0 +1,143 @@
+H                                                  He
+Li Be                               B  C  N  O  F  Ne
+Na Mg                               Al Si P  S  Cl Ar
+K  Ca Sc Ti V  Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr
+Rb Sr Y  Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I  Xe
+Cs Ba La Hf Ta W  Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn
+Fr Ra Ac Rf Db Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og
+
+      Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu
+      Th Pa U  Np Pu Am Cm Bk Cf Es Fm Md No Lr
+
+
+ALPHABETIC LIST BY SYMBOL
+                  Z    RAM*
+Ac Actinium       89
+Ag Silver         47  107.87
+Al Aluminium      13   26.98
+Am Americium      95
+Ar Argon          18   39.95
+As Arsenic        33   74.92
+At Astatine       85
+Au Gold           79  196.97
+B  Boron           5   10.81
+Ba Barium         56  137.33
+Be Beryllium       4    9.01
+Bh Bohrium       107
+Bi Bismuth        83  208.98
+Bk Berkelium      97
+Br Bromine        35   79.90
+C  Carbon          6   12.01
+Ca Calcium        20   40.08
+Cd Cadmium        48  112.41
+Ce Cerium         58  140.12
+Cf Californium    98
+Cl Chlorine       17   35.45
+Cm Curium         96
+Cn Copernicium   112
+Co Cobalt         27   58.93
+Cr Chromium       24   52.00
+Cs Caesium        55  132.91
+Cu Copper         29   63.55
+Db Dubnium       105
+Ds Darmstadtium  110
+Dy Dysprosium     66  162.50
+Er Erbium         68  167.26
+Es Einsteinium    99
+Eu Europium       63
+F  Fluorine        9   19.00
+Fe Iron           26   55.85
+Fl Flerovium     114
+Fm Fermium       100
+Fr Francium       87
+Ga Gallium        31   69.72
+Gd Gadolinium     64  157.25
+Ge Germanium      32   72.63
+H  Hydrogen        1    1.008
+He Helium          2    4.003
+Hf Hafnium        72  178.49
+Hg Mercury        80  200.59
+Ho Holmium        67  164.93
+Hs Hassium       108
+I  Iodine         53  126.90
+In Indium         49  114.82
+Ir Iridium        77  192.22
+K  Potassium      19   39.10
+Kr Krypton        36   83.80
+La Lanthanum      57  138.91
+Li Lithium         3    6.94
+Lr Lawrencium    103
+Lu Lutetium       71  174.97
+Lv Livermorium   116
+Mc Moscovium     115
+Md Mendeleevium  101
+Mg Magnesium      12   24.31
+Mn Manganese      25   54.94
+Mo Molybdenum     42   95.95
+Mt Meitnerium    109
+N  Nitrogen        7   14.01
+Na Sodium         11   22.99
+Nb Niobium        41   92.91
+Nd Neodymium      60  114.24
+Ne Neon           10   20.18
+Nh Nihonium      113
+Ni Nickel         28   58.69
+No Nobelium      102
+Np Neptunium      93
+O  Oxygen          8   16.00
+Og Oganesson     118
+Os Osmium         76  190.23
+P  Phosphorus     15   30.97
+Pa Protactinium   91
+Pb Lead           82  207.2
+Pd Palladium      46  106.42
+Pm Promethium     61
+Po Polonium       84
+Pr Praseodymium   59  140.91
+Pt Platinum       78  195.08
+Pu Plutonium      94
+Ra Radium         88
+Rb Rubidium       37   85.47
+Re Rhenium        75  186.21
+Rf Rutherfordium 104
+Rg Roentgenium   111
+Rh Rhodium        45  102.91
+Rn Radon          86
+Ru Ruthenium      44  101.07
+S  Sulphur        16   32.06
+Sb Antimony       51  121.76
+Sc Scandium       21   44.96
+Se Selenium       34   78.97
+Sg Seaborgium    106
+Si Silicon        14   28.09
+Sm Samarium       62  150.36
+Sn Tin            50  118.71
+Sr Strontium      38   87.62
+Ta Tantalum       73  180.95
+Tb Terbium        65  158.93
+Tc Technetium     43
+Te Tellurium      52  127.60
+Th Thorium        90  232.04
+Ti Titanium       22   47.87
+Tl Thallium       81  204.38
+Tm Thulium        69  168.93
+Ts Tennessine    117
+U  Uranium        92  238.03
+V  Vanadium       23   50.94
+W  Tungsten       74  183.84
+Xe Xenon          54  131.29
+Y  Yttrium        39   88.91
+Yb Ytterbium      70  173.05
+Zn Zinc           30   65.38
+Zr Zirconium      40   91.22
+
+* Relative atomic masses are given to two decimal places except for
+hydrogen and helium, where this would lead to an unsuitably low
+precision, and for lead, where the isotopic composition of samples
+varies so much that two decimal places is inappropriate.  RAMs are
+omitted for elements which do not occur naturally (such as plutonium),
+or which occur naturally only as a temporary part of a decay chain
+(such as radium).
+
+From: <gopher://gopher.srcf.net/0/users/amr66/b_scientific/
+periodic_table.txt>

ADDED   data/shells.csv
Index: data/shells.csv
==================================================================
--- /dev/null
+++ data/shells.csv
@@ -0,0 +1,5 @@
+Shell,Name,Description
+"s-shell","s-block","The s-block consists of elements in Groups 1 and 2 plus Helium. The valence electrons of these elements are in the s-shell. This spherical shaped shell holds at most 2 electrons, and has an azimuthal quantum number of 0. The ""s"" stands for ""sharp""."
+"p-shell","p-block","The p-block consists elements in Groups 13 to 18 but not Helium. The valence electrons of these elements are in the p-shell. This dumb-bell shaped shell holds at most 6 electrons, and has an azimuthal quantum number of 1. The ""p"" stands for ""principal""."
+"d-shell","d-block","The d-block consists of elements in Groups 3 to 12. The valence electrons of these elements are in the d-shell. This shell holds at most 10 electrons, and has an azimuthal quantum number of 2. The ""d"" stands for ""diffuse""."
+"f-shell","f-block","The f-block consists of elements in the Lanthanides and Actinides families. The valence electrons of these elements are in the f-shell. This shell holds at most 14 electrons, and has an azimuthal quantum number of 3. The ""f"" stands for ""fundamental""."

ADDED   data/sources.csv
Index: data/sources.csv
==================================================================
--- /dev/null
+++ data/sources.csv
@@ -0,0 +1,9 @@
+Source,Name
+"bigbang","The big bang"
+"dyinghigh","Dying high-mass stars"
+"dyinglow","Dying low-mass stars"
+"supernova","White dwarf supernovae"
+"decay","Radioactive decay"
+"rays","Cosmic ray collision"
+"neutron","Merging neutron stars"
+"human","Human-made"

ADDED   periodic.awk
Index: periodic.awk
==================================================================
--- /dev/null
+++ periodic.awk
@@ -0,0 +1,923 @@
+# periodic.awk version 1 by Ben Collver
+#
+# Generate static gopher content for the periodic table of elements.
+#
+# Edit gopher_dir, gopher_host, and gopher_port in function main()
+#
+# Requires figlet and uncsv.
+#
+# http://www.figlet.org
+# https://tamentis.com/projects/uncsv/
+
+function center(width, str,    len, pad, retval) {
+    len = int(width / 2) - int(length(str) / 2)
+    if (len > 0) {
+        pad = sprintf("%" len "s", " ")
+    }
+    retval = sprintf("%-" width "s", pad str)
+    return retval
+}
+
+function csv_read(f, out,     base, cmd, header, i, key) {
+    OLDFS = FS
+    FS = "\t"
+    NR = 0
+    delete out
+    cmd = "uncsv -d \"\t\" \"" f "\""
+    while ((cmd | getline) > 0) {
+        base = NR
+        NR++
+        if (NR == 1) {
+            for (i = 1; i <= NF; i++) {
+                header[i] = $i
+            }
+        } else {
+            for (i = 1; i <= NF; i++) {
+                if (!i in header) {
+                    print "Error: invalid header index: " i
+                    exit 1
+                }
+                key = base "_" header[i]
+                out[key] = $i
+            }
+            key = base "_length"
+            out[key] = NF
+        }
+    }
+    out["length"] = base
+    close(cmd)
+    FS = OLDFS
+    return
+}
+
+function dir(str,    retval) {
+    retval = tolower(str)
+    gsub(/ /, "-", retval)
+    return retval
+}
+
+function format_field(f, element, fieldname,    key, retval) {
+    key = element "_" fieldname
+    retval = sprintf("%-23s %s", fieldname ":", elements[key])
+    return retval
+}
+
+# heapsort
+#
+# Unstable, and unlike merge and quicksort it relies on random-access
+# so has poorer cache performance.
+#
+# Advantage over quicksort is that its worst-case same as avg: O(n log n)
+#
+# This presentation based on http://dada.perl.it/shootout/heapsort.lua5.html
+#
+# From: <https://raw.githubusercontent.com/
+# dubiousjim/awkenough/refs/heads/master/library.awk>
+#
+# Requires 1-based numerically indexed arrays.
+
+function hsort(A, n,   c, p, t, i) {
+    if (!n) {
+        n = 1
+        while (n in A) n++
+        n--
+    }
+    i = int(n/2) + 1
+    while (1) {
+        if (i > 1) {
+            i--
+            t = A[i]
+        } else {
+            t = A[n]
+            A[n] = A[1]
+            n--
+            if (n == 1) {
+                A[1] = t
+                return
+            }
+        }
+        for (p = i; (c = 2*p) <= n; p = c) {
+            if ((c < n) && (A[c] < A[c+1]))
+                c++
+            if (t < A[c])
+                A[p] = A[c]
+            else break
+        }
+        A[p] = t
+    }
+}
+
+function make_source_lookup(    i, key, len, source_id) {
+    delete source_lookup
+
+    len = sources["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Source"
+        source_id = sources[key]
+        source_lookup[source_id] = i
+    }
+    return
+}
+
+function make_table(    col, cols, i, key, len, row, rows) {
+    delete table_col
+    delete table_row
+    delete table
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Table Column"
+        col = elements[key]
+        if (col > cols) {
+            cols = col
+        }
+        key = i "_Table Row"
+        row = elements[key]
+        if (row > rows) {
+            rows = row
+        }
+        key = row "_" col
+        table[key] = i
+        table_col[i] = col
+        table_row[i] = row
+    }
+    table["cols"] = cols
+    table["rows"] = rows
+    return
+}
+
+function print_element_gph(element,    cmd, count, f, i, key, label, \
+    mass, name, path, source_list, source, str, symbol)
+{
+    f = outdir "/element/" element "/index.gph"
+    key = element "_Atomic Mass"
+    mass = elements[key]
+    key = element "_Name"
+    name = elements[key]
+    key = element "_Symbol"
+    symbol = elements[key]
+
+    label = sprintf("%d %s %s (plaintext)", element, symbol, name)
+    path = gopher_dir "/element/" element "/index.txt"
+    printf "[0|%s|%s|%s|%s]\n\n", label, path, gopher_host, gopher_port >f
+
+    print_table(f)
+    printf "\n" >>f
+
+    # navigation
+
+    str = "Left"
+    if (table_col[element] > 1) {
+        key = table_row[element] "_" (table_col[element] - 1)
+        path = gopher_dir "/element/" table[key] "/"
+        printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+    } else {
+        printf "%s\n", str >>f
+    }
+
+    str = "Up"
+    if (table_row[element] > 1) {
+        key = (table_row[element] - 1) "_" table_col[element]
+        path = gopher_dir "/element/" table[key] "/"
+        printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+    } else {
+        printf "%s\n", str >>f
+    }
+
+    str = "Down"
+    if (table_row[element] < table["rows"]) {
+        key = (table_row[element] + 1) "_" table_col[element]
+        path = gopher_dir "/element/" table[key] "/"
+        printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+    } else {
+        printf "%s\n", str >>f
+    }
+
+    str = "Right"
+    if (table_col[element] < table["cols"]) {
+        key = table_row[element] "_" (table_col[element] + 1)
+        path = gopher_dir "/element/" table[key] "/"
+        printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+    } else {
+        printf "%s\n", str >>f
+    }
+
+    str = "List All"
+    path = gopher_dir "/list/atomic/"
+    printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+
+    # element detail
+
+    cmd = "figlet " symbol
+    printf "+--------------------+\n" >>f
+    NR = 0
+    while ((cmd | getline) > 0) {
+        NR++
+        if (NR == 1) {
+            str = sprintf("%3d", element) substr(center(20, $0), 4)
+        } else {
+            str = center(20, $0)
+        }
+        printf "|%s|\n", str >>f
+    }
+    close(cmd)
+    str = center(20, name)
+    printf "|%s|\n", str >>f
+    str = center(20, mass)
+    printf "|%s|\n", str >>f
+    printf "+--------------------+\n\n" >>f
+    print format_field(f, element, "Electron Configuration") >>f
+    print format_field(f, element, "Electronegativity") >>f
+    print format_field(f, element, "Atomic Radius") >>f
+    print format_field(f, element, "Ionization Energy") >>f
+    print format_field(f, element, "Electron Affinity") >>f
+    print format_field(f, element, "Oxidation States") >>f
+    print format_field(f, element, "Standard State") >>f
+    print format_field(f, element, "Melting Point") >>f
+    print format_field(f, element, "Boiling Point") >>f
+    print format_field(f, element, "Density") >>f
+
+    str = format_field(f, element, "Family")
+    key = element "_Family"
+    path = gopher_dir "/family/" dir(elements[key]) "/"
+    printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+
+    print format_field(f, element, "Year Discovered") >>f
+    print format_field(f, element, "Number of Neutrons") >>f
+    print format_field(f, element, "Number of Protons") >>f
+    print format_field(f, element, "Number of Electrons") >>f
+    print format_field(f, element, "Number of Valence") >>f
+    print format_field(f, element, "Valency") >>f
+    print format_field(f, element, "Group") >>f
+    print format_field(f, element, "Period") >>f
+
+    str = format_field(f, element, "Shell")
+    key = element "_Shell"
+    path = gopher_dir "/shell/" elements[key] "/"
+    printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+
+    print format_field(f, element, "Specific Heat") >>f
+    print format_field(f, element, "Radioactive") >>f
+    print format_field(f, element, "Occurrence") >>f
+
+    key = element "_Source"
+    source_list = elements[key]
+    count = split(source_list, source, / /)
+    for (i = 1; i <= count; i++) {
+        key = source_lookup[source[i]] "_Name"
+        name = sources[key]
+        str = sprintf("%-23s %s", "Source:", name)
+        path = gopher_dir "/source/" source[i] "/"
+        printf "[1|%s|%s|%s|%s]\n", str, path, gopher_host, gopher_port >>f
+    }
+
+    close(f)
+    return
+}
+
+function print_element_txt(element,    cmd, f, key, label, map, mass, \
+    name, path, str, symbol, txt)
+{
+    f = outdir "/element/" element "/index.txt"
+    key = element "_Atomic Mass"
+    mass = elements[key]
+    key = element "_Name"
+    name = elements[key]
+    key = element "_Symbol"
+    symbol = elements[key]
+
+    printf "%d %s %s\n\n", element, symcol, name >f
+    print_table(f)
+    printf "\n" >>f
+
+    cmd = "figlet " symbol
+    printf "+--------------------+\n" >>f
+    NR = 0
+    while ((cmd | getline) > 0) {
+        NR++
+        if (NR == 1) {
+            str = sprintf("%3d", element) substr(center(20, $0), 4)
+        } else {
+            str = center(20, $0)
+        }
+        printf "|%s|\n", str >>f
+    }
+    close(cmd)
+    str = center(20, name)
+    printf "|%s|\n", str >>f
+    str = center(20, mass)
+    printf "|%s|\n", str >>f
+    printf "+--------------------+\n\n" >>f
+    print format_field(f, element, "Electron Configuration") >>f
+    print format_field(f, element, "Electronegativity") >>f
+    print format_field(f, element, "Atomic Radius") >>f
+    print format_field(f, element, "Ionization Energy") >>f
+    print format_field(f, element, "Electron Affinity") >>f
+    print format_field(f, element, "Oxidation States") >>f
+    print format_field(f, element, "Standard State") >>f
+    print format_field(f, element, "Melting Point") >>f
+    print format_field(f, element, "Boiling Point") >>f
+    print format_field(f, element, "Density") >>f
+    print format_field(f, element, "Family") >>f
+    print format_field(f, element, "Year Discovered") >>f
+    print format_field(f, element, "Number of Neutrons") >>f
+    print format_field(f, element, "Number of Protons") >>f
+    print format_field(f, element, "Number of Electrons") >>f
+    print format_field(f, element, "Number of Valence") >>f
+    print format_field(f, element, "Valency") >>f
+    print format_field(f, element, "Group") >>f
+    print format_field(f, element, "Period") >>f
+    print format_field(f, element, "Shell") >>f
+    print format_field(f, element, "Specific Heat") >>f
+    print format_field(f, element, "Radioactive") >>f
+    print format_field(f, element, "Occurrence") >>f
+
+    key = element "_Source"
+    source_list = elements[key]
+    count = split(source_list, source, / /)
+    for (i = 1; i <= count; i++) {
+        key = source_lookup[source[i]] "_Name"
+        name = sources[key]
+        printf "%-23s %s\n", "Source:", name >>f
+    }
+
+    close(f)
+    return
+}
+
+function print_elements(     i, len) {
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+        select_clear()
+        select_atom(i)
+        print_element_gph(i)
+        print_element_txt(i)
+    }
+    return
+}
+
+function print_families(    family_id, fdir, i, key, len, name, outfile) {
+    outfile = outdir "/family/index.gph"
+    printf "# Families\n\n" >outfile
+    len = families["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Family"
+        family_id = families[key]
+        key = i "_Name"
+        name = families[key]
+        fdir = dir(family_id)
+        printf "[1|%s|%s/family/%s/|%s|%s]\n", name, gopher_dir, fdir, \
+            gopher_host, gopher_port >>outfile
+        select_clear()
+        select_family(family_id)
+        print_family_gph(i, family_id, name, fdir)
+        print_family_txt(i, family_id, name, fdir)
+    }
+    close(outfile)
+    return
+}
+
+function print_family_gph(family, family_id, name, fdir,    descr, i, \
+    f, key, label, len, path, symbol)
+{
+    key = family "_Description"
+    descr = families[key]
+
+    f = outdir "/family/" fdir "/index.gph"
+
+    label = sprintf("Family: %s", name)
+    path = sprintf("%s/family/%s/index.txt", gopher_dir, fdir)
+    printf "[0|%s|%s|%s|%s]\n\n", label, path, gopher_host, gopher_port >f
+
+    print_table(f)
+
+    printf "\n" >>f
+    print_wrap(descr, 70, f)
+    printf "\n" >>f
+
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Family"
+         if (elements[key] == family_id) {
+             key = i "_Name"
+             name = elements[key]
+             key = i "_Symbol"
+             symbol = elements[key]
+             label = sprintf("%3d %-2s %s", i, symbol, name)
+             path = sprintf("%s/element/%d/", gopher_dir, i)
+             printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host,
+                 gopher_port >>f
+         }
+    }
+
+    printf "\n" >>f
+    printf "[1|All Families|%s/family/|%s|%s]\n", gopher_dir, \
+        gopher_host, gopher_port >>f
+
+    close(f)
+    return
+}
+
+function print_family_txt(family, family_id, name, fdir,    descr, i, \
+    f, key, len, symbol)
+{
+    key = family "_Description"
+    descr = families[key]
+
+    f = outdir "/family/" fdir "/index.txt"
+
+    printf "Family: %s\n\n", name >f
+
+    print_table(f)
+
+    printf "\n" >>f
+    print_wrap(descr, 70, f)
+    printf "\n" >>f
+
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Family"
+         if (elements[key] == family_id) {
+             key = i "_Name"
+             name = elements[key]
+             key = i "_Symbol"
+             symbol = elements[key]
+             printf "%3d %-2s %s\n", i, symbol, name >>f
+         }
+    }
+
+    close(f)
+    return
+}
+
+function print_list_atomic(    f, i, key, label, name, path, symbol) {
+    f = outdir "/list/atomic/index.gph"
+    printf "# List Elements By Atomic Number\n\n" >f
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Name"
+        name = elements[key]
+        key = i "_Symbol"
+        symbol = elements[key]
+        label = sprintf("%3d %-2s %s", i, symbol, name)
+        path = sprintf("%s/element/%d/", gopher_dir, i)
+        printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+    }
+    printf "\n" >>f
+
+    printf "List Elements By Atomic Number\n" >>f
+
+    label = "List Elements By Name"
+    path = sprintf("%s/list/name/", gopher_dir)
+    printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+
+    label = "List Elements By Symbol"
+    path = sprintf("%s/list/symbol/", gopher_dir)
+    printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+
+    close(f)
+    return
+}
+
+function print_list_name(    element, f, i, key, label, len, map, \
+    name, order, path, symbol)
+{
+    delete map
+    delete order
+    f = outdir "/list/name/index.gph"
+    printf "# List Elements By Name\n\n" >f
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Name"
+        name = elements[key]
+        map[name] = i
+        order[i] = name
+    }
+    hsort(order, len)
+    for (i = 1; i <= len; i++) {
+        name = order[i]
+        element = map[name]
+        key = element "_Symbol"
+        symbol = elements[key]
+        label = sprintf("%3d %-2s %s", element, symbol, name)
+        path = sprintf("%s/element/%d/", gopher_dir, element)
+        printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+    }
+    printf "\n" >>f
+
+    label = "List Elements By Atomic Number"
+    path = sprintf("%s/list/atomic/", gopher_dir)
+    printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+
+    printf "List Elements By Name\n" >>f
+
+    label = "List Elements By Symbol"
+    path = sprintf("%s/list/symbol/", gopher_dir)
+    printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+
+    return
+}
+
+function print_list_symbol(    element, f, i, key, label, len, map, \
+    name, order, path, symbol)
+{
+    delete map
+    delete order
+    f = outdir "/list/symbol/index.gph"
+    printf "# List Elements By Symbol\n\n" >f
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Symbol"
+        symbol = elements[key]
+        map[symbol] = i
+        order[i] = symbol
+    }
+    hsort(order, len)
+    for (i = 1; i <= len; i++) {
+        symbol = order[i]
+        element = map[symbol]
+        key = element "_Name"
+        name = elements[key]
+        label = sprintf("%3d %-2s %s", element, symbol, name)
+        path = sprintf("%s/element/%d/", gopher_dir, element)
+        printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+    }
+    printf "\n" >>f
+
+    label = "List Elements By Atomic Number"
+    path = sprintf("%s/list/atomic/", gopher_dir)
+    printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+
+    label = "List Elements By Name"
+    path = sprintf("%s/list/name/", gopher_dir)
+    printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host, gopher_port >>f
+
+    printf "List Elements By Symbol\n" >>f
+
+    return
+}
+
+function print_lists() {
+    print_list_atomic()
+    print_list_name()
+    print_list_symbol()
+    return
+}
+
+function print_shells(    i, key, len, name, outfile, shell_id) {
+    outfile = outdir "/shell/index.gph"
+    printf "# Shells\n\n" >outfile
+    len = shells["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Shell"
+        shell_id = shells[key]
+        key = i "_Name"
+        name = shells[key]
+        printf "[1|%s|%s/shell/%s/|%s|%s]\n", name, gopher_dir, \
+            shell_id, gopher_host, gopher_port >>outfile
+        select_clear()
+        select_shell(shell_id)
+        print_shell_gph(i, shell_id, name)
+        print_shell_txt(i, shell_id, name)
+    }
+    close(outfile)
+    return
+}
+
+function print_shell_gph(shell, shell_id, name,    descr, i, \
+    f, key, label, len, path, symbol)
+{
+    key = shell "_Description"
+    descr = shells[key]
+
+    f = outdir "/shell/" shell_id "/index.gph"
+
+    label = sprintf("Shell: %s", name)
+    path = sprintf("%s/shell/%s/index.txt", gopher_dir, shell_id)
+    printf "[0|%s|%s|%s|%s]\n\n", label, path, gopher_host, gopher_port >f
+
+    print_table(f)
+
+    printf "\n" >>f
+    print_wrap(descr, 70, f)
+    printf "\n" >>f
+
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Shell"
+         if (elements[key] == shell_id) {
+             key = i "_Name"
+             name = elements[key]
+             key = i "_Symbol"
+             symbol = elements[key]
+             label = sprintf("%3d %-2s %s", i, symbol, name)
+             path = sprintf("%s/element/%d/", gopher_dir, i)
+             printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host,
+                 gopher_port >>f
+         }
+    }
+
+    printf "\n" >>f
+    printf "[1|All Shells|%s/shell/|%s|%s]\n", gopher_dir, \
+        gopher_host, gopher_port >>f
+
+    close(f)
+    return
+}
+
+function print_shell_txt(shell, shell_id, name,    descr, i, \
+    f, key, len, symbol)
+{
+    key = shell "_Description"
+    descr = shells[key]
+
+    f = outdir "/shell/" shell_id "/index.txt"
+
+    printf "Shell: %s\n\n", name >f
+
+    print_table(f)
+
+    printf "\n" >>f
+    print_wrap(descr, 70, f)
+    printf "\n" >>f
+
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Shell"
+         if (elements[key] == shell_id) {
+             key = i "_Name"
+             name = elements[key]
+             key = i "_Symbol"
+             symbol = elements[key]
+             printf "%3d %-2s %s\n", i, symbol, name >>f
+         }
+    }
+
+    close(f)
+    return
+}
+
+function print_sources(    i, key, len, name, outfile, source_id) {
+    outfile = outdir "/source/index.gph"
+    printf "# Sources\n\n" >outfile
+    len = sources["length"]
+    for (i = 1; i <= len; i++) {
+        key = i "_Source"
+        source_id = sources[key]
+        key = i "_Name"
+        name = sources[key]
+        printf "[1|%s|%s/source/%s/|%s|%s]\n", name, gopher_dir, \
+            source_id, gopher_host, gopher_port >>outfile
+        select_clear()
+        select_source(source_id)
+        print_source_gph(i, source_id, name)
+        print_source_txt(i, source_id, name)
+    }
+    close(outfile)
+    return
+}
+
+function print_source_gph(source, source_id, name,    i, \
+    f, key, label, len, path, symbol)
+{
+    f = outdir "/source/" source_id "/index.gph"
+
+    label = sprintf("Source: %s", name)
+    path = sprintf("%s/source/%s/index.txt", gopher_dir, source_id)
+    printf "[0|%s|%s|%s|%s]\n\n", label, path, gopher_host, gopher_port >f
+
+    print_table(f)
+    printf "\n" >>f
+
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Source"
+         if (elements[key] == source_id) {
+             key = i "_Name"
+             name = elements[key]
+             key = i "_Symbol"
+             symbol = elements[key]
+             label = sprintf("%3d %-2s %s", i, symbol, name)
+             path = sprintf("%s/element/%d/", gopher_dir, i)
+             printf "[1|%s|%s|%s|%s]\n", label, path, gopher_host,
+                 gopher_port >>f
+         }
+    }
+
+    printf "\n" >>f
+    printf "[1|All Sources|%s/source/|%s|%s]\n", gopher_dir, \
+        gopher_host, gopher_port >>f
+
+    close(f)
+    return
+}
+
+function print_source_txt(source, source_id, name,    i, \
+    f, key, len, symbol)
+{
+    f = outdir "/source/" source_id "/index.txt"
+
+    printf "Source: %s\n\n", name >f
+
+    print_table(f)
+    printf "\n" >>f
+
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Source"
+         if (elements[key] == source_id) {
+             key = i "_Name"
+             name = elements[key]
+             key = i "_Symbol"
+             symbol = elements[key]
+             printf "%3d %-2s %s\n", i, symbol, name >>f
+         }
+    }
+
+    close(f)
+    return
+}
+
+function print_table(f,    col, cols, element, i, key, \
+    row, rows, sel, sel_l, sel_r, symbol)
+{
+    cols = table["cols"]
+    rows = table["rows"]
+
+    for (row = 1; row <= rows; row++) {
+        for (col = 1; col <= cols; col++) {
+            key = row "_" col
+            element = table[key]
+            sel = selection[key]
+            key = element "_Symbol"
+            symbol = sprintf("%-2s", elements[key])
+            if (sel) {
+                sub(/ /, "_", symbol)
+            }
+            if (col == 1) {
+                key = row "_" (col + 1)
+                sel_r = selection[key]
+                if (sel) {
+                    if (sel_r) {
+                        printf "[%s", symbol >>f
+                    } else {
+                        printf "[%s]", symbol >>f
+                    }
+                } else {
+                    printf " %s", symbol >>f
+                }
+            } else if (col == cols) {
+                key = row "_" (col - 1)
+                sel_l = selection[key]
+                if (sel) {
+                    if (sel_l) {
+                        printf "_%s]", symbol >>f
+                    } else {
+                        printf "[%s]", symbol >>f
+                    }
+                } else {
+                    if (sel_l) {
+                        printf "%s", symbol >>f
+                    } else {
+                        printf " %s", symbol >>f
+                    }
+                }
+            } else {
+                key = row "_" (col - 1)
+                sel_l = selection[key]
+                key = row "_" (col + 1)
+                sel_r = selection[key]
+                if (sel) {
+                    if (sel_l) {
+                        if (sel_r) {
+                            printf "_%s", symbol >>f
+                        } else {
+                            printf "_%s]", symbol >>f
+                        }
+                    } else {
+                        if (sel_r) {
+                            printf "[%s", symbol >>f
+                        } else {
+                            printf "[%s]", symbol >>f
+                        }
+                    }
+                } else {
+                    if (sel_l) {
+                        printf "%s", symbol >>f
+                    } else {
+                        printf " %s", symbol >>f
+                    }
+                }
+            }
+        }
+        printf "\n" >>f
+    }
+    return
+}
+
+function print_top(    f) {
+    f = outdir "/index.gph"
+    select_clear()
+    printf "             Periodic Table Of The Elements\n\n" >f
+    print_table(f)
+    printf "\n" >>f
+    printf "[1|List All|%s/list/atomic/|%s|%s]\n", gopher_dir,
+        gopher_host, gopher_port >>f
+    printf "[9|Code (.zip)|%s/periodic.zip|%s|%s]\n", gopher_dir,
+        gopher_host, gopher_port >>f
+    close(f)
+    return
+}
+
+function print_wrap(str, wraplen, outfile,    after, before, buf, chunk) {
+    buf = str
+    while (length(buf) > wraplen) {
+        chunk = substr(buf, 0, wraplen)
+        if (match(chunk, / [^ ]*$/)) {
+            before = substr(buf, 0, RSTART)
+            after = substr(buf, RSTART + 1)
+            print before >>outfile
+            buf = after
+       } else {
+            break
+       }
+    }
+    print buf >>outfile
+    return
+}
+
+function select_atom(element,     col, key, row) {
+    col = table_col[element]
+    row = table_row[element]
+    key = row "_" col
+    selection[key] = 1
+    return
+}
+
+function select_clear() {
+    delete selection
+    return
+}
+
+function select_family(family_id,    i, key, len) {
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Family"
+         if (elements[key] == family_id) {
+             select_atom(i)
+         }
+    }
+    return
+}
+
+function select_shell(shell_id,    i, key, len) {
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Shell"
+         if (elements[key] == shell_id) {
+             select_atom(i)
+         }
+    }
+    return
+}
+
+function select_source(source_id,    count, i, j, key, len, \
+    source_list, source)
+{
+    len = elements["length"]
+    for (i = 1; i <= len; i++) {
+         key = i "_Source"
+         source_list = elements[key]
+         count = split(source_list, source, / /)
+         for (j = 1; j <= count; j++) {
+             if (source[j] == source_id) {
+                 select_atom(i)
+             }
+         }
+    }
+    return
+}
+
+function main() {
+    gopher_dir = "/~bencollver/periodic"
+    gopher_host = "server"
+    gopher_port = "port"
+    outdir = "output"
+    csv_read("data/elements.csv", elements)
+    csv_read("data/families.csv", families)
+    csv_read("data/shells.csv", shells)
+    csv_read("data/sources.csv", sources)
+    make_source_lookup()
+    make_table()
+    print_elements()
+    print_families()
+    print_lists()
+    print_shells()
+    print_sources()
+    print_top()
+    return
+}
+
+BEGIN {
+    main()
+    exit 0
+}