Marcus Rohrmoser 1 month ago
parent
commit
19b16df0b3

+ 24 - 20
content/posts/2010-06-14-simple-http-access-authorisation.md

@@ -5,34 +5,38 @@ type: post
 date: 2010-06-14T09:56:46+00:00
 url: /2010/06/simple-http-access-authorisation/
 yourls_shorturl:
-  - http://s.mro.name/27
-
+- http://s.mro.name/27
 categories:
-  - sysadmin
+- en
+- sysadmin
 tags:
-  - apache
-  - authentication
-  - authorisation
-  - Basic Authentication
-  - Cram
-  - htaccess
-  - HTTPS
-  - mod_rewrite
-  - rest
-  - restful
-  - RewriteCond
-  - RewriteRule
+- apache
+- authentication
+- authorisation
+- Basic Authentication
+- Cram
+- htaccess
+- HTTPS
+- mod_rewrite
+- rest
+- restful
+- RewriteCond
+- RewriteRule
 
 ---
 sometimes you may want to lock down [RESTful APIs][1] or plain HTTP GET resources for [authorised access][2] by your own client software only, without requiring [authentication][3]. You don't know who (not authenticated), but you know she may access (is authorised).
 
 If the server has a valid [SSL certificate][4] based on a root certificate pre-installed on the iPhone among the simplest ways to do it are:
 
-  * [HTTP Basic Authentication][5] with static username + password. This requires just a [`.htaccess` configuration setting][6] and you're done.
-  * send a custom [HTTP Request Header][7] with a secret token, also just a `<a href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html">.htaccess</a>` [rewrite][8] setting required: <pre lang="htaccess">RewriteEngine On
-RewriteCond %{HTTP:My-Secret-Token} !=WRdsWXwwTZjEIRrgD5tODVf0U
-RewriteRule ^.*$ - [forbidden,last]
-# Test: $  curl --header "My-Secret-Token:WRdsWXwwTZjEIRrgD5tODVf0U" http://myserver.example.com/demo/</pre>
+* [HTTP Basic Authentication][5] with static username + password. This requires just a [`.htaccess` configuration setting][6] and you're done.
+* send a custom [HTTP Request Header][7] with a secret token, also just a [`.htaccess`](http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html) [rewrite][8] setting required:
+
+```apache
+RewriteEngine On
+RewriteCond %{HTTP:My-Secret-Token} !=WRdsWXwwTZjEIRrgD5tODVf0U
+RewriteRule ^.*$ - [forbidden,last]
+# Test: $  curl --header "My-Secret-Token:WRdsWXwwTZjEIRrgD5tODVf0U" http://myserver.example.com/demo/
+```
 
 Decompiling an App may raise the bar high enough though hard-coded secrets surely aren't bulletproof Secret Service grade quality. If you don't want the password or secret token as literal string inside the App, synthesize it at runtime.
 

+ 83 - 79
content/posts/2010-08-15-visualise-macports-dependencies.md

@@ -5,98 +5,102 @@ type: post
 date: 2010-08-15T16:12:04+00:00
 url: /2010/08/visualise-macports-dependencies/
 yourls_shorturl:
-  - http://s.mro.name/1e
-
+- http://s.mro.name/1e
 categories:
-  - sysadmin
+- en
+- sysadmin
 tags:
-  - Graphviz
-  - MacPorts
-  - OS X
-  - Ruby
+- Graphviz
+- MacPorts
+- OS X
+- Ruby
 
 ---
-to clean up your installed macports and remove cruft you need to uninstall them in the correct order &#8211; according to their dependencies.
+to clean up your installed macports and remove cruft you need to uninstall them in the correct order  according to their dependencies.
 
 A graphical visualisation might help doing so:
 
-[<img class="aligncenter size-medium wp-image-1928" title="port-deps" src="http://blog.mro.name/wp-content/uploads/2010/08/port-deps-188x300.png" alt="" width="188" height="300" srcset="http://blog.mro.name/wp-content/uploads/2010/08/port-deps-188x300.png 188w, http://blog.mro.name/wp-content/uploads/2010/08/port-deps-644x1024.png 644w" sizes="(max-width: 188px) 100vw, 188px" />][1]
+{{< figure  src="/wp-content/uploads/2010/08/port-deps-644x1024.png" caption="port-deps"  width="188"  height="300" >}}
 
 Call
 
-<pre lang="bash">$ ./port-deps2dot.rb | dot -Tpdf -o port-deps.pdf ; open port-deps.pdf</pre>
+```bash
+$ ./port-deps2dot.rb | dot -Tpdf -o port-deps.pdf ; open port-deps.pdf
+```
 
 with the ruby script [`port-deps2dot.rb` (github gist)][2] as follows:
 
-<pre lang="ruby" line="1">#!/usr/bin/ruby -w
-
-# visualize macports dependencies.
-# pipe the result through graphviz, e.g.
-# $ ./port-deps2dot.rb | dot -Tpdf -o port-deps.pdf ; open port-deps.pdf
-
-def scan_deps
-	pat = /^([^:]+):(.+)$/
-	name = ''
-	deps = []
-	IO.popen('port info --name --pretty --depends installed') do |f|
-		f.each_line do |l|
-			case l
-				when /^--$/
-					yield name, deps
-					name = ''
-					deps = []
-				when /^([^:]+):(.+)$/
-					if 'name' == "#$1"
-						name = "#$2".strip
-					else
-						deps.concat("#$2".split(/\s*,\s*/))
-					end
-				else
-					raise "Fall-through for '#{l}'"
-			end
-		end
-	end
-end
-
-all = {}
-
-scan_deps do |name,deps|
-	d = all[name]
-	all[name] = d = [] if d.nil?
-	deps.collect! {|i| i.strip}
-	d.concat deps
-	d.sort!
-	d.uniq!
-end
-
-head = &lt; &lt;END_OF_STRING
-#!/usr/bin/dot -Tpdf -o port-deps.pdf
-/*
-	See http://www.graphviz.org/Documentation.php
-*/
-digraph "port deps" {
-	rankdir=LR;
-    label="port deps";
-    node [style=filled,fillcolor=lightblue,shape=ellipse];
-    top_level [shape=point];
-END_OF_STRING
-
-puts head
-
-all.keys.sort.each do |name|
-	deps = all[name]
-	if deps.count > 0
-		deps.each {|d| puts "\t\"#{name}\" -> \"#{d}\";" }
-	else
-		puts "\t\"#{name}\";"
-	end
-end
-
-foot = &lt; &lt;END_OF_STRING
-}
-END_OF_STRING
-
-puts foot</pre>
+```ruby
+#!/usr/bin/ruby -w
+
+# visualize macports dependencies.
+# pipe the result through graphviz, e.g.
+# $ ./port-deps2dot.rb | dot -Tpdf -o port-deps.pdf ; open port-deps.pdf
+
+def scan_deps
+  pat = /^([^:]+):(.+)$/
+  name = ''
+  deps = []
+  IO.popen('port info --name --pretty --depends installed') do |f|
+    f.each_line do |l|
+      case l
+        when /^--$/
+          yield name, deps
+          name = ''
+          deps = []
+        when /^([^:]+):(.+)$/
+          if 'name' == "#$1"
+            name = "#$2".strip
+          else
+            deps.concat("#$2".split(/\s*,\s*/))
+          end
+        else
+          raise "Fall-through for '#{l}'"
+      end
+    end
+  end
+end
+
+all = {}
+
+scan_deps do |name,deps|
+  d = all[name]
+  all[name] = d = [] if d.nil?
+  deps.collect! {|i| i.strip}
+  d.concat deps
+  d.sort!
+  d.uniq!
+end
+
+head = <<END_OF_STRING
+#!/usr/bin/dot -Tpdf -o port-deps.pdf
+/*
+  See http://www.graphviz.org/Documentation.php
+*/
+digraph "port deps" {
+  rankdir=LR;
+    label="port deps";
+    node [style=filled,fillcolor=lightblue,shape=ellipse];
+    top_level [shape=point];
+END_OF_STRING
+
+puts head
+
+all.keys.sort.each do |name|
+  deps = all[name]
+  if deps.count > 0
+    deps.each {|d| puts "\t\"#{name}\" -> \"#{d}\";" }
+  else
+    puts "\t\"#{name}\";"
+  end
+end
+
+foot = <<END_OF_STRING
+}
+END_OF_STRING
+
+puts foot
+```
 
  [1]: http://blog.mro.name/wp-content/uploads/2010/08/port-deps.png
  [2]: https://gist.github.com/794713

+ 33 - 33
content/posts/2010-10-22-high-res-artwork-management-automation.md

@@ -5,46 +5,46 @@ type: post
 date: 2010-10-22T10:17:23+00:00
 url: /2010/10/high-res-artwork-management-automation/
 yourls_shorturl:
-  - http://s.mro.name/g
-
-language: en
+- http://s.mro.name/g
 categories:
-  - development
+- en
+- development
 tags:
-  - ImageMagick
-  - iPhone
-  - iPhone4
-  - make
-  - Makefile
-  - Retina Display
+- ImageMagick
+- iPhone
+- iPhone4
+- make
+- Makefile
+- Retina Display
 
 ---
-The iPhone4 comes with a [super high-res display][1] and to leverage that encourages App Developers to provide all artwork twofold &#8211; once &#8222;normal&#8220; and once in double resolution named equally with a &#8222;`@2x`&#8220; suffix.
+The iPhone4 comes with a [super high-res display][1] and to leverage that encourages App Developers to provide all artwork twofold  once &#8222;normal&#8220; and once in double resolution named equally with a &#8222;`@2x`&#8220; suffix.
 
 To ease my designers' life and avoid confusion (and designers are easily confused I found) I ask them to provide the high-res artwork only and I scale it down myself. And as this is a reoccuring task, I automated via a [Makefile][2] like this:
 
-<pre lang="make" line="1">#!/usr/bin/make
-# Make help: http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
-
-# Requires ImageMagick, Installation per macport: $ sudo port install imagemagick +no_x11
-CONVERT	:=	convert
-
-# Where are the images?
-ASSETS_DIR := .
-
-# Which ones? All @2x.png plus twins without @2x.png
-ASSETS_HIGH	:=	$(wildcard $(ASSETS_DIR)/*@2x.png)
-ASSETS_LOW	:=	$(patsubst %@2x.png,%.png,$(ASSETS_HIGH))
-
-# The scaling command
-%.png: %@2x.png
-	convert $&lt; -resize 50% $@
-
-assets: $(ASSETS_LOW)
-
-clean:
-	-rm $(ASSETS_LOW)
-</pre>
+```make
+#!/usr/bin/make
+# Make help: http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
+
+# Requires ImageMagick, Installation per macport: $ sudo port install imagemagick +no_x11
+CONVERT :=  convert
+
+# Where are the images?
+ASSETS_DIR := .
+
+# Which ones? All @2x.png plus twins without @2x.png
+ASSETS_HIGH :=  $(wildcard $(ASSETS_DIR)/*@2x.png)
+ASSETS_LOW  :=  $(patsubst %@2x.png,%.png,$(ASSETS_HIGH))
+
+# The scaling command
+%.png: %@2x.png
+  convert $< -resize 50% $@
+
+assets: $(ASSETS_LOW)
+
+clean:
+  -rm $(ASSETS_LOW)
+```
 
 See also my [link collection about high-res images][3] and my [general Xcode project setup][4].
 

+ 51 - 50
content/posts/2010-11-08-high-res-uiimage-remote-load.md

@@ -5,63 +5,64 @@ type: post
 date: 2010-11-08T10:10:12+00:00
 url: /2010/11/high-res-uiimage-remote-load/
 yourls_shorturl:
-  - http://s.mro.name/3q
-
-language: en
+- http://s.mro.name/3q
 categories:
-  - development
+- en
+- development
 tags:
-  - Cocoa
-  - Image
-  - iPhone
-  - iPhone4
-  - Retina Display
-  - UIImage
+- Cocoa
+- Image
+- iPhone
+- iPhone4
+- Retina Display
+- UIImage
 
 ---
-Loading [<tt>UIImage</tt>s automatically in high-resolution][1] works fine for locally stored images &#8211; but if you want to fetch them via remote URL you have to code yourself.
+Loading [<tt>UIImage</tt>s automatically in high-resolution][1] works fine for locally stored images  but if you want to fetch them via remote URL you have to code yourself.
 
 A simple, blocking but backward compatible (iOS >= 3.0, maybe even 2.0 but untested)  implementation could look like this:
 
-<pre lang="objc" line="1">@implementation UIImage (MRORemote)
-
-// add the @2x filename suffix
-+(NSURL *)url2x:(NSURL *)url
-{
-  NSString *path = url.path;
-  NSAssert(path != nil, @"");
-  NSString *last = path.lastPathComponent;
-  NSString *ext = path.pathExtension;
-  NSAssert(last != nil, @"");
-  NSAssert(ext != nil, @"");
-  NSString *part = [last substringToIndex:MAX(0, last.length - ext.length - 1)];
-  return [NSURL URLWithString:[NSString stringWithFormat:@"%@@2x.%@", part, ext] relativeToURL:[url absoluteURL]];
-}
-
-+(UIImage *)imageWithContentsOfURL:(NSURL *)url probe2x:(BOOL)probe2x
-{
-  if ( url == nil )
-    return nil;
-  UIScreen *screen = [UIScreen mainScreen];
-  const CGFloat scale = [screen respondsToSelector:@selector(scale)] ? [screen scale] : 1.0f;
-  if ( probe2x && 2.0f == scale && [UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)] ) {
-    UIImage *img = nil;
-    NSData *raw = [NSData dataWithContentsOfURL:[UIImage url2x:url]];
-    if ( raw != nil )
-      img = [UIImage imageWithData:raw];
-    if ( img != nil )
-      img = [UIImage imageWithCGImage:img.CGImage scale:scale orientation:img.imageOrientation];
-    if ( img != nil )
-      return img;
-    NSAssert(raw == nil && img == nil, @"");
-  }
-  // MRLogD(@"loading %@", [url absoluteURL]);
-  NSData *raw = [NSData dataWithContentsOfURL:url];
-  if ( raw == nil )
-    return nil;
-  return [UIImage imageWithData:raw];
-}
-@end</pre>
+```objc
+@implementation UIImage (MRORemote)
+
+// add the @2x filename suffix
++(NSURL *)url2x:(NSURL *)url
+{
+  NSString *path = url.path;
+  NSAssert(path != nil, @"");
+  NSString *last = path.lastPathComponent;
+  NSString *ext = path.pathExtension;
+  NSAssert(last != nil, @"");
+  NSAssert(ext != nil, @"");
+  NSString *part = [last substringToIndex:MAX(0, last.length - ext.length - 1)];
+  return [NSURL URLWithString:[NSString stringWithFormat:@"%@@2x.%@", part, ext] relativeToURL:[url absoluteURL]];
+}
+
++(UIImage *)imageWithContentsOfURL:(NSURL *)url probe2x:(BOOL)probe2x
+{
+  if ( url == nil )
+    return nil;
+  UIScreen *screen = [UIScreen mainScreen];
+  const CGFloat scale = [screen respondsToSelector:@selector(scale)] ? [screen scale] : 1.0f;
+  if ( probe2x && 2.0f == scale && [UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)] ) {
+    UIImage *img = nil;
+    NSData *raw = [NSData dataWithContentsOfURL:[UIImage url2x:url]];
+    if ( raw != nil )
+      img = [UIImage imageWithData:raw];
+    if ( img != nil )
+      img = [UIImage imageWithCGImage:img.CGImage scale:scale orientation:img.imageOrientation];
+    if ( img != nil )
+      return img;
+    NSAssert(raw == nil && img == nil, @"");
+  }
+  // MRLogD(@"loading %@", [url absoluteURL]);
+  NSData *raw = [NSData dataWithContentsOfURL:url];
+  if ( raw == nil )
+    return nil;
+  return [UIImage imageWithData:raw];
+}
+@end
+```
 
 Use at your will but without any warranty.
 

+ 10 - 4
content/posts/2011-01-13-alcocalc-iphone-app-online.md

@@ -20,13 +20,19 @@ tags:
   - Widmark Formel
 
 ---
-Hurra! Vor einigen Tagen ist die erste Version des Promillerechners im [<img class="size-full wp-image-2113 alignnone" style="vertical-align: middle;" title="AlcoCalc App Store Link" src="http://blog.mro.name/wp-content/uploads/2011/01/appstore.png" alt="AlcoCalc App Store Link" width="116" height="40" />][1] erschienen. Die App merkt sich was Du wann getrunken hast und schätzt nach der [Widmark Formel][2] grob den aktuellen und fallenden Promillewert ab:
+Hurra! Vor einigen Tagen ist die erste Version des Promillerechners im 
 
-[<img class="aligncenter size-medium wp-image-2110" title="Promillekurve" src="http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.curve_-300x200.png" alt="" width="300" height="200" srcset="http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.curve_-300x200.png 300w, http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.curve_.png 960w" sizes="(max-width: 300px) 100vw, 300px" />][3]
+{{< figure src="/wp-content/uploads/2011/01/appstore.png" caption="AlcoCalc App Store Link" width="116" height="40" >}}
 
-[][3][<img class="size-medium wp-image-2111 aligncenter" title="Getrunkenes" src="http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.drinks-200x300.png" alt="" width="200" height="300" srcset="http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.drinks-200x300.png 200w, http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.drinks.png 640w" sizes="(max-width: 200px) 100vw, 200px" />][4][][5]
+{{< figure src="/wp-content/uploads/2011/01/alcocalc.curve_-300x200.png" caption="Promillekurve" width="300" height="200" >}}
 
-[<img class="size-medium wp-image-2112 aligncenter" title="Getränk anlegen" src="http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.edit_-200x300.png" alt="" width="200" height="300" srcset="http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.edit_-200x300.png 200w, http://blog.mro.name/wp-content/uploads/2011/01/alcocalc.edit_.png 640w" sizes="(max-width: 200px) 100vw, 200px" />][5]
+erschienen. Die App merkt sich was Du wann getrunken hast und schätzt nach der [Widmark Formel][2] grob den aktuellen und fallenden Promillewert ab:
+ 
+{{< figure  src="/wp-content/uploads/2011/01/alcocalc.curve_-300x200.png" caption="Promillekurve"  width="300"  height="200" >}}
+
+{{< figure  src="/wp-content/uploads/2011/01/alcocalc.drinks-200x300.png" caption="Getrunkenes"  width="200"  height="300" >}}
+
+{{< figure  src="/wp-content/uploads/2011/01/alcocalc.edit_-200x300.png" caption="Getränk anlegen"  width="200"  height="300" >}}
 
 .
 

+ 99 - 98
content/posts/2011-04-05-simple-ruby-fast-fourier-transform.md

@@ -5,21 +5,20 @@ type: post
 date: 2011-04-05T00:07:33+00:00
 url: /2011/04/simple-ruby-fast-fourier-transform/
 yourls_shorturl:
-  - http://mro.name/47
+- http://mro.name/47
 yourls_tweeted:
-  - 1
-
-language: en
+- 1
 categories:
-  - development
+- en
+- development
 tags:
-  - DFT
-  - DSP
-  - FFT
-  - Fourier
-  - Math
-  - Ruby
-  - Transform
+- DFT
+- DSP
+- FFT
+- Fourier
+- Math
+- Ruby
+- Transform
 
 ---
 by far not as powerful as the [Fastest Fourier Transform in the West][1] but maybe sometimes useful for a quick data analysis or de-noising. Reads stdin and writes to stdout.
@@ -28,92 +27,94 @@ Algorithm taken from [Meyberg, Vachenauer: Höhere Mathematik II][2] and ported
 
 <!--more-->
 
-<pre lang="ruby" line="1">#!/usr/bin/env ruby
-require 'complex'
-
-class Array
-  # DFT and inverse.
-  # 
-  # Algorithm from 
-  # 'Meyberg, Vachenauer: Hoehere Mathematik II, Springer Berlin, 1991, page 332'
-  #
-  # See http://blog.mro.name/2011/04/simple-ruby-fast-fourier-transform/ 
-  #
-  def fft doinverse = false
-    src = self
-    # raise ArgumentError.new "Expected array input but was '#{src.class}'" unless src.kind_of? Array
-    n = src.length
-    nlog2 = Math.log( n ) / Math.log( 2 )
-    raise ArgumentError.new "Input array size must be a power of two but was '#{n}'" unless nlog2.floor - nlog2 == 0.0
-    n2 = n / 2
-    phi = Math::PI / n2
-    if doinverse
-      phi = -phi
-    else
-      src.collect!{|c| c /= n.to_f}
-    end
-
-    # build a sine/cosine table
-    wt = Array.new n2
-    wt.each_index { |i| wt[i] = Complex.new Math.cos(i * phi), Math.sin(i * phi) }
-
-    # bit reordering
-    n1 = n - 1
-    j = 0
-    1.upto(n1) do |i|
-      m = n2
-      while j &gt;= m
-        j -= m
-        m /= 2
-      end
-      j += m
-      src[i],src[j] = src[j],src[i] if j &gt; i
-    end
-
-    # 1d(N) Ueberlagerungen
-    mm = 1
-    begin
-      m = mm
-      mm *= 2
-      0.upto(m - 1) do |k|
-        w = wt[ k * n2 ]
-        k.step(n1, mm) do |i|
-          j = i + m
-          src[j] = src[i] - (temp = w * src[j])
-          src[i] += temp
-        end
-      end
-      n2 /= 2
-    end while mm != n
-    src
-  end
-end
-
-class String
-  # parse Complex.new.to_s
-  def to_c
-    m = @@PATTERN.match self
-    return nil if m.nil?
-    Complex.new m[1].to_f, m[2].to_f
-  end
-private
-  # float_pat = /(-?\d+(?:\.\d+)?(?:e[+-]?\d+)?)/
-  @@PATTERN = /^[ \t\r\n]*(-?\d+(?:\.\d+)?(?:e[+-]?\d+)?)?\s*((?:\s+|[+-])\d+(?:\.\d+)?(?:e[+-]?\d+)?i)?[ \t\r\n]*$/
-end
-
-values = []
-$stdin.each_line do |l|
-  c = l.to_c
-  if c.nil?
-    $stderr.puts "unmatched '#{l}'"
-  else
-    values &lt;&lt; c
-  end
-end
-INVERSE = ARGV[0] == 'inverse'
-$stderr.puts INVERSE ? 'inverse' : 'forward'
-
-values.fft(INVERSE).each {|i| puts "#{i.real} #{i.image}i"}</pre>
+```ruby
+#!/usr/bin/env ruby
+require 'complex'
+
+class Array
+  # DFT and inverse.
+  # 
+  # Algorithm from 
+  # 'Meyberg, Vachenauer: Hoehere Mathematik II, Springer Berlin, 1991, page 332'
+  #
+  # See http://blog.mro.name/2011/04/simple-ruby-fast-fourier-transform/ 
+  #
+  def fft doinverse = false
+    src = self
+    # raise ArgumentError.new "Expected array input but was '#{src.class}'" unless src.kind_of? Array
+    n = src.length
+    nlog2 = Math.log( n ) / Math.log( 2 )
+    raise ArgumentError.new "Input array size must be a power of two but was '#{n}'" unless nlog2.floor - nlog2 == 0.0
+    n2 = n / 2
+    phi = Math::PI / n2
+    if doinverse
+      phi = -phi
+    else
+      src.collect!{|c| c /= n.to_f}
+    end
+
+    # build a sine/cosine table
+    wt = Array.new n2
+    wt.each_index { |i| wt[i] = Complex.new Math.cos(i * phi), Math.sin(i * phi) }
+
+    # bit reordering
+    n1 = n - 1
+    j = 0
+    1.upto(n1) do |i|
+      m = n2
+      while j >= m
+        j -= m
+        m /= 2
+      end
+      j += m
+      src[i],src[j] = src[j],src[i] if j > i
+    end
+
+    # 1d(N) Ueberlagerungen
+    mm = 1
+    begin
+      m = mm
+      mm *= 2
+      0.upto(m - 1) do |k|
+        w = wt[ k * n2 ]
+        k.step(n1, mm) do |i|
+          j = i + m
+          src[j] = src[i] - (temp = w * src[j])
+          src[i] += temp
+        end
+      end
+      n2 /= 2
+    end while mm != n
+    src
+  end
+end
+
+class String
+  # parse Complex.new.to_s
+  def to_c
+    m = @@PATTERN.match self
+    return nil if m.nil?
+    Complex.new m[1].to_f, m[2].to_f
+  end
+private
+  # float_pat = /(-?\d+(?:\.\d+)?(?:e[+-]?\d+)?)/
+  @@PATTERN = /^[ \t\r\n]*(-?\d+(?:\.\d+)?(?:e[+-]?\d+)?)?\s*((?:\s+|[+-])\d+(?:\.\d+)?(?:e[+-]?\d+)?i)?[ \t\r\n]*$/
+end
+
+values = []
+$stdin.each_line do |l|
+  c = l.to_c
+  if c.nil?
+    $stderr.puts "unmatched '#{l}'"
+  else
+    values << c
+  end
+end
+INVERSE = ARGV[0] == 'inverse'
+$stderr.puts INVERSE ? 'inverse' : 'forward'
+
+values.fft(INVERSE).each {|i| puts "#{i.real} #{i.image}i"}
+```
 
 WordPress messes up the angle brackets as usual, but there's [a gist for that][3].
 

+ 51 - 50
content/posts/2013-12-05-catch-javascript-exceptions-in-uiwebviewstringbyevaluatingjavascriptfromstring.md

@@ -5,62 +5,63 @@ type: post
 date: 2013-12-05T14:37:10+00:00
 url: /2013/12/catch-javascript-exceptions-in-uiwebviewstringbyevaluatingjavascriptfromstring/
 yourls_shorturl:
-  - http://mro.name/4j
-
-language: en
+- http://mro.name/4j
 categories:
-  - development
+- en
+- development
 tags:
-  - Catch
-  - Cocoa
-  - Exception
-  - iOS
-  - JavaScript
-  - NSError
-  - Objective C
-  - stringByEvaluatingJavaScriptFromString
-  - Throw
-  - UIWebView
+- Catch
+- Cocoa
+- Exception
+- iOS
+- JavaScript
+- NSError
+- Objective C
+- stringByEvaluatingJavaScriptFromString
+- Throw
+- UIWebView
 
 ---
 A small but useful category method on [UIWebView][1]: Turn uncaught JavaScript Exception into a [NSError][2]!
 
-<pre lang="objc">//
-// Created by Marcus Rohrmoser on 05.12.13.
-// Copyright (c) 2013 Marcus Rohrmoser mobile Software. All rights reserved.
-//
-
-#import "UIWebView+JavaScriptNSError.h"
-
-#define NSERROR_UIWEBVIEW_SCRIPT @"NSERROR_UIWEBVIEW_SCRIPT"
-#define NSERROR_UIWEBVIEW_SCRIPT_CODE 1
-
-@implementation UIWebView(JavaScriptNSError)
-
--(NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script error:(NSError * __autoreleasing *)error
-{
-  NSString *errorPrefix = NSERROR_UIWEBVIEW_SCRIPT;
-  NSString *exec = [NSString stringWithFormat:@"try { %@ } catch (e) { '%@' + e; }", script, errorPrefix, nil];
-  NSString *ret = [self stringByEvaluatingJavaScriptFromString:exec];
-
-  if( ![ret hasPrefix:errorPrefix] )
-    return ret;
-
-  if( error ) {
-    NSString *msg = [ret substringFromIndex:errorPrefix.length];
-    NSDictionary *ui = @ {
-      NSLocalizedDescriptionKey: msg,
-      NSFilePathErrorKey:[self.request.URL absoluteString],
-      NSURLErrorKey: self.request.URL,
-      NSLocalizedFailureReasonErrorKey: msg,
-      NSURLErrorFailingURLErrorKey: self.request.URL,
-      NSURLErrorFailingURLStringErrorKey: self.request.URL
-    };
-    *error = [NSError errorWithDomain:NSERROR_UIWEBVIEW_SCRIPT code:NSERROR_UIWEBVIEW_SCRIPT_CODE userInfo:ui];
-  }
-  return nil;
-}
-@end</pre>
+```objc
+//
+// Created by Marcus Rohrmoser on 05.12.13.
+// Copyright (c) 2013 Marcus Rohrmoser mobile Software. All rights reserved.
+//
+
+#import "UIWebView+JavaScriptNSError.h"
+
+#define NSERROR_UIWEBVIEW_SCRIPT @"NSERROR_UIWEBVIEW_SCRIPT"
+#define NSERROR_UIWEBVIEW_SCRIPT_CODE 1
+
+@implementation UIWebView(JavaScriptNSError)
+
+-(NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script error:(NSError * __autoreleasing *)error
+{
+  NSString *errorPrefix = NSERROR_UIWEBVIEW_SCRIPT;
+  NSString *exec = [NSString stringWithFormat:@"try { %@ } catch (e) { '%@' + e; }", script, errorPrefix, nil];
+  NSString *ret = [self stringByEvaluatingJavaScriptFromString:exec];
+
+  if( ![ret hasPrefix:errorPrefix] )
+    return ret;
+
+  if( error ) {
+    NSString *msg = [ret substringFromIndex:errorPrefix.length];
+    NSDictionary *ui = @ {
+      NSLocalizedDescriptionKey: msg,
+      NSFilePathErrorKey:[self.request.URL absoluteString],
+      NSURLErrorKey: self.request.URL,
+      NSLocalizedFailureReasonErrorKey: msg,
+      NSURLErrorFailingURLErrorKey: self.request.URL,
+      NSURLErrorFailingURLStringErrorKey: self.request.URL
+    };
+    *error = [NSError errorWithDomain:NSERROR_UIWEBVIEW_SCRIPT code:NSERROR_UIWEBVIEW_SCRIPT_CODE userInfo:ui];
+  }
+  return nil;
+}
+@end
+```
 
  [1]: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIWebView_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006950-CH3-SW21
  [2]: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/Reference/Reference.html

+ 26 - 26
content/posts/2014-06-20-ad-blocking-proxy-abloprox.md

@@ -5,41 +5,41 @@ type: post
 date: 2014-06-20T21:43:43+00:00
 url: /2014/06/ad-blocking-proxy-abloprox/
 yourls_shorturl:
-  - http://mro.name/4o
-
-language: en
+- http://mro.name/4o
 categories:
-  - sysadmin
+- en
+- sysadmin
 tags:
-  - Adblock
-  - Android
-  - PAC
-  - Proxy
-  - raspi
-  - Ruby
+- Adblock
+- Android
+- PAC
+- Proxy
+- raspi
+- Ruby
 
 ---
 as an act of digital hygiene, I installed [abloprox][1] on a raspi and added this [PAC][2] file to save some keystrokes when configuring:
 
-<pre lang="javascript">function FindProxyForURL(url, host) {
-  if (shExpMatch(host,"*.fritz.box")) return "DIRECT";
-  if (shExpMatch(host,"*.local")) return "DIRECT";
-  if (shExpMatch(host,"*.akamaistream.net")) return "DIRECT";
-  if (shExpMatch(host,"*.m945.mwn.de")) return "DIRECT";
-  // auto config:
-  // 1. ensure there's a host 'wpad' in the current network, see
-  //   - https://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol#Context
-  //   - http://fritz.box/net/network_user_devices.lua
-  // 2. have a http webserver running on that host
-  // 3. ensure http://wpad/wpad.dat or http://wpad.fritz.box/wpad.dat contains a PAC file like in http://blog.mro.name/2014/06/ad-blocking-proxy-abloprox/
-  // return "PROXY wpad:3126"; // Default return condition is the proxy on host 'wpad'.
-  return "PROXY &lt;hostname_of_the_raspi&gt;:3126"; // Default return condition is the proxy.
-}
-</pre>
+```javascript
+function FindProxyForURL(url, host) {
+  if (shExpMatch(host,"*.fritz.box")) return "DIRECT";
+  if (shExpMatch(host,"*.local")) return "DIRECT";
+  if (shExpMatch(host,"*.akamaistream.net")) return "DIRECT";
+  if (shExpMatch(host,"*.m945.mwn.de")) return "DIRECT";
+  // auto config:
+  // 1. ensure there's a host 'wpad' in the current network, see
+  //   - https://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol#Context
+  //   - http://fritz.box/net/network_user_devices.lua
+  // 2. have a http webserver running on that host
+  // 3. ensure http://wpad/wpad.dat or http://wpad.fritz.box/wpad.dat contains a PAC file like in http://blog.mro.name/2014/06/ad-blocking-proxy-abloprox/
+  // return "PROXY wpad:3126"; // Default return condition is the proxy on host 'wpad'.
+  return "PROXY <hostname_of_the_raspi>:3126"; // Default return condition is the proxy.
+}
+```
 
 **Update**: I pushed this one step further recently and use the automatic proxy-configuration itself to filter — see <http://purl.mro.name/wpad>.
 
-**Update:** hu &#8211; it took [Android until version 5.0 (lollipop) to support PAC][3].
+**Update:** hu  it took [Android until version 5.0 (lollipop) to support PAC][3].
 
  [1]: https://github.com/sononum/abloprox/
  [2]: https://en.wikipedia.org/wiki/Proxy_auto-config#The_PAC_File

+ 32 - 30
content/posts/2015-04-20-lua-timezones-by-name.md

@@ -5,40 +5,41 @@ type: post
 date: 2015-04-20T06:42:36+00:00
 url: /2015/04/lua-timezones-by-name/
 yourls_fetching:
-  - 1
-
-language: en
+- 1
 categories:
-  - development
+- en
+- development
 tags:
-  - ISO8601
-  - lua
-  - TimeZone
-  - W3C
+- ISO8601
+- lua
+- TimeZone
+- W3C
 
 ---
 A bit hard to puzzle due to scarce documentation.
 
-<pre lang="lua">#!/usr/bin/env lua
-local luatz = require 'luatz' -- https://github.com/daurnimator/luatz/
-
-local tz_name = 'Europe/Berlin'
-local ts_loc = luatz.time({year=2014, month=12, day=31, hour=23, min=59})
-
-local function tz_off_iso8601(tz_offset_seconds)
-  local separator = '' -- 8601 %z compliant
-  -- separator = ':' -- 8601 W3C compliant http://www.w3.org/TR/xmlschema-2/#dateTime-timezones
-  local tz_offset_minutes = tz_offset_seconds / 60
-  local sign = string.byte('+')
-  if tz_offset_minutes &lt; 0 then sign = string.byte('-') end
-  return string.format('%c%02d%s%02d', sign, tz_offset_minutes / 60, separator, tz_offset_minutes % 60)
-end
-
-local tzi = assert(luatz.get_tz( tz_name ), 'No such timezone: \''..tz_name..'\'')
-local ts_utc = tzi:utctime ( ts_loc )
-local t_loc = luatz.timetable.new_from_timestamp( ts_loc )
-local t_utc = luatz.timetable.new_from_timestamp( ts_utc )
-
-print( t_loc:strftime('%F %T'), tz_off_iso8601(tzi:find_current( ts_utc ).gmtoff), tz_name )
-print( t_utc:strftime('%F %T'), tz_off_iso8601(0), 'UTC' )</pre>
+```lua
+#!/usr/bin/env lua
+local luatz = require 'luatz' -- https://github.com/daurnimator/luatz/
+
+local tz_name = 'Europe/Berlin'
+local ts_loc = luatz.time({year=2014, month=12, day=31, hour=23, min=59})
+
+-- %z isn't supported yet: https://github.com/daurnimator/luatz/blob/523b2e0f1ece77c569f6db4c040886ed3124512e/luatz/strftime.lua#L178
+local function tz_off_iso8601(tz_offset_seconds)
+  local separator = '' -- 8601 %z compliant
+  -- separator = ':' -- 8601 W3C compliant http://www.w3.org/TR/xmlschema-2/#dateTime-timezones
+  local tz_offset_minutes = tz_offset_seconds / 60
+  local sign = string.byte('+')
+  if tz_offset_minutes < 0 then sign = string.byte('-') end
+  return string.format('%c%02d%s%02d', sign, tz_offset_minutes / 60, separator, tz_offset_minutes % 60)
+end
+
+local tzi = assert(luatz.get_tz( tz_name ), 'No such timezone: \''..tz_name..'\'')
+local ts_utc = tzi:utctime ( ts_loc )
+local t_loc = luatz.timetable.new_from_timestamp( ts_loc )
+local t_utc = luatz.timetable.new_from_timestamp( ts_utc )
+
+print( t_loc:strftime('%F %T'), tz_off_iso8601(tzi:find_current( ts_utc ).gmtoff), tz_name )
+print( t_utc:strftime('%F %T'), tz_off_iso8601(0), 'UTC' )
+```