My first posting to kragen-hacks, 1998-11-13, was a dumb little Perl
program I called "sideways", which turned text sideways.  In the
interest of making kragen-hacks posts easier to enjoy, I'm translating
74 of them into dynamic HTML to reduce the hassle of running them.

So here's the DHTML version of "sideways", which will eventually be at
http://pobox.com/~kragen/sw/sideways.html.

Should work in any browser that supports JavaScript and
document.getElementById.

<html><head><title>Sideways JavaScript</title>
<script type="text/javascript">

/* This approach is 38 lines in JavaScript, but was only 14 in Perl.
   The first 12 would go away if I were using MochiKit. */

function $(id) { return document.getElementById(id) }
function forEachRange(n, func) {
  for (var ii = 0; ii < n; ii++) { func(ii) }
}
function forEach(list, func) {
  forEachRange(list.length, function(ii) { func(list[ii]) })
}
function map(func, list) {
  var rv = []
  forEach(list, function(item) { rv.push(func(item)) })
  return rv
}
function perlish_flip(id) {
  var elem = $(id)
  var lines = elem.value.split('\n')
  elem.value = ''
  for (;;) {
    try {
      forEach(lines, function(line) {
        if (!line) return
        var col = map(function(_) { return (_ ? _.substr(0, 1) : ' ') },
                      lines)
        elem.value += col.join('') + '\n'
        forEachRange(lines.length, function(ii) { 
          lines[ii] = lines[ii].substr(1) 
        })
        throw "not done yet"
      })
      break
    } catch (e) { 
      if (e != 'not done yet') throw e
    }
  }
}

/* This other approach is more concise, using 12 lines of the above
 * plus 16 here for only 28 lines, still twice the length of the Perl,
 * but much more straightforward and less clever */

function max(list) {
  var rv = list[0]
  map(function(item) { if (item > rv) rv = item }, list)
  return rv
}
function numbered_flip(id) {
  var elem = $(id)
  var lines = elem.value.split('\n')
  var maxwidth = max(map(function(line) { return line.length }, lines))
  elem.value = ''
  forEachRange(maxwidth, function(col) {
    forEach(lines, function(line) { elem.value += line[col] || ' '})
    elem.value += '\n'
  })
}
v
// It would be cool to have a bookmarklet version of this code that
// worked on the currently-focused element.

flip = numbered_flip

</script>
</head>
<body>
<h1>Sideways JavaScript</h1>
<p>Swap rows with columns: <a href="javascript:flip('flipper')">flip</a>.</p>
<form>
<textarea rows="40" cols="80" id="flipper">
You are
I am
he is
she is
</textarea>
</form>
</body></html>

Reply via email to