Subsecciones


Práctica: Ficheros INI

Donde

[~/srcPLgrado/ini(develop)]$ pwd -P
/Users/casiano/local/src/javascript/PLgrado/ini
[~/srcPLgrado/ini(develop)]$ git remote -v
origin  ssh://git@bitbucket.org/casiano/pl-grado-ini-files.git (fetch)
origin  ssh://git@bitbucket.org/casiano/pl-grado-ini-files.git (push)

Véase

index.html

[~/javascript/PLgrado/ini(master)]$ cat index.html 
<html>
  <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <title>INI files</title>
     <link href="global.css" rel="stylesheet" type="text/css">
<!--
     <link rel="shortcut icon" href="logo.png" />
-->
     <link rel="shortcut icon" href="etsiiull.png" type="image/x-icon">

     <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

     <script type="text/javascript" src="ini.js"></script>
  </head>
  <body>
    <h1>INI files</h1>
    <input type="file" id="fileinput" />
    <div id="out" class="hidden">
    <table>
      <tr><th>Original</th><th>Tokens</th></tr>
      <tr>
        <td>
          <pre class="input" id="initialinput"></pre>
        </td>
        <td>
          <pre class="output" id="finaloutput"></pre>
        </td>
      </tr>
    </table>
    </div>
  </body>
</html>

Shortcut icon

     <link rel="shortcut icon" href="etsiiull.png" type="image/x-icon">

Véase Favicon en la Wikipedia

Ficheros

Vease

Fechas

Drag and Drop/Arrastra y Suelta

Propagación de Eventos

Registrando Manejadores de Eventos

Insertando Directamente una Imagen en HTML: <img src="data:image/gif;base64, ...

insertBefore

global.css

[~/javascript/PLgrado/ini(master)]$ cat global.css 
html *
{
   font-size: large; 
   /* The !important ensures that nothing can override what you've set in this style (unless it is also important). */
   font-family: Arial;
}

.thumb {
    height: 75px;
    border: 1px solid #000;
    margin: 10px 5px 0 0;
  }

h1            { text-align: center; font-size: x-large; }
th, td        { vertical-align: top; text-align: left; }   
/* #finaltable  * { color: white; background-color: black; }   */

/* #finaltable table { border-collapse:collapse; } */
/* #finaltable table, td { border:1px solid white; } */
#finaltable:hover td { background-color: blue; } 
tr:nth-child(odd)    { background-color:#eee; }
tr:nth-child(even)    { background-color:#00FF66; }
input        { text-align: right;  border: none;       }     /* Align input to the right  */
textarea     { border: outset; border-color: white;       }                        
table        { border: inset; border-color: white; }
.hidden      { display: none; }
.unhidden    { display: block; }
table.center { margin-left:auto; margin-right:auto; }
#result      { border-color: red; }
tr.error       { background-color: red; }
pre.output   { background-color: white; }
/*
span.repeated { background-color: red }
span.header { background-color: blue }
span.comments { background-color: orange }
span.blanks { background-color: green }
span.nameEqualValue { background-color: cyan }
span.error { background-color: red }
*/
body
{
 background-color:#b0c4de;  /* blue */
}

Ficheros de Prueba

~/Dropbox/src/javascript/PLgrado/ini(master)]$ cat input.ini 
; last modified 1 April 2001 by John Doe
[owner]
name=John Doe
organization=Acme Widgets Inc.

[database]
; use IP address in case network name resolution is not working
server=192.0.2.62     
port=143
file = "payroll.dat"

$ cat input2.ini 
[special_fields] 
required = "EmailAddr,FirstName,LastName,Mesg" 
csvfile = "contacts.csv" 
csvcolumns = "EmailAddr,FirstName,LastName,Mesg,Date,Time" 

[email_addresses] 
sales = "jack@yahoo.com,mary@my-sales-force.com,president@my-company.com"

$ cat inputerror.ini
[owner]
name=John Doe
organization$Acme Widgets Inc.
 
[database
; use IP address in case network name resolution is not working
server=192.0.2.62     
port=143
file = "payroll.dat"

ini.js

[~/javascript/PLgrado/ini(master)]$ cat ini.js
"use strict"; // Use ECMAScript 5 strict mode in browsers that support it

$(document).ready(function() {
   $("#fileinput").change(calculate);
});

function calculate(evt) {
  var f = evt.target.files[0]; 

  if (f) {
    var r = new FileReader();
    r.onload = function(e) { 
      var contents = e.target.result;
      
      var tokens = lexer(contents);
      var pretty = tokensToString(tokens);
      
      out.className = 'unhidden';
      initialinput.innerHTML = contents;
      finaloutput.innerHTML = pretty;
    }
    r.readAsText(f);
  } else { 
    alert("Failed to load file");
  }
}

var temp = '<li> <span class = "<%= token.type %>"> <%= match %> </span>\n';

function tokensToString(tokens) {
   var r = '';
   for(var i=0; i < tokens.length; i++) {
     var t = tokens[i]
     var s = JSON.stringify(t, undefined, 2);
     s = _.template(temp, {token: t, match: s});
     r += s;
   }
   return '<ol>\n'+r+'</ol>';
}

function lexer(input) {
  var blanks         = /^\s+/;
  var iniheader      = /^\[([^\]\r\n]+)\]/;
  var comments       = /^[;#](.*)/;
  var nameEqualValue = /^([^=;\r\n]+)=([^;\r\n]*)/;
  var any            = /^(.|\n)+/;

  var out = [];
  var m = null;

  while (input != '') {
    if (m = blanks.exec(input)) {
      input = input.substr(m.index+m[0].length);
      out.push({ type : 'blanks', match: m });
    }
    else if (m = iniheader.exec(input)) {
      input = input.substr(m.index+m[0].length);
      out.push({ type: 'header', match: m });
    }
    else if (m = comments.exec(input)) {
      input = input.substr(m.index+m[0].length);
      out.push({ type: 'comments', match: m });
    }
    else if (m = nameEqualValue.exec(input)) {
      input = input.substr(m.index+m[0].length);
      out.push({ type: 'nameEqualValue', match: m });
    }
    else if (m = any.exec(input)) {
      out.push({ type: 'error', match: m });
      input = '';
    }
    else {
      alert("Fatal Error!"+substr(input,0,20));
      input = '';
    }
  }
  return out;
}
Véase la sección JSON.stringify() 1.4 para saber mas sobre JSON.stringify.

Dudas sobre la Sintáxis del Formato INI

La sintáxis de INI no está bien definida. Se aceptan decisiones razonables para cada una de las expresiones regulares. Si quiere ver un parser en acción puede instalar la gema inifile (Ruby).

Una opción que no hemos contemplado en nuestro código es la posibilidad de hacer que una línea de asignación se expanda en varias líneas. En inifile el carácter \ indica que la línea continúa en la siguiente:

[~/javascript/PLgrado/inifile(master)]$ cat test/data/good.ini 
[section_one]
one = 1
two = 2

[section_two]
three =         3
multi = multiline \
support

; comments should be ignored
[section three]
four   =4
five=5
six =6

[section_four]
   [section_five]
 seven and eight= 7 & 8

[~/javascript/PLgrado/inifile(master)]$ pry
[2] pry(main)> require 'inifile'
=> true
[3] pry(main)> p = IniFile.new(:filename => 'test/data/good.ini')
=> #<IniFile:0x007fba2f41a500
 @_line=" seven and eight= 7 & 8",
 @_section={"seven and eight"=>"7 & 8"},
 @comment=";#",
 @content=
  "[section_one]\none = 1\ntwo = 2\n\n[section_two]\nthree =         3\nmulti = multiline \\\nsupport\n\n; comments should be ignored\n[section three]\nfour   =4\nfive=5\nsix =6\n\n[section_four]\n   [section_five]\n seven and eight= 7 & 8\n\n",
 @default="global",
 @encoding=nil,
 @escape=true,
 @filename="test/data/good.ini",
 @ini=
  {"section_one"=>{"one"=>"1", "two"=>"2"},
   "section_two"=>{"three"=>"3", "multi"=>"multiline support"},
   "section three"=>{"four"=>"4", "five"=>"5", "six"=>"6"},
   "section_four"=>{},
   "section_five"=>{"seven and eight"=>"7 & 8"}},
 @param="=">

[4] pry(main)> p["section_two"]
=> {"three"=>"3", "multi"=>"multiline support"}
[5] pry(main)> p[:section_two]

Tareas

Es conveniente que consiga estos objetivos:

Véase

  1. JSON.stringify
  2. www.json.org
  3. JSON in JavaScript
  4. Underscore: template
  5. Stackoverflow::how to use Underscore template

Casiano Rodríguez León
2016-03-27