Marcus Rohrmoser 1 month ago
parent
commit
720aeb350a

+ 10 - 13
content/posts/2009-06-28-nsurlconnection-gzip-magic.md

@@ -34,9 +34,7 @@ That's how to use it:
 $ wget --header='Accept-Encoding: gzip' \
     --server-response http://example.com/demo.xmlz
 ```
-    
 It should (in case of a gzipped xml document) look like
-    
 ```log
 HTTP/1.1 200 OK
 ...
@@ -44,7 +42,6 @@ Content-Type: text/xml
 Content-Encoding: gzip
 ...
 ```
-
 2. If your webserver doesn't support transparent compression, you can still upload gzipped content and tell the server to send the correct response headers by setting up a [.htaccess][4] file:
 
 ```htaccess
@@ -59,8 +56,8 @@ AddEncoding gzip .gz .xmlz
 AddOutputFilterByType DEFLATE text/html text/plain text/xml
 ...
 ```
-
 3. to verify from within your app, log the response header in the NSURLConnection callbacks:
+
 ```objc
 - (void)connection:(NSURLConnection *)connection
   didReceiveResponse:(NSURLResponse *)response
@@ -82,9 +79,9 @@ AddOutputFilterByType DEFLATE text/html text/plain text/xml
     [buffer release];
 }
 ```
-    
-  It should look like
-    
+
+   It should look like
+
 ```log
 2009-06-28 14:31:09.722 DemoApp[3981:20b] \
   didReceiveResponse http://example.com/demo.xmlz: {
@@ -97,13 +94,13 @@ AddOutputFilterByType DEFLATE text/html text/plain text/xml
 2009-06-28 14:31:11.619 DemoApp[3981:20b] \
   connectionDidFinishLoading 602979 bytes
 ```
-    
+
    As you can see we received way more bytes than went over the wire.
-    
-* enjoy lightning fast network communication!</ol> 
-    
-    P.S.: It seems not to be necessary setting the request header yourself:
-    
+
+* enjoy lightning fast network communication!
+
+P.S.: It seems not to be necessary setting the request header yourself:
+
 ```objc
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
     cachePolicy:NSURLRequestReloadIgnoringLocalCacheData

+ 1 - 1
content/posts/2009-07-01-ruby-parse-apache-serverlogs.md

@@ -29,7 +29,7 @@ class Apache
     req_pat=/"([A-Z]+)\s([^\s]+)\s([^\s]+)"/
     ref_pat=/"([^"]+)"/
     date_fmt = '[%d/%b/%Y:%H:%M:%S %Z]'
-    apache_pat = Regexp.new( "(#{ip_pat})\s([^\s]+)\s([^\s]+)\s" < <
+    apache_pat = Regexp.new( "(#{ip_pat})\s([^\s]+)\s([^\s]+)\s" <<
       "(#{date_pat})\s#{req_pat}\s([0-9]+)\s(-|[0-9]+)\s#{ref_pat}\s#{ref_pat}")
     src.each_line do |l|
       m = apache_pat.match l

+ 51 - 44
content/posts/2009-07-10-sane-batch-scan-workaroun.md

@@ -5,68 +5,75 @@ type: post
 date: 2009-07-10T14:29:36+00:00
 url: /2009/07/sane-batch-scan-workaroun/
 yourls_shorturl:
-  - http://s.mro.name/2v
-
-language: de
+- http://s.mro.name/2v
 categories:
+- de
 - sysadmin
 tags:
-  - bash
-  - ImageMagick
-  - OS X
-  - printf
-  - SANE
-  - scanimage
-  - Scanner
+- bash
+- ImageMagick
+- OS X
+- printf
+- SANE
+- scanimage
+- Scanner
 
 ---
 Obwohl [scanimage][1] aus dem [SANE][2] Werkzeugkasten in der (aktuellen?) [OS X][3] Version
 
-<pre lang="bash">$ scanimage --version
-scanimage (sane-backends) 1.0.21cvs; backend version 1.0.21</pre>
+```bash
+$ scanimage --version
+scanimage (sane-backends) 1.0.21cvs; backend version 1.0.21
+```
 
 (installiert nach <http://blog.mro.name/2008/12/scanner-mustek-1200-cu-unter-mac-os-x-105/>) beim Versuch per &#8222;batch&#8220; mehrere Seiten zu scannen jeweils nach Seite 1 aus der Kurve fliegt:
 
-<pre lang="bash">$ scanimage --batch-start=45 --batch-count=16 --batch --batch-prompt \
---format=pnm --mode Color --resolution 300
-...
-Scanning page 46
-scanimage: sane_start: Invalid argument</pre>
+```bash
+$ scanimage --batch-start=45 --batch-count=16 --batch --batch-prompt \
+--format=pnm --mode Color --resolution 300
+...
+Scanning page 46
+scanimage: sane_start: Invalid argument
+```
 
 und das auch ein [bekanntes Problem][4] zu sein scheint, gibt's einen Workaround per selbstgebautem Shell-Script:
 
-<pre lang="bash">#!/bin/sh
-# http://blog.mro.name/2009/07/sane-batch-scan-workaroun/
-pre=scan-`date "+%Y-%m-%dT%H:%M"`
-echo "To create a pdf, call after scanning the pages:"
-echo "    convert $pre*.png -despeckle -density 100x100 -compress JPEG -quality 50 -page a4 $pre.pdf"
-for ((i=0;i &lt; 100;i++))
-do
-	echo "Place document no. $i on the scanner."
-	echo "Press &lt;RETURN&gt; to continue, &lt;q&gt; + &lt;RETURN&gt; to quit."
-	echo \\a
-	read key
-	if [[ $key == "q" || $key == "Q" ]] ; then
-		break
-	fi
-	dst=$pre-page$(printf %03d $i)
-	scanimage --mode Gray --resolution 300 --buffer-size=1024 --progress > $dst.pnm
-	# background conversion:
-	(convert $dst.pnm -level 15,85% -density 300x300 -type grayscale \
-		-resample 100x100 $dst.png && rm $dst.pnm) &
-done
-ls -l $pre*</pre>
+```bash
+#!/bin/sh
+# http://blog.mro.name/2009/07/sane-batch-scan-workaroun/
+pre=scan-`date "+%Y-%m-%dT%H:%M"`
+echo "To create a pdf, call after scanning the pages:"
+echo "    convert $pre*.png -despeckle -density 100x100 -compress JPEG -quality 50 -page a4 $pre.pdf"
+for ((i=0;i < 100;i++))
+do
+	echo "Place document no. $i on the scanner."
+	echo "Press <RETURN> to continue, <q> + <RETURN> to quit."
+	echo \\a
+	read key
+	if [[ $key == "q" || $key == "Q" ]] ; then
+		break
+	fi
+	dst=$pre-page$(printf %03d $i)
+	scanimage --mode Gray --resolution 300 --buffer-size=1024 --progress > $dst.pnm
+	# background conversion:
+	(convert $dst.pnm -level 15,85% -density 300x300 -type grayscale \
+		-resample 100x100 $dst.png && rm $dst.pnm) &
+done
+ls -l $pre*
+```
 
 é voilá.
 
 Um das ganze dann noch in ein PDF moderater Größe zu verwandeln genügt ([ImageMagick z.B. via darwinport][5] vorausgesetzt):
 
-<pre lang="bash">$ time convert *.png -despeckle -density 100x100 \
--compress JPEG -quality 75 -page a4 out.pdf
-
-real	3m39.867s
-user	2m55.069s
-sys	0m9.628s</pre>
+```bash
+$ time convert *.png -despeckle -density 100x100 \
+-compress JPEG -quality 75 -page a4 out.pdf
+
+real	3m39.867s
+user	2m55.069s
+sys	0m9.628s
+```
 
 .
 

+ 51 - 49
content/posts/2009-07-24-delta-debugging-git-bisect.md

@@ -5,65 +5,67 @@ type: post
 date: 2009-07-23T22:02:38+00:00
 url: /2009/07/delta-debugging-git-bisect/
 yourls_shorturl:
-  - http://s.mro.name/2z
-
-language: en
+- http://s.mro.name/2z
 categories:
-  - development
+- en
+- development
 tags:
-  - bisect
-  - Delta Debugging
-  - Eclipse
-  - git
-  - piccolo2d
+- bisect
+- Delta Debugging
+- Eclipse
+- git
+- piccolo2d
 
 ---
-Just had the problem &#8211; which of the last 40+ commits broke a certain feature in [Piccolo2D rev550][1]. As I used [git as a svn proxy][2] before, I remembered having heard of it's binary-search [delta-debugging][3] feature.
+Just had the problem  which of the last 40+ commits broke a certain feature in [Piccolo2D rev550][1]. As I used [git as a svn proxy][2] before, I remembered having heard of it's binary-search [delta-debugging][3] feature.
 
 So I started my first [git bisect][4] session:
 
 <!--more-->
 
-  1. go back fairly far (`git checkout 9377e6a0c6e9bcdff1803f18918e8a1a9282a4ee`, Eclipse Refresh, try, fine!),
-  2. start bisecting (doing each step: Eclipse->Refresh, Eclipse->Project->Clean, Try it out): <pre lang="bash">(master) $ git bisect start
-(master|BISECTING) $ git bisect bad
-(master|BISECTING) $ git bisect good 9377e6a0c6e9bcdff1803f18918e8a1a9282a4ee
-Bisecting: 47 revisions left to test after this (roughly 6 steps)
-[484ba591db63f6f476511787a5156cdaeb51889c] Fixed Issue 100; Plastered PInputEvent...
-(484ba59...|BISECTING) $ git bisect good
-Bisecting: 23 revisions left to test after this (roughly 5 steps)
-[fa515a6d0eb5ce23d3e47df5e5b4e81e94fdfa81] Added tests for PBasicInputEventHandler
-(fa515a6...|BISECTING) $ git bisect good
-Bisecting: 11 revisions left to test after this (roughly 4 steps)
-[6e496e12219346e856c8c519c29fedab3f196e35] Cleaned up PNavigationEventhandler.  R...
-(6e496e1...|BISECTING) $ git bisect bad
-Bisecting: 5 revisions left to test after this (roughly 3 steps)
-[c591c3098e6268cfc90fcb84672d642b0878a4b7] Removed some unnecessary imports from...
-(c591c30...|BISECTING) $ git bisect bad
-Bisecting: 2 revisions left to test after this (roughly 2 steps)
-[f3ca00181f2512b10bf12204395ad99f3d474f00] #84 added developers.
-(f3ca001...|BISECTING) $ git bisect good
-Bisecting: 1 revisions left to test after this (roughly 1 steps)
-[99e495ec4fc54b0f3a36ffd3b605f8a27bd86cdf] Refactored mousePressed and mouseRelease...
-(99e495e...|BISECTING) $ git bisect bad
-Bisecting: 0 revisions left to test after this (roughly 0 steps)
-[3f0c21d7cb88e696c23d4058acb708898bb60363] Just updated my contact info in the Maven...
-(3f0c21d...|BISECTING) $ git bisect good
-99e495ec4fc54b0f3a36ffd3b605f8a27bd86cdf is first bad commit
-commit 99e495ec4fc54b0f3a36ffd3b605f8a27bd86cdf
-Author:
-Date:   Mon Jul 20 15:02:56 2009 +0000
-
-    Refactored mousePressed and mouseReleased so that code common to each is now in a hel...
-
-    git-svn-id: https://piccolo2d.googlecode.com/svn/piccolo2d.java/trunk@524 aadc08cf-13...
-
-:040000 040000 b6c487cfdbe4df04947923af5fd05c45aa2ad38d 4dcd8070206a34a2d4037c3d90409ff1e...
-(3f0c21d...|BISECTING) $ git bisect reset
-Previous HEAD position was 3f0c21d... Just updated my contact info in the Maven Config File.
-Switched to branch 'master'</pre>
+1. go back fairly far (`git checkout 9377e6a0c6e9bcdff1803f18918e8a1a9282a4ee`, Eclipse Refresh, try, fine!),
+2. start bisecting (doing each step: Eclipse->Refresh, Eclipse->Project->Clean, Try it out):
+
+```bash
+(master) $ git bisect start
+(master|BISECTING) $ git bisect bad
+(master|BISECTING) $ git bisect good 9377e6a0c6e9bcdff1803f18918e8a1a9282a4ee
+Bisecting: 47 revisions left to test after this (roughly 6 steps)
+[484ba591db63f6f476511787a5156cdaeb51889c] Fixed Issue 100; Plastered PInputEvent...
+(484ba59...|BISECTING) $ git bisect good
+Bisecting: 23 revisions left to test after this (roughly 5 steps)
+[fa515a6d0eb5ce23d3e47df5e5b4e81e94fdfa81] Added tests for PBasicInputEventHandler
+(fa515a6...|BISECTING) $ git bisect good
+Bisecting: 11 revisions left to test after this (roughly 4 steps)
+[6e496e12219346e856c8c519c29fedab3f196e35] Cleaned up PNavigationEventhandler.  R...
+(6e496e1...|BISECTING) $ git bisect bad
+Bisecting: 5 revisions left to test after this (roughly 3 steps)
+[c591c3098e6268cfc90fcb84672d642b0878a4b7] Removed some unnecessary imports from...
+(c591c30...|BISECTING) $ git bisect bad
+Bisecting: 2 revisions left to test after this (roughly 2 steps)
+[f3ca00181f2512b10bf12204395ad99f3d474f00] #84 added developers.
+(f3ca001...|BISECTING) $ git bisect good
+Bisecting: 1 revisions left to test after this (roughly 1 steps)
+[99e495ec4fc54b0f3a36ffd3b605f8a27bd86cdf] Refactored mousePressed and mouseRelease...
+(99e495e...|BISECTING) $ git bisect bad
+Bisecting: 0 revisions left to test after this (roughly 0 steps)
+[3f0c21d7cb88e696c23d4058acb708898bb60363] Just updated my contact info in the Maven...
+(3f0c21d...|BISECTING) $ git bisect good
+99e495ec4fc54b0f3a36ffd3b605f8a27bd86cdf is first bad commit
+commit 99e495ec4fc54b0f3a36ffd3b605f8a27bd86cdf
+Author:
+Date:   Mon Jul 20 15:02:56 2009 +0000
+
+    Refactored mousePressed and mouseReleased so that code common to each is now in a hel...
+
+    git-svn-id: https://piccolo2d.googlecode.com/svn/piccolo2d.java/trunk@524 aadc08cf-13...
 
-  3. done, got the fishy commit! (524)
+:040000 040000 b6c487cfdbe4df04947923af5fd05c45aa2ad38d 4dcd8070206a34a2d4037c3d90409ff1e...
+(3f0c21d...|BISECTING) $ git bisect reset
+Previous HEAD position was 3f0c21d... Just updated my contact info in the Maven Config File.
+Switched to branch 'master'
+```
+3. done, got the fishy commit! (524)
 
 P.S.: I cut the long lines, git spits them out in full, naturally.
 

+ 258 - 253
content/posts/2009-09-01-cocoa-wrapped-regexh.md

@@ -5,276 +5,281 @@ type: post
 date: 2009-09-01T08:55:51+00:00
 url: /2009/09/cocoa-wrapped-regexh/
 yourls_shorturl:
-  - http://s.mro.name/2d
-
-language: en
+- http://s.mro.name/2d
 categories:
-  - development
+- en
+- development
 tags:
-  - Cocoa
-  - iPhone
-  - NSRegularExpression
-  - Objective C
-  - regex
-  - YouTube
+- Cocoa
+- iPhone
+- NSRegularExpression
+- Objective C
+- regex
+- YouTube
 
 ---
 Strange enough there's no regular expression class in the iPhone SDK.
 
-**Update**: iOS 4 brings `<a href="http://developer.apple.com/iphone/library/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html">NSRegularExpression</a>`.
+**Update**: iOS 4 brings [`NSRegularExpression`](http://developer.apple.com/iphone/library/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html).
 
 My simple wrapper around the [regex.h C API][1] is not safe for unicode matching patterns but does the job e.g. for parsing URLs. If you need more, have a look at [RegexKitLite][2]. My simple wrapper has the interface:
 
 <!--more-->
 
-<pre lang="objc">//  RegExp.h
-//
-//  Created by Marcus Rohrmoser on 26.08.09.
-//  Copyright 2009 Marcus Rohrmoser. All rights reserved.
-
-#import &lt; Foundation/Foundation.h &gt;
-#import &lt; regex.h &gt;
-
-#define REGEXP_NSERROR_DOMAIN   @"regex.h"
-#define NSRegExpPatternKey      @"NSRegExpPatternKey"
-
-/** Very simple Objective-C Wrapper around the regex.h functions.
- */
-@interface RegExp : NSObject
-{
-    @private
-    regex_t * c_regex;
-}
-
-/** Compile a RegExp.
- @param pattern See regex.h / regcomp for details. ASCII encodeable characters only!
- @param error in case of trouble: REGEXP_NSERROR_DOMAIN, errocode from regcomp
- and userinfo NSLocalizedDescriptionKey and NSRegExpPatternKey.
- @return the regexp or nil in case of error.
- */
-+(RegExp*)RegExpWithString:(NSString*)pattern error:(NSError**)error;
-
-/**
- Perform a match.
- @param string text to search
- @return nil (no match) or the complete match plus all matching groups.
- */
--(NSArray*)match:(NSString*)string;
-
-@end</pre>
+```objc
+//  RegExp.h
+//
+//  Created by Marcus Rohrmoser on 26.08.09.
+//  Copyright 2009 Marcus Rohrmoser. All rights reserved.
+
+#import <Foundation/Foundation.h>
+#import <regex.h>
+
+#define REGEXP_NSERROR_DOMAIN   @"regex.h"
+#define NSRegExpPatternKey      @"NSRegExpPatternKey"
+
+/** Very simple Objective-C Wrapper around the regex.h functions.
+ */
+@interface RegExp : NSObject
+{
+    @private
+    regex_t * c_regex;
+}
+
+/** Compile a RegExp.
+ @param pattern See regex.h / regcomp for details. ASCII encodeable characters only!
+ @param error in case of trouble: REGEXP_NSERROR_DOMAIN, errocode from regcomp
+ and userinfo NSLocalizedDescriptionKey and NSRegExpPatternKey.
+ @return the regexp or nil in case of error.
+ */
++(RegExp*)RegExpWithString:(NSString*)pattern error:(NSError**)error;
+
+/**
+ Perform a match.
+ @param string text to search
+ @return nil (no match) or the complete match plus all matching groups.
+ */
+-(NSArray*)match:(NSString*)string;
+
+@end
+```
 
 with implementation
 
-<pre lang="objc">//  RegExp.m
-//
-//  Created by Marcus Rohrmoser on 26.08.09.
-//  Copyright 2009 Marcus Rohrmoser. All rights reserved.
-
-#import "RegExp.h"
-
-#define ENCODING NSASCIIStringEncoding
-
-/* Currently uses stringWithCString - which is bashed at
- + http://lists.apple.com/archives/cocoa-dev/2004/Nov/msg01643.html, but why?
- + What's wrong with it?
- + */
-@implementation RegExp
-
-#pragma mark Internal Helpers
-
--(id)initWithParsedPattern:(regex_t*)value_
-{
-    if ( self = [super init] )
-        c_regex = value_;
-    return self;
-}
-
-+(NSError*)errorFromRegExpError:(regex_t*)regex pattern:(NSString*)pattern code:(NSInteger)code
-{
-    const size_t errbuf_size = 1000;
-    char * errbuf = calloc(errbuf_size, sizeof(errbuf[0]));
-    regerror(code, regex, errbuf, errbuf_size);
-//	regfree(regex);
-//	free(regex);
-
-    NSString *msg = [NSString stringWithCString:errbuf encoding:NSASCIIStringEncoding];
-    NSError *error = [NSError errorWithDomain:REGEXP_NSERROR_DOMAIN code:code
-        userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
-            pattern,  NSRegExpPatternKey,
-            msg,  NSLocalizedDescriptionKey, nil]];
-    free(errbuf);
-    return error;
-}
-
-#pragma mark Public Interface
-
-+(RegExp*)RegExpWithString:(NSString*)value_ error:(NSError**)error
-{
-    if(value_ == nil)
-        return nil;
-    const char * pat_c = [value_ cStringUsingEncoding:ENCODING];
-    regex_t * regex = calloc(1, sizeof(regex_t));
-    const int ec = regcomp(regex, pat_c, REG_EXTENDED);
-    if(ec != 0)
-    {
-        if(error != nil)
-            *error = [RegExp errorFromRegExpError:regex pattern:value_ code:ec];
-        regfree(regex);
-        free(regex);
-        return nil;
-    }
-    return [[[RegExp alloc] initWithParsedPattern:regex] autorelease];
-}
-
--(NSArray*)match:(NSString*)string
-{
-    if(string == nil)
-        return nil;
-    const char * c_str = [string cStringUsingEncoding:ENCODING];
-    if(c_str == NULL)
-        return nil;
-    const int count = 1 + c_regex-&gt;re_nsub;
-    regmatch_t match[count];
-    const int ec = regexec(c_regex, c_str, count, match, 0);
-    if(ec != 0)
-        return nil;
-    NSMutableArray *arr = [NSMutableArray arrayWithCapacity:count];
-    for(int i = 0; i &lt; count; i++)
-    {
-        if(match[i].rm_so == -1 && match[i].rm_eo == -1)
-            [arr addObject:[NSNull null]];
-        else
-        {
-            const char * start = &c_str[ match[i].rm_so ];
-            const int length = match[i].rm_eo - match[i].rm_so;
-            [arr addObject:[[[NSString alloc] initWithBytes:start length:length encoding:ENCODING] autorelease]];
-        }
-    }
-    return arr;
-}
-
--(void)dealloc
-{
-    regfree(c_regex);
-    free(c_regex);
-    [super dealloc];
-}
-@end</pre>
+```objc
+//  RegExp.m
+//
+//  Created by Marcus Rohrmoser on 26.08.09.
+//  Copyright 2009 Marcus Rohrmoser. All rights reserved.
+
+#import "RegExp.h"
+
+#define ENCODING NSASCIIStringEncoding
+
+/* Currently uses stringWithCString - which is bashed at
+ + http://lists.apple.com/archives/cocoa-dev/2004/Nov/msg01643.html, but why?
+ + What's wrong with it?
+ + */
+@implementation RegExp
+
+#pragma mark Internal Helpers
+
+-(id)initWithParsedPattern:(regex_t*)value_
+{
+    if ( self = [super init] )
+        c_regex = value_;
+    return self;
+}
+
++(NSError*)errorFromRegExpError:(regex_t*)regex pattern:(NSString*)pattern code:(NSInteger)code
+{
+    const size_t errbuf_size = 1000;
+    char * errbuf = calloc(errbuf_size, sizeof(errbuf[0]));
+    regerror(code, regex, errbuf, errbuf_size);
+//  regfree(regex);
+//  free(regex);
+
+    NSString *msg = [NSString stringWithCString:errbuf encoding:NSASCIIStringEncoding];
+    NSError *error = [NSError errorWithDomain:REGEXP_NSERROR_DOMAIN code:code
+        userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
+            pattern,  NSRegExpPatternKey,
+            msg,  NSLocalizedDescriptionKey, nil]];
+    free(errbuf);
+    return error;
+}
+
+#pragma mark Public Interface
+
++(RegExp*)RegExpWithString:(NSString*)value_ error:(NSError**)error
+{
+    if(value_ == nil)
+        return nil;
+    const char * pat_c = [value_ cStringUsingEncoding:ENCODING];
+    regex_t * regex = calloc(1, sizeof(regex_t));
+    const int ec = regcomp(regex, pat_c, REG_EXTENDED);
+    if(ec != 0)
+    {
+        if(error != nil)
+            *error = [RegExp errorFromRegExpError:regex pattern:value_ code:ec];
+        regfree(regex);
+        free(regex);
+        return nil;
+    }
+    return [[[RegExp alloc] initWithParsedPattern:regex] autorelease];
+}
+
+-(NSArray*)match:(NSString*)string
+{
+    if(string == nil)
+        return nil;
+    const char * c_str = [string cStringUsingEncoding:ENCODING];
+    if(c_str == NULL)
+        return nil;
+    const int count = 1 + c_regex->re_nsub;
+    regmatch_t match[count];
+    const int ec = regexec(c_regex, c_str, count, match, 0);
+    if(ec != 0)
+        return nil;
+    NSMutableArray *arr = [NSMutableArray arrayWithCapacity:count];
+    for(int i = 0; i < count; i++)
+    {
+        if(match[i].rm_so == -1 && match[i].rm_eo == -1)
+            [arr addObject:[NSNull null]];
+        else
+        {
+            const char * start = &c_str[ match[i].rm_so ];
+            const int length = match[i].rm_eo - match[i].rm_so;
+            [arr addObject:[[[NSString alloc] initWithBytes:start length:length encoding:ENCODING] autorelease]];
+        }
+    }
+    return arr;
+}
+
+-(void)dealloc
+{
+    regfree(c_regex);
+    free(c_regex);
+    [super dealloc];
+}
+@end
+```
 
 and an accompanying testcase
 
-<pre lang="objc">//  RegExpTC.m
-//
-//  Created by Marcus Rohrmoser on 26.08.09.
-//  Copyright 2009 Marcus Rohrmoser. All rights reserved.
-
-#include "TargetConditionals.h"
-#if !TARGET_IPHONE_SIMULATOR
-#warning TestCase ignored when not building for Simulator
-#else
-
-#import "../Classes/RegExp.h"
-
-#import &lt; SenTestingKit/SenTestingKit.h &gt;
-
-@interface RegExpTC : SenTestCase
-{
-
-}
-
-@end
-
-@implementation RegExpTC
-
--(void)testYouTube
-{
-    NSError *error = nil;
-    RegExp *pat =
-[RegExp RegExpWithString:@"http.+\.youtube\.com/(v/|watch\?v=)([A-Za-z0-9._%-]+)" error:&error];
-    STAssertNil(error, @"pattern compile");
-    STAssertNotNil(pat, @"pattern compile");
-
-    NSArray *match = [pat match:@"http://www.youtube.com/v/61wkfmWzLq4&hl=de
-&fs=1&rel=0&color1=0x3a3a3a&color2=0x999999&hd=1&border=1"];
-    STAssertNotNil(match, @"must match");
-    STAssertEquals(3u, match.count, @"one matching subexpression");
-    STAssertEqualObjects(@"v/", [match objectAtIndex:1], @"snippet");
-    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:2], @"snippet");
-
-// /youtube.com/watch?v=([A-Za-z0-9._%-]*)[&w;=+_-]*/
-
-    match = [pat match:@"http://www.youtube.com/watch?v=61wkfmWzLq4"];
-    STAssertNotNil(match, @"must match");
-    STAssertEquals(3u, match.count, @"one matching subexpression");
-    STAssertEqualObjects(@"watch?v=", [match objectAtIndex:1], @"snippet");
-    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:2], @"snippet");
-
-    match = [pat match:@"http://www.youtube.com/v/61wkfmWzLq4&hl=de&fs=1&"];
-    STAssertNotNil(match, @"must match");
-    STAssertEqualObjects(@"v/", [match objectAtIndex:1], @"snippet");
-    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:2], @"snippet");
-}
-
--(void)testCocoaOk
-{
-    NSError *error = nil;
-
-    STAssertNil([RegExp RegExpWithString:nil error:&error], @"pattern nil");
-    STAssertNil(error, @"pattern must compile ok");
-
-    RegExp *reg = [RegExp RegExpWithString:@"http.+\.youtube\.com/v/([^\&]+)\&.*"
-error:&error];
-    STAssertNil(error, @"pattern must compile ok");
-
-    NSString *str = @"http://www.youtube.com/v/61wkfmWzLq4&hl=de&fs=1
-&rel=0&color1=0x3a3a3a&color2=0x999999&hd=1&border=1";
-    NSArray * match = [reg match:str];
-    STAssertNotNil(match, @"must match");
-
-    STAssertEquals(2u, match.count, @"two matches expected");
-    STAssertEqualObjects(str, [match objectAtIndex:0], @"complete match");
-    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:1], @"first matching group");
-
-    STAssertNil([reg match:nil], @"must not match");
-}
-
--(void)testCocoaFail
-{
-    NSError *error = nil;
-    RegExp *reg = [RegExp RegExpWithString:@"" error:&error];
-    STAssertNil(reg, @"pattern must fail");
-    STAssertNotNil(error, @"pattern must fail");
-    STAssertEqualObjects(REGEXP_NSERROR_DOMAIN, error.domain, @"domain check");
-    STAssertEquals(REG_EMPTY, error.code, @"code check");
-    STAssertEqualObjects(@"empty (sub)expression", error.localizedDescription, @"description check");
-    STAssertEqualObjects(@"", [error.userInfo valueForKey:NSRegExpPatternKey], @"pattern info");
-}
-
--(void)testRaw
-{
-    regex_t regex;
-    const char * pattern = "http.+\.youtube\.com/v/([^\&]+)\&.*";
-    STAssertTrue(0 == regcomp(&regex, pattern, REG_EXTENDED), @"RegExp compile");
-
-    regmatch_t * match = calloc(1 + regex.re_nsub, sizeof(regmatch_t));
-    const char * string = "http://www.youtube.com/v/61wkfmWzLq4&hl=de&fs=1&rel=0
-&color1=0x3a3a3a&color2=0x999999&hd=1&border=1";
-
-    STAssertTrue(0 == regexec(&regex, string, 1 + regex.re_nsub, match, 0), @"RegExp Match");
-    STAssertTrue(1 == regex.re_nsub, @"Matching groups count");
-
-    STAssertTrue(0 == match[0].rm_so, @"Match 0 start");
-    STAssertTrue(127 == match[0].rm_eo, @"Match 0 start");
-
-    STAssertTrue(25 == match[1].rm_so, @"Match 1 start");
-    STAssertTrue(36 == match[1].rm_eo, @"Match 1 start");
-
-    free(match);
-    regfree(&regex);
-}
-
-@end
-#endif</pre>
+```objc
+//  RegExpTC.m
+//
+//  Created by Marcus Rohrmoser on 26.08.09.
+//  Copyright 2009 Marcus Rohrmoser. All rights reserved.
+
+#include "TargetConditionals.h"
+#if !TARGET_IPHONE_SIMULATOR
+#warning TestCase ignored when not building for Simulator
+#else
+
+#import "../Classes/RegExp.h"
+
+#import <SenTestingKit/SenTestingKit.h>
+
+@interface RegExpTC : SenTestCase
+{
+
+}
+
+@end
+
+@implementation RegExpTC
+
+-(void)testYouTube
+{
+    NSError *error = nil;
+    RegExp *pat =
+[RegExp RegExpWithString:@"http.+\.youtube\.com/(v/|watch\?v=)([A-Za-z0-9._%-]+)" error:&error];
+    STAssertNil(error, @"pattern compile");
+    STAssertNotNil(pat, @"pattern compile");
+
+    NSArray *match = [pat match:@"http://www.youtube.com/v/61wkfmWzLq4&hl=de
+&fs=1&rel=0&color1=0x3a3a3a&color2=0x999999&hd=1&border=1"];
+    STAssertNotNil(match, @"must match");
+    STAssertEquals(3u, match.count, @"one matching subexpression");
+    STAssertEqualObjects(@"v/", [match objectAtIndex:1], @"snippet");
+    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:2], @"snippet");
+
+// /youtube.com/watch?v=([A-Za-z0-9._%-]*)[&w;=+_-]*/
+
+    match = [pat match:@"http://www.youtube.com/watch?v=61wkfmWzLq4"];
+    STAssertNotNil(match, @"must match");
+    STAssertEquals(3u, match.count, @"one matching subexpression");
+    STAssertEqualObjects(@"watch?v=", [match objectAtIndex:1], @"snippet");
+    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:2], @"snippet");
+
+    match = [pat match:@"http://www.youtube.com/v/61wkfmWzLq4&hl=de&fs=1&"];
+    STAssertNotNil(match, @"must match");
+    STAssertEqualObjects(@"v/", [match objectAtIndex:1], @"snippet");
+    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:2], @"snippet");
+}
+
+-(void)testCocoaOk
+{
+    NSError *error = nil;
+
+    STAssertNil([RegExp RegExpWithString:nil error:&error], @"pattern nil");
+    STAssertNil(error, @"pattern must compile ok");
+
+    RegExp *reg = [RegExp RegExpWithString:@"http.+\.youtube\.com/v/([^\&]+)\&.*"
+error:&error];
+    STAssertNil(error, @"pattern must compile ok");
+
+    NSString *str = @"http://www.youtube.com/v/61wkfmWzLq4&hl=de&fs=1
+&rel=0&color1=0x3a3a3a&color2=0x999999&hd=1&border=1";
+    NSArray * match = [reg match:str];
+    STAssertNotNil(match, @"must match");
+
+    STAssertEquals(2u, match.count, @"two matches expected");
+    STAssertEqualObjects(str, [match objectAtIndex:0], @"complete match");
+    STAssertEqualObjects(@"61wkfmWzLq4", [match objectAtIndex:1], @"first matching group");
+
+    STAssertNil([reg match:nil], @"must not match");
+}
+
+-(void)testCocoaFail
+{
+    NSError *error = nil;
+    RegExp *reg = [RegExp RegExpWithString:@"" error:&error];
+    STAssertNil(reg, @"pattern must fail");
+    STAssertNotNil(error, @"pattern must fail");
+    STAssertEqualObjects(REGEXP_NSERROR_DOMAIN, error.domain, @"domain check");
+    STAssertEquals(REG_EMPTY, error.code, @"code check");
+    STAssertEqualObjects(@"empty (sub)expression", error.localizedDescription, @"description check");
+    STAssertEqualObjects(@"", [error.userInfo valueForKey:NSRegExpPatternKey], @"pattern info");
+}
+
+-(void)testRaw
+{
+    regex_t regex;
+    const char * pattern = "http.+\.youtube\.com/v/([^\&]+)\&.*";
+    STAssertTrue(0 == regcomp(&regex, pattern, REG_EXTENDED), @"RegExp compile");
+
+    regmatch_t * match = calloc(1 + regex.re_nsub, sizeof(regmatch_t));
+    const char * string = "http://www.youtube.com/v/61wkfmWzLq4&hl=de&fs=1&rel=0
+&color1=0x3a3a3a&color2=0x999999&hd=1&border=1";
+
+    STAssertTrue(0 == regexec(&regex, string, 1 + regex.re_nsub, match, 0), @"RegExp Match");
+    STAssertTrue(1 == regex.re_nsub, @"Matching groups count");
+
+    STAssertTrue(0 == match[0].rm_so, @"Match 0 start");
+    STAssertTrue(127 == match[0].rm_eo, @"Match 0 start");
+
+    STAssertTrue(25 == match[1].rm_so, @"Match 1 start");
+    STAssertTrue(36 == match[1].rm_eo, @"Match 1 start");
+
+    free(match);
+    regfree(&regex);
+}
+
+@end
+#endif
+```
 
  [1]: http://developer.apple.com/iphone/library/documentation/System/Conceptual/ManPages_iPhoneOS/man3/regex.3.html
  [2]: http://regexkit.sourceforge.net/RegexKitLite/

+ 8 - 7
content/posts/2009-09-30-screenshots-fur-den-app-store.md

@@ -5,19 +5,20 @@ type: post
 date: 2009-09-30T08:24:05+00:00
 url: /2009/09/screenshots-fur-den-app-store/
 yourls_shorturl:
-  - http://s.mro.name/1t
-language: de
+- http://s.mro.name/1t
 categories:
+- de
 - development
 tags:
-  - App Store
-  - ImageMagick
-  - iPhone
+- App Store
+- ImageMagick
+- iPhone
 
 ---
 Der App Store möchte gerne Screenshots ohne Statuszeile und im TIFF Format. Da das immer gleich sein soll bietet sich [ImageMagick][1] an:
 
-<pre>convert MyScreenshot.png -compress None -crop '320x460-0+20' MyScreenshot.tiff
-</pre>
+```
+$ convert MyScreenshot.png -compress None -crop '320x460-0+20' MyScreenshot.tiff
+```
 
  [1]: http://www.imagemagick.org/

+ 15 - 14
content/posts/2009-10-02-google-app-engine-xslt.md

@@ -5,38 +5,39 @@ type: post
 date: 2009-10-02T13:47:46+00:00
 url: /2009/10/google-app-engine-xslt/
 yourls_shorturl:
-  - http://s.mro.name/o
-
-language: en
+- http://s.mro.name/o
 categories:
-  - development
+- en
+- development
 tags:
-  - GAE
-  - Google App Engine
-  - Java
-  - Xalan
-  - XSLT
+- GAE
+- Google App Engine
+- Java
+- Xalan
+- XSLT
 
 ---
 [Google App Engine (java)][1] doesn't do [XSLT transformations][2] out of the box. Using a [Transformer][3] like
 
-<pre lang="java">TransformerFactory.newInstance().newTransformer(new StreamSource(...)).transform(...);</pre>
+```java
+TransformerFactory.newInstance().newTransformer(new StreamSource(...)).transform(...);
+```
 
 yields a
 
-`Nested in javax.servlet.ServletException: java.lang.NoClassDefFoundError: com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary is a restricted class. Please see the Google App Engine developer's guide for more details.:<br />
+`Nested in javax.servlet.ServletException: java.lang.NoClassDefFoundError: com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary is a restricted class. Please see the Google App Engine developer's guide for more details.:  
 java.lang.NoClassDefFoundError: com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary is a restricted class. Please see the Google App Engine developer's guide for more details.`
 
 These google groups posts <http://code.google.com/p/googleappengine/issues/detail?id=1452> and <http://groups.google.com/group/google-appengine-java/browse_thread/thread/9c9fb88e1b175395> lead into the right direction but didn't completely solve my problem. I added `xalan.jar` and `serializer.jar` from xalan-2.7.1 to `war/WEB_INF/lib` as suggested, but **didn't change** the TransformerFactory setup.
 
 This got me the WARNING log entries `Failed calling setMethod method` and `Failed calling setIndent method`.
 
-This [cyrillc blog-post][4] lead me to removing all `<xsl:output/>` statements from the transformation and voilá &#8211; the trafo ran fine!
+This [cyrillc blog-post][4] lead me to removing all `<xsl:output/>` statements from the transformation and voilá  the trafo ran fine!
 
 The whole procedure in short:
 
-  * add `xalan.jar` and `serializer.jar` to `war/WEB_INF/lib`,
-  * remove `<xsl:output/>` from the stylesheet.
+* add `xalan.jar` and `serializer.jar` to `war/WEB_INF/lib`,
+* remove `<xsl:output/>` from the stylesheet.
 
  [1]: http://code.google.com/intl/en-GB/appengine/docs/java/
  [2]: http://www.w3.org/TR/xslt

+ 29 - 25
content/posts/2009-10-15-ist-das-zensursula.md

@@ -5,41 +5,45 @@ type: post
 date: 2009-10-15T21:59:04+00:00
 url: /2009/10/ist-das-zensursula/
 yourls_shorturl:
-  - http://s.mro.name/1r
-language: de
+- http://s.mro.name/1r
 categories:
+- de
 - sysadmin
 tags:
-  - DNS
-  - Root-Nameserver
-  - T-Online
-  - zensursula
+- DNS
+- Root-Nameserver
+- T-Online
+- zensursula
 
 ---
 Seit heute ca. 15:30 sind die [Root-Nameserver][1] für mich (T-Online Kunde) nicht mehr erreichbar:
 
-<pre>$ nslookup google.com - j.root-servers.net
-Server:		j.root-servers.net
-Address:	192.58.128.30#53
-
-Non-authoritative answer:
-*** Can't find google.com: No answer</pre>
+```bash
+$ nslookup google.com - j.root-servers.net
+Server:		j.root-servers.net
+Address:	192.58.128.30#53
+
+Non-authoritative answer:
+*** Can't find google.com: No answer
+```
 
 Ist das die Vorbereitung der [China Wochen][2] bei T-Online & Co.? Bei Gelegenheit mal ausprobieren: [eigene bind Nameserver Instanz][3].
 
-**[Update]**: Am rosa Riesen scheint's nicht zu liegen &#8211; das Problem liegt wohl in [Layer 8][4].
-
-<pre>$ nslookup google.com - resolver1.opendns.com
-Server:		resolver1.opendns.com
-Address:	208.67.222.222#53
-
-Non-authoritative answer:
-Name:	google.com
-Address: 74.125.67.100
-Name:	google.com
-Address: 74.125.45.100
-Name:	google.com
-Address: 74.125.53.100</pre>
+**[Update]**: Am rosa Riesen scheint's nicht zu liegen – das Problem liegt wohl in [Layer 8][4].
+
+```bash
+$ nslookup google.com - resolver1.opendns.com
+Server:		resolver1.opendns.com
+Address:	208.67.222.222#53
+
+Non-authoritative answer:
+Name:	google.com
+Address: 74.125.67.100
+Name:	google.com
+Address: 74.125.45.100
+Name:	google.com
+Address: 74.125.53.100
+```
 
 In Zukunft also nicht mehr mit den Root-Nameservern, sondern einem vom [CCC][5] empfohlenen.
 

+ 60 - 59
content/posts/2009-10-23-cocoatouch-coredata-and-binary-string-search.md

@@ -5,76 +5,77 @@ type: post
 date: 2009-10-23T18:27:59+00:00
 url: /2009/10/cocoatouch-coredata-and-binary-string-search/
 yourls_shorturl:
-  - http://mro.name/3o
-
-language: en
+- http://mro.name/3o
 categories:
-  - development
+- de
+- development
 tags:
-  - Binary
-  - Cocoa
-  - CoreData
-  - iPhone
-  - NSPredicate
-  - Objective C
-  - Search
+- Binary
+- Cocoa
+- CoreData
+- iPhone
+- NSPredicate
+- Objective C
+- Search
 
 ---
 The [query optimiser][1] for [NSPredicate][2] queries ontop CoreData/SQLite on the iPhone is a bit rudimentary (cough) and so I had to optimise myself to get binary-search enabled quick results:
 
 <!--more-->
 
-<pre lang="objc">+(NSPredicate*)findBySearchTerm:(NSString*)rawTerm within:(BOOL)within context:(NSManagedObjectContext*)context
-{
-    NSSet *tokens = [MovieM indexTokens:rawTerm];
-    if(tokens == nil || tokens.count &lt; = 0)
-        return [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];
-    NSMutableArray *preds = [NSMutableArray arrayWithCapacity:tokens.count];
-
-    if(within == NO && context != nil)
-    {
-	// As queries aren't optimised by default we do it ourselves:
-	// 1st: find matching entries from the IndexKey table - leveraging it's index:
-        NSFetchRequest *fr = [[NSFetchRequest alloc] init];
-        fr.entity = [NSEntityDescription entityForName:@"IndexKey" inManagedObjectContext:context];
-        NSMutableSet *result = nil;
-        NSError *error = nil;
-        for(NSString *token in tokens)
-        {
-	    // BETWEEN uses the table-index while BEGINSWITH does not:
-            fr.predicate = [NSPredicate predicateWithFormat:@"key BETWEEN {%@, %@}", token, [MovieM upperBoundSearchString:token]];
-            NSArray *keys = [context executeFetchRequest:fr error:&error];
-            if(error != nil)
-                NSLog(@"Oops: %@", error);
-	    // turn IndexKey entries to movies (join up):
-            NSArray *movs = [keys valueForKey:@"movie"];
-	    // aggregate the results for each token:
-            if(result == nil)
-                result = [NSMutableSet setWithArray:movs];
-            else
-                [result intersectSet:[NSSet setWithArray:movs]];
-        }
-        [fr release];
-        return [NSPredicate predicateWithFormat:@"SELF IN %@", result];
-    }
-
-    NSPredicate *template = nil;
-    if(within)
-        template = [NSPredicate predicateWithFormat:@"ANY index.key CONTAiNS $searchTerm"];
-    else
-        template = [NSPredicate predicateWithFormat:@"ANY index.key BEGINSWITH $searchTerm"];
-    for(NSString *token in tokens)
-    {
-        NSDictionary *params = [NSDictionary dictionaryWithObject:token forKey:@"searchTerm"];
-        [preds addObject:[template predicateWithSubstitutionVariables:params]];
-    }
-    return [NSCompoundPredicate andPredicateWithSubpredicates:preds];
-}</pre>
+```objc
++(NSPredicate*)findBySearchTerm:(NSString*)rawTerm within:(BOOL)within context:(NSManagedObjectContext*)context
+{
+    NSSet *tokens = [MovieM indexTokens:rawTerm];
+    if(tokens == nil || tokens.count < = 0)
+        return [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];
+    NSMutableArray *preds = [NSMutableArray arrayWithCapacity:tokens.count];
+
+    if(within == NO && context != nil)
+    {
+        // As queries aren't optimised by default we do it ourselves:
+        // 1st: find matching entries from the IndexKey table - leveraging it's index:
+        NSFetchRequest *fr = [[NSFetchRequest alloc] init];
+        fr.entity = [NSEntityDescription entityForName:@"IndexKey" inManagedObjectContext:context];
+        NSMutableSet *result = nil;
+        NSError *error = nil;
+        for(NSString *token in tokens)
+        {
+            // BETWEEN uses the table-index while BEGINSWITH does not:
+            fr.predicate = [NSPredicate predicateWithFormat:@"key BETWEEN {%@, %@}", token, [MovieM upperBoundSearchString:token]];
+            NSArray *keys = [context executeFetchRequest:fr error:&error];
+            if(error != nil)
+                NSLog(@"Oops: %@", error);
+            // turn IndexKey entries to movies (join up):
+            NSArray *movs = [keys valueForKey:@"movie"];
+            // aggregate the results for each token:
+            if(result == nil)
+                result = [NSMutableSet setWithArray:movs];
+            else
+                [result intersectSet:[NSSet setWithArray:movs]];
+        }
+        [fr release];
+        return [NSPredicate predicateWithFormat:@"SELF IN %@", result];
+    }
+
+    NSPredicate *template = nil;
+    if(within)
+        template = [NSPredicate predicateWithFormat:@"ANY index.key CONTAiNS $searchTerm"];
+    else
+        template = [NSPredicate predicateWithFormat:@"ANY index.key BEGINSWITH $searchTerm"];
+    for(NSString *token in tokens)
+    {
+        NSDictionary *params = [NSDictionary dictionaryWithObject:token forKey:@"searchTerm"];
+        [preds addObject:[template predicateWithSubstitutionVariables:params]];
+    }
+    return [NSCompoundPredicate andPredicateWithSubpredicates:preds];
+}
+```
 
 Helpers herein are
 
-  * `[MovieM indexTokens:rawTerm]` folds diacritics and uppercase and cuts at whitespace or interpunction,
-  * `[MovieM upperBoundSearchString:token]` which was inspired by [Apple Sample Code &#8222;DerivedProperty&#8220; `NormalizedStringTransformer::upperBoundSearchString:`][3].
+* `[MovieM indexTokens:rawTerm]` folds diacritics and uppercase and cuts at whitespace or interpunction,
+* `[MovieM upperBoundSearchString:token]` which was inspired by [Apple Sample Code &#8222;DerivedProperty&#8220; `NormalizedStringTransformer::upperBoundSearchString:`][3].
 
  [1]: http://en.wikipedia.org/wiki/Query_optimizer
  [2]: http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/Reference/NSPredicate.html

File diff suppressed because it is too large
+ 8 - 10
content/posts/2009-10-30-filmfest-iphone-app-v1-0-online.md


+ 43 - 40
content/posts/2009-11-04-t-mobile-rechnungen-auspacken-umbenennen.md

@@ -5,53 +5,56 @@ type: post
 date: 2009-11-04T17:50:19+00:00
 url: /2009/11/t-mobile-rechnungen-auspacken-umbenennen/
 yourls_shorturl:
-  - http://s.mro.name/24
-
-language: de
+- http://s.mro.name/24
 categories:
+- de
 - sysadmin
 tags:
-  - GnuPG
-  - gpg
-  - Ruby
-  - T-Mobile
+- GnuPG
+- gpg
+- Ruby
+- T-Mobile
 
 ---
-über [T-Mobile RechnungOnline][1] kann man sich die Rechnung als [gpg][2]-verschlüsselten Anhang per Mail schicken lassen &#8211; incl. Einzelverbindungsnachweis. Und obwohl's nur 1x im Monat kommt, ist das Auspacken und Umbenennen in sinnvolle Dateinamen eine lästige Routinearbeit.
+über [T-Mobile RechnungOnline][1] kann man sich die Rechnung als [gpg][2]-verschlüsselten Anhang per
+Mail schicken lassen – incl. Einzelverbindungsnachweis. Und obwohl's nur 1x im Monat kommt, ist das
+Auspacken und Umbenennen in sinnvolle Dateinamen eine lästige Routinearbeit.
+
+Also – automatisieren. Das folgende Ruby-Script erledigt das, nachdem der Rechnungsanhang in einen
+der Ordner &#8222;Downloads&#8220; oder &#8222;Desktop&#8220; gelegt wurde:
+
+```ruby
+#!/usr/bin/ruby
+
+dst="#{ENV['HOME']}/Documents/tmobile"
 
-Also &#8211; automatisieren. Das folgende Ruby-Script erledigt das, nachdem der Rechnungsanhang in einen der Ordner &#8222;Downloads&#8220; oder &#8222;Desktop&#8220; gelegt wurde:
+# 1. pull together all pgp crypted find Rechnung_15.10.2009.zip.pgp in Desktop, Downloads, local dir
+["#{ENV['HOME']}/Downloads", "#{ENV['HOME']}/Desktop", dst].each do |dir|
+  Dir.foreach(dir) do |file|
+    m = /Rechnung_(\d{2})\.(\d{2})\.(\d{4})\.zip(\.pgp|\.gpg)?/.match file
+    if m
+      s = system "mv #{dir}/#{file} #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip#{m[4]}"
+      s = system "gpg #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip#{m[4]}" if m[4]
+      system "rm #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip#{m[4]}" if s && m[4]
+      s = system "unzip #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip"
+      system "rm #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip" if s
+      puts "de-crypted & unpacked #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip"
+    end
+  end
+end
 
-<pre lang="ruby">#!/usr/bin/ruby
-
-dst="#{ENV['HOME']}/Documents/tmobile"
-
-# 1. pull together all pgp crypted find Rechnung_15.10.2009.zip.pgp in Desktop, Downloads, local dir
-["#{ENV['HOME']}/Downloads", "#{ENV['HOME']}/Desktop", dst].each do |dir|
-  Dir.foreach(dir) do |file|
-    m = /Rechnung_(\d{2})\.(\d{2})\.(\d{4})\.zip(\.pgp|\.gpg)?/.match file
-    if m
-      s = system "mv #{dir}/#{file} #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip#{m[4]}"
-      s = system "gpg #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip#{m[4]}" if m[4]
-      system "rm #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip#{m[4]}" if s && m[4]
-      s = system "unzip #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip"
-      system "rm #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip" if s
-      puts "de-crypted & unpacked #{dst}/#{m[3]}-#{m[2]}-#{m[1]}-bill.zip"
-    end
-  end
-end
-
-# 2. rename unpacked files accordingly
-Dir.foreach(dst) do |file|
-  m = /^Rechnung_(\d{4})_(\d{2})_(.+)$/.match file
-  system "mv #{dst}/#{file} #{dst}/#{m[1]}-#{m[2]}-bill-#{m[3]}" if m
-  m = /^Einzelverbindungsnachweis_(\d{4})_(\d{2})_(.+)$/.match file
-  system "mv #{dst}/#{file} #{dst}/#{m[1]}-#{m[2]}-evn--#{m[3]}" if m
-  m = /^Rechnung_(\d{5,20})_(\d{2})_(\d{4})(.+)$/.match file
-  system "mv #{dst}/#{file} #{dst}/#{m[3]}-#{m[2]}-bill-#{m[1]}#{m[4]}" if m
-  m = /^Einzelverbindungsnachweis_(\d{5,20})_(\d{2})_(\d{4})(.+)$/.match file
-  system "mv #{dst}/#{file} #{dst}/#{m[3]}-#{m[2]}-evn--#{m[1]}#{m[4]}" if m
-end
-</pre>
+# 2. rename unpacked files accordingly
+Dir.foreach(dst) do |file|
+  m = /^Rechnung_(\d{4})_(\d{2})_(.+)$/.match file
+  system "mv #{dst}/#{file} #{dst}/#{m[1]}-#{m[2]}-bill-#{m[3]}" if m
+  m = /^Einzelverbindungsnachweis_(\d{4})_(\d{2})_(.+)$/.match file
+  system "mv #{dst}/#{file} #{dst}/#{m[1]}-#{m[2]}-evn--#{m[3]}" if m
+  m = /^Rechnung_(\d{5,20})_(\d{2})_(\d{4})(.+)$/.match file
+  system "mv #{dst}/#{file} #{dst}/#{m[3]}-#{m[2]}-bill-#{m[1]}#{m[4]}" if m
+  m = /^Einzelverbindungsnachweis_(\d{5,20})_(\d{2})_(\d{4})(.+)$/.match file
+  system "mv #{dst}/#{file} #{dst}/#{m[3]}-#{m[2]}-evn--#{m[1]}#{m[4]}" if m
+end
+```
 
  [1]: http://www.t-mobile.de/faq/1,1951,18-_,00.html
  [2]: http://www.gnupg.org/

+ 7 - 10
content/posts/2009-11-17-cute-idea.md

@@ -5,20 +5,17 @@ type: post
 date: 2009-11-17T10:43:43+00:00
 url: /2009/11/cute-idea/
 yourls_shorturl:
-  - http://s.mro.name/8
-language: en
+- http://s.mro.name/8
 categories:
-  - screendesign
+- de
+- screendesign
 tags:
-  - iPhone
-  - sync
+- iPhone
+- sync
 
 ---
 to trigger a refresh – just pull down the list:
 
-[<img class="aligncenter size-full wp-image-1385" title="IMG_1223" src="http://blog.mro.name/wp-content/uploads/2009/11/IMG_1223.PNG" alt="IMG_1223" width="320" height="480" srcset="http://blog.mro.name/wp-content/uploads/2009/11/IMG_1223.PNG 320w, http://blog.mro.name/wp-content/uploads/2009/11/IMG_1223-200x300.PNG 200w" sizes="(max-width: 320px) 100vw, 320px" />][1]
+{{< figure  src="/wp-content/uploads/2009/11/IMG_1223.PNG" caption="IMG_1223"  width="320"  height="480" >}}
 
-Seen in [NibiruTech Mobile RSS v1.2][2].
-
- [1]: http://blog.mro.name/wp-content/uploads/2009/11/IMG_1223.PNG
- [2]: http://www.nibirutech.com/product_MR.html
+Seen in [NibiruTech Mobile RSS v1.2](http://www.nibirutech.com/product_MR.html).

+ 58 - 43
content/posts/2009-11-28-upgrade-to-snow-leopard.md

@@ -5,60 +5,75 @@ type: post
 date: 2009-11-28T21:58:42+00:00
 url: /2009/11/upgrade-to-snow-leopard/
 yourls_shorturl:
-  - http://s.mro.name/36
-
-language: en
+- http://s.mro.name/36
 categories:
-  - sysadmin
+- en
+- sysadmin
 tags:
-  - git
-  - Graphviz
-  - iPhone
-  - MacPorts
-  - OS X
-  - SANE
-  - SenTestingKit
-  - Snow Leopard
-  - Twain
-  - XCode
+- git
+- Graphviz
+- iPhone
+- MacPorts
+- OS X
+- SANE
+- SenTestingKit
+- Snow Leopard
+- Twain
+- XCode
 
 ---
-  1. Mac OS X 10.6 Snow Leopard (partition 25G, HFS+ Journaled, Upper/Lower)
-  2. Mac OS X 10.5 Leopard (partition 25G, HFS+ Journaled, Upper/Lower)
-  3. partition userspace 100G, HFS+ Journaled, Upper/Lower <pre lang="bash">$ cat /etc/fstab
-# mount partition "userspace" as /Users
-UUID=D016E3FD-E322-3006-A8F5-D2348C6A5B7B	/Users	hfs	rw,auto</pre>
+1. Mac OS X 10.6 Snow Leopard (partition 25G, HFS+ Journaled, Upper/Lower)
+2. Mac OS X 10.5 Leopard (partition 25G, HFS+ Journaled, Upper/Lower)
+3. partition userspace 100G, HFS+ Journaled, Upper/Lower
+
+```bash
+$ cat /etc/fstab
+# mount partition "userspace" as /Users
+UUID=D016E3FD-E322-3006-A8F5-D2348C6A5B7B /Users  hfs rw,auto
+```
+
+4. create user &#8222;mig&#8220;
+5. TimeMachine restore Users + Settings
+6. delete user &#8222;mig&#8220;
+7. manually copy user &#8222;Shared&#8220;
+8. iPhone SDK 3.1.2 + XCode 3.2.1
+9. [modgenerator 1.5][1] plus [trick][2]
+
+```bash
+$ ln -s /Developer/usr/bin/momc /Developer/Library/Xcode/Plug-ins/XDCoreDataModel.xdplugin/Contents/Resources/momc
+```
+
+10. [git 1.6.5.2][3], manually add to `.bash_profile`:
 
-  4. create user &#8222;mig&#8220;
-  5. TimeMachine restore Users + Settings
-  6. delete user &#8222;mig&#8220;
-  7. manually copy user &#8222;Shared&#8220;
-  8. iPhone SDK 3.1.2 + XCode 3.2.1
-  9. [modgenerator 1.5][1] plus [trick][2] <pre lang="bash">$ ln -s /Developer/usr/bin/momc /Developer/Library/Xcode/Plug-ins/XDCoreDataModel.xdplugin/Contents/Resources/momc</pre>
+```bash
+export PATH=$PATH:/usr/local/git/bin
+```
 
- 10. [git 1.6.5.2][3], manually add to `.bash_profile`: <pre lang="bash">export PATH=$PATH:/usr/local/git/bin</pre>
+11. [Macports][4] / http://trac.macports.org/wiki/Migration
 
- 11. [Macports][4] / http://trac.macports.org/wiki/Migration <pre lang="bash">$ sudo port selfupdate
-$ sudo port install bcpp pwgen wget lftp fortune optipng graphviz ragel imagemagick
-$ sudo port clean --all installed
-$ sudo port -f uninstall inactive</pre>
+```bash
+$ sudo port selfupdate
+$ sudo port install bcpp pwgen wget lftp fortune optipng graphviz ragel imagemagick
+$ sudo port clean --all installed
+$ sudo port -f uninstall inactive
+```
 
- 12. [graphviz-2.25.20091129.0545.pkg][5]
- 13. [Textwrangler 3.0 (2538)][6]
- 14. [Gimp 2.6.7][7]
- 15. [NeoOffice 3.0.1][8]
- 16. [Evernote 1.5.2 (62233)][9]
- 17. [TrueCrypt 6.3a][10]
- 18. [Dropbox v0.6.570][11]
- 19. [Skype 2.8.0.722][12]
- 20. [Firefox 3.5,5][13]
- 21. [Miro Video Player 2.5.3 (775f9134)][14]
- 22. [wxMaxima-0.8.3 & Maxima-5.19.2.dmg][15]
- 23. [Twain SANE Scanner Support][16]
+12. [graphviz-2.25.20091129.0545.pkg][5]
+13. [Textwrangler 3.0 (2538)][6]
+14. [Gimp 2.6.7][7]
+15. [NeoOffice 3.0.1][8]
+16. [Evernote 1.5.2 (62233)][9]
+17. [TrueCrypt 6.3a][10]
+18. [Dropbox v0.6.570][11]
+19. [Skype 2.8.0.722][12]
+20. [Firefox 3.5,5][13]
+21. [Miro Video Player 2.5.3 (775f9134)][14]
+22. [wxMaxima-0.8.3 & Maxima-5.19.2.dmg][15]
+23. [Twain SANE Scanner Support][16]
 
 Remaining issues:
 
-  1. SenTestingKit error highlighting not working.
+1. SenTestingKit error highlighting not working.
 
  [1]: http://rentzsch.com/code/mogenerator_v1.5
  [2]: http://aralbalkan.com/2152

+ 39 - 38
content/posts/2009-12-03-nsdateformatter-case-sensitive-trap.md

@@ -5,56 +5,57 @@ type: post
 date: 2009-12-03T14:05:24+00:00
 url: /2009/12/nsdateformatter-case-sensitive-trap/
 yourls_shorturl:
-  - http://s.mro.name/3b
-
-language: en
+- http://s.mro.name/3b
 categories:
-  - development
+- en
+- development
 tags:
-  - Cocoa
-  - iPhone
-  - NSDateFormatter
-  - Objective C
-  - OS X
-  - SenTestingKit
-  - Unicode
+- Cocoa
+- iPhone
+- NSDateFormatter
+- Objective C
+- OS X
+- SenTestingKit
+- Unicode
 
 ---
 Though [NSDateFormatter behaves slightly different than documented][1], the following might even be correct, as strange as it might look (mind the last two lines):
 
-<pre lang="objc">-(void)testNSDateFormatterTrap
-{
-    NSDateFormatter *lower = [[[NSDateFormatter alloc] init] autorelease];
-    lower.dateFormat = @"yyyy-MM-dd HH:mm:SS ZZZ";
-
-    NSDateFormatter *upper = [[[NSDateFormatter alloc] init] autorelease];
-    upper.dateFormat = @"YYYY-MM-dd HH:mm:SS ZZZ";
-
-    lower.timeZone = upper.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
-
-    NSDate *d = [lower dateFromString:@"1970-01-01 00:00:00 +0000"];
-    STAssertEqualObjects(@"1970-01-01 00:00:00 +0000", [lower stringFromDate:d], @"lower iso wrong");
-    STAssertEqualObjects(@"1970-01-01 00:00:00 +0000", [upper stringFromDate:d], @"upper iso wrong");
-
-    d = [d addTimeInterval:(-60*60)];
-
-    STAssertEqualObjects(@"1969-12-31 23:00:00 +0000", [lower stringFromDate:d], @"lower iso wrong");
-    STAssertEqualObjects(@"1970-12-31 23:00:00 +0000", [upper stringFromDate:d], @"upper iso wrong");
-}</pre>
-
-The [Unicode Format Pattern Documentation][2] explains the difference of the upper- and lowercase year format &#8211; but frankly I don't get the &#8222;Year of week of year&#8220; idea.
-
-But that subtracting one hour in fact **adds almost a whole year** &#8211; that's odd to me.
-
-So I rather stay away from the uppercase form &#8211; be it correct or buggy.
+```objc
+-(void)testNSDateFormatterTrap
+{
+    NSDateFormatter *lower = [[[NSDateFormatter alloc] init] autorelease];
+    lower.dateFormat = @"yyyy-MM-dd HH:mm:SS ZZZ";
+
+    NSDateFormatter *upper = [[[NSDateFormatter alloc] init] autorelease];
+    upper.dateFormat = @"YYYY-MM-dd HH:mm:SS ZZZ";
+
+    lower.timeZone = upper.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
+
+    NSDate *d = [lower dateFromString:@"1970-01-01 00:00:00 +0000"];
+    STAssertEqualObjects(@"1970-01-01 00:00:00 +0000", [lower stringFromDate:d], @"lower iso wrong");
+    STAssertEqualObjects(@"1970-01-01 00:00:00 +0000", [upper stringFromDate:d], @"upper iso wrong");
+
+    d = [d addTimeInterval:(-60*60)];
+
+    STAssertEqualObjects(@"1969-12-31 23:00:00 +0000", [lower stringFromDate:d], @"lower iso wrong");
+    STAssertEqualObjects(@"1970-12-31 23:00:00 +0000", [upper stringFromDate:d], @"upper iso wrong");
+}
+```
+
+The [Unicode Format Pattern Documentation][2] explains the difference of the upper- and lowercase year format – but frankly I don't get the &#8222;Year of week of year&#8220; idea.
+
+But that subtracting one hour in fact **adds almost a whole year** – that's odd to me.
+
+So I rather stay away from the uppercase form – be it correct or buggy.
 
 Seen with iPhone SDK 3.1.2 and XCode 3.2.1 on Snow Leopard.
 
 **Update:**
 
-I think I got it! Uppercase YYYY makes sense only in combination with a calendar week &#8211; and not months or quarters.
+I think I got it! Uppercase YYYY makes sense only in combination with a calendar week  and not months or quarters.
 
-Look at January 1st 2010. It belongs to calendar week 53 of 2009. Week 1/2010 starts on Jan 4th.
+Look at January 1st 2010. It belongs to calendar week 53 of 2009. Week 1 / 2010 starts on Jan 4th.
 
  [1]: http://blog.mro.name/2009/08/nsdateformatter-http-header/
  [2]: http://unicode.org/reports/tr35/tr35-6.html#Date_Field_Symbol_Table

File diff suppressed because it is too large
+ 5 - 8
content/posts/2009-12-08-heute-nur-fur-stammgaste.md


+ 73 - 68
content/posts/2009-12-09-coredata-generic-findmanybykey.md

@@ -5,86 +5,91 @@ type: post
 date: 2009-12-09T03:32:34+00:00
 url: /2009/12/coredata-generic-findmanybykey/
 yourls_shorturl:
-  - http://s.mro.name/2x
-
-language: en
+- http://s.mro.name/2x
 categories:
-  - development
+- en
+- development
 tags:
-  - Cocoa
-  - CoreData
-  - iPhone
-  - NSEntityDescription
-  - NSManagedObject
-  - NSManagedObjectContext
-  - NSPredicate
-  - Objective C
+- Cocoa
+- CoreData
+- iPhone
+- NSEntityDescription
+- NSManagedObject
+- NSManagedObjectContext
+- NSPredicate
+- Objective C
 
 ---
 The base for many of my [SELECT][1]-ish queries when querying by exact match is one generic method I created in some [category methods][2] on [NSManagedObjectContext][3]:
 
-<pre lang="objc">-(NSArray*)entityName:(NSString*)entityName findManyByRelation:(NSDictionary*)dict
-{
-//  TODO handle dict nil and emptyness
-    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:dict.count];
-    for(NSString *key in dict)
-    {
-        NSExpression *left = [NSExpression expressionForKeyPath:key];
-        NSExpression *right = [NSExpression expressionForConstantValue:[dict objectForKey:key]];
-        NSComparisonPredicate *cp = [[NSComparisonPredicate alloc] initWithLeftExpression:left
-            rightExpression:right modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];
-        [arr addObject:cp];
-        [cp release];
-    }
-    NSPredicate *pred = nil;
-    if(arr.count == 1)
-        pred = [[arr objectAtIndex:0] retain];    // why do I have to retain here?
-    else
-        pred = [[NSCompoundPredicate alloc] initWithType:NSAndPredicateType subpredicates:arr];
-
-    NSFetchRequest *fr = [[NSFetchRequest alloc] init];
-    fr.entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
-    fr.predicate = pred;
-    [arr release];
-    [pred release];
-//	NSLog(@"predicate effective: %@", fr.predicate);
-
-    NSError *err = nil;
-    NSArray *ps = [self executeFetchRequest:fr error:&err];
-    if(err != nil)
-        [NSException raise:@"DB Error" format:@"Fetch problem %@", fr.predicate.predicateFormat];
-    [fr release];
-    return ps;
-}</pre>
+```objc
+-(NSArray*)entityName:(NSString*)entityName findManyByRelation:(NSDictionary*)dict
+{
+//  TODO handle dict nil and emptyness
+    NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:dict.count];
+    for(NSString *key in dict)
+    {
+        NSExpression *left = [NSExpression expressionForKeyPath:key];
+        NSExpression *right = [NSExpression expressionForConstantValue:[dict objectForKey:key]];
+        NSComparisonPredicate *cp = [[NSComparisonPredicate alloc] initWithLeftExpression:left
+            rightExpression:right modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0];
+        [arr addObject:cp];
+        [cp release];
+    }
+    NSPredicate *pred = nil;
+    if(arr.count == 1)
+        pred = [[arr objectAtIndex:0] retain];    // why do I have to retain here?
+    else
+        pred = [[NSCompoundPredicate alloc] initWithType:NSAndPredicateType subpredicates:arr];
+
+    NSFetchRequest *fr = [[NSFetchRequest alloc] init];
+    fr.entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
+    fr.predicate = pred;
+    [arr release];
+    [pred release];
+//  NSLog(@"predicate effective: %@", fr.predicate);
+
+    NSError *err = nil;
+    NSArray *ps = [self executeFetchRequest:fr error:&err];
+    if(err != nil)
+        [NSException raise:@"DB Error" format:@"Fetch problem %@", fr.predicate.predicateFormat];
+    [fr release];
+    return ps;
+}
+```
 
 For example it serves under the hood of it's sibling helpers
 
-<pre lang="objc">-(NSManagedObject*)entityName:(NSString*)entityName findByPrimaryKey:(NSDictionary*)dict
-{
-    NSArray *ps = [self entityName:entityName findManyByRelation:dict];
-    if(ps == nil || ps.count == 0)
-        return nil;
-    if (ps.count == 1)
-        return [ps objectAtIndex:0];
-    [NSException raise:@"DB Error" format:@"Multiple hits for %@", dict];
-    return (NSManagedObject*)1/0;
-}</pre>
+```objc
+-(NSManagedObject*)entityName:(NSString*)entityName findByPrimaryKey:(NSDictionary*)dict
+{
+    NSArray *ps = [self entityName:entityName findManyByRelation:dict];
+    if(ps == nil || ps.count == 0)
+        return nil;
+    if (ps.count == 1)
+        return [ps objectAtIndex:0];
+    [NSException raise:@"DB Error" format:@"Multiple hits for %@", dict];
+    return (NSManagedObject*)1/0;
+}
+```
 
 and
 
-<pre lang="objc">-(NSManagedObject*)entityName:(NSString*)entityName selectOrInsertWithKey:(NSDictionary*)dict
-{
-    NSManagedObject *o = [self entityName:entityName findByPrimaryKey:dict];
-    if(o == nil)
-    {
-        NSEntityDescription *ed = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
-        o = [[NSManagedObject alloc] initWithEntity:ed insertIntoManagedObjectContext:self];
-        for(NSString *key in dict)
-            [o setValue:[dict objectForKey:key] forKey:key];
-        [o autorelease];
-    }
-    return o;
-}</pre>
+```objc
+-(NSManagedObject*)entityName:(NSString*)entityName selectOrInsertWithKey:(NSDictionary*)dict
+{
+    NSManagedObject *o = [self entityName:entityName findByPrimaryKey:dict];
+    if(o == nil)
+    {
+        NSEntityDescription *ed = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
+        o = [[NSManagedObject alloc] initWithEntity:ed insertIntoManagedObjectContext:self];
+        for(NSString *key in dict)
+            [o setValue:[dict objectForKey:key] forKey:key];
+        [o autorelease];
+    }
+    return o;
+}
+```
 
 Those methods again are called by custom convenience wrappers in the [model classes][4] loosely following the [ActiveRecord Pattern][5].
 

File diff suppressed because it is too large
+ 96 - 76
content/posts/2010-05-21-xml-toolbox-relax-ng-trang.md


+ 96 - 84
content/posts/2011-08-05-rank-sqlite-text-search-results.md

@@ -5,118 +5,130 @@ type: post
 date: 2011-08-05T06:48:19+00:00
 url: /2011/08/rank-sqlite-text-search-results/
 yourls_shorturl:
-  - http://mro.name/4a
+- http://mro.name/4a
 yourls_tweeted:
-  - 1
+- 1
 flattrss_autosubmited:
-  - 'true'
-
-language: en
+- 'true'
 categories:
-  - development
+- en
+- development
 tags:
-  - iOS
-  - iPhone
-  - like
-  - Search
-  - SQL
-  - SQLite
+- iOS
+- iPhone
+- like
+- Search
+- SQL
+- SQLite
 
 ---
-When searching for text snippets in sql databases you might want to rank the results according to &#8222;how good did it match&#8220;. And: the ranking shouldn't make the query slower.
+When searching for text snippets in sql databases you might want to rank the results according to
+&#8222;how good did it match&#8220;. And: the ranking shouldn't make the query slower.
 
-Let's take a simple example using the [LIKE operator][1]. (I know, [FTS][2] does a better job, but let's stick to like for now).
+Let's take a simple example using the [LIKE operator][1]. (I know, [FTS][2] does a better job, but
+let's stick to like for now).
 
-Assume the search expression 'a bc de' and a table 'my_table' with text columns 'title' and 'description'.
+Assume the search expression 'a bc de' and a table 'my_table' with text columns 'title' and
+'description'.
 
 We want to find all rows with 'title' matching all three blank-separated parts of the search term:
 
 <!--more-->
 
-<pre lang="sql">SELECT rowid, title
-FROM my_table
-WHERE (title LIKE '%a%' AND title LIKE '%bc%' AND title LIKE '%de%')</pre>
+```sql
+SELECT rowid, title
+FROM my_table
+WHERE (title LIKE '%a%' AND title LIKE '%bc%' AND title LIKE '%de%')
+```
 
 **To sort them, we apply a bonus for parts matching the column start**:
 
-<pre lang="sql">SELECT rowid, title,
-    -- column start bonus
-    LIKE('a%', title) +
-    LIKE('bc%', title) +
-    LIKE('de%', title) +
-0 AS bonus
-FROM my_table
-WHERE ((title LIKE '%a%') AND (title LIKE '%bc%') AND (title LIKE '%de%'))
-ORDER BY bonus DESC, title ASC, rowid ASC</pre>
+```sql
+SELECT rowid, title,
+    -- column start bonus
+    LIKE('a%', title) +
+    LIKE('bc%', title) +
+    LIKE('de%', title) +
+0 AS bonus
+FROM my_table
+WHERE ((title LIKE '%a%') AND (title LIKE '%bc%') AND (title LIKE '%de%'))
+ORDER BY bonus DESC, title ASC, rowid ASC
+```
 
 Next, we'd like to add a (somewhat smaller) **bonus for word-starts**:
 
-<pre lang="sql">SELECT rowid, title,
-    -- column start bonus
-    LIKE('a%', title) * 2 +
-    LIKE('bc%', title) * 2 +
-    LIKE('de%', title) * 2 +
-    -- word start bonus
-    LIKE('% a%', title) * 1 +
-    LIKE('% bc%', title) * 1 +
-    LIKE('% de%', title) * 1 +
-0 AS bonus
-FROM my_table
-WHERE ((title LIKE '%a%') AND (title LIKE '%bc%') AND (title LIKE '%de%'))
-ORDER BY bonus DESC, title ASC, rowid ASC</pre>
+```sql
+SELECT rowid, title,
+    -- column start bonus
+    LIKE('a%', title) * 2 +
+    LIKE('bc%', title) * 2 +
+    LIKE('de%', title) * 2 +
+    -- word start bonus
+    LIKE('% a%', title) * 1 +
+    LIKE('% bc%', title) * 1 +
+    LIKE('% de%', title) * 1 +
+0 AS bonus
+FROM my_table
+WHERE ((title LIKE '%a%') AND (title LIKE '%bc%') AND (title LIKE '%de%'))
+ORDER BY bonus DESC, title ASC, rowid ASC
+```
 
 Rows **matching the three terms in order** get an even bigger bonus:
 
-<pre lang="sql">SELECT rowid, title,
-    -- correct order bonus
-    LIKE('%a%bc%de%', title) * 5 * 3 +
-    -- column start bonus
-    LIKE('a%', title) * 2 +
-    LIKE('bc%', title) * 2 +
-    LIKE('de%', title) * 2 +
-    -- word start bonus
-    LIKE('% a%', title) * 1 +
-    LIKE('% bc%', title) * 1 +
-    LIKE('% de%', title) * 1 +
-0 AS bonus
-FROM my_table
-WHERE ((title LIKE '%a%') AND (title LIKE '%bc%') AND (title LIKE '%de%'))
-ORDER BY bonus DESC, title ASC, rowid ASC</pre>
+```sql
+SELECT rowid, title,
+    -- correct order bonus
+    LIKE('%a%bc%de%', title) * 5 * 3 +
+    -- column start bonus
+    LIKE('a%', title) * 2 +
+    LIKE('bc%', title) * 2 +
+    LIKE('de%', title) * 2 +
+    -- word start bonus
+    LIKE('% a%', title) * 1 +
+    LIKE('% bc%', title) * 1 +
+    LIKE('% de%', title) * 1 +
+0 AS bonus
+FROM my_table
+WHERE ((title LIKE '%a%') AND (title LIKE '%bc%') AND (title LIKE '%de%'))
+ORDER BY bonus DESC, title ASC, rowid ASC
+```
 
 And finally adding the **match on 'description' secondary**:
 
-<pre lang="sql">SELECT rowid, title, description,
-    -- title is primary match:
-    -- correct order bonus
-    LIKE('%a%bc%de%', title) * 50 * 3 +
-    -- column start bonus
-    LIKE('a%', title) * 20 +
-    LIKE('bc%', title) * 20 +
-    LIKE('de%', title) * 20 +
-    -- word start bonus
-    LIKE('% a%', title) * 10 +
-    LIKE('% bc%', title) * 10 +
-    LIKE('% de%', title) * 10 +
-    -- description is secondary match:
-    -- correct order bonus
-    LIKE('%a%bc%de%', description) * 5 * 3 +
-    -- column start bonus
-    LIKE('a%', description) * 2 +
-    LIKE('bc%', description) * 2 +
-    LIKE('de%', description) * 2 +
-    -- word start bonus
-    LIKE('% a%', description) * 1 +
-    LIKE('% bc%', description) * 1 +
-    LIKE('% de%', description) * 1 +
-0 AS bonus
-FROM my_table
-WHERE ((title       LIKE '%a%') AND (title       LIKE '%bc%') AND (title       LIKE '%de%'))
-OR    ((description LIKE '%a%') AND (description LIKE '%bc%') AND (description LIKE '%de%'))
-ORDER BY bonus DESC, title ASC, description ASC, rowid ASC</pre>
+```sql
+SELECT rowid, title, description,
+    -- title is primary match:
+    -- correct order bonus
+    LIKE('%a%bc%de%', title) * 50 * 3 +
+    -- column start bonus
+    LIKE('a%', title) * 20 +
+    LIKE('bc%', title) * 20 +
+    LIKE('de%', title) * 20 +
+    -- word start bonus
+    LIKE('% a%', title) * 10 +
+    LIKE('% bc%', title) * 10 +
+    LIKE('% de%', title) * 10 +
+    -- description is secondary match:
+    -- correct order bonus
+    LIKE('%a%bc%de%', description) * 5 * 3 +
+    -- column start bonus
+    LIKE('a%', description) * 2 +
+    LIKE('bc%', description) * 2 +
+    LIKE('de%', description) * 2 +
+    -- word start bonus
+    LIKE('% a%', description) * 1 +
+    LIKE('% bc%', description) * 1 +
+    LIKE('% de%', description) * 1 +
+0 AS bonus
+FROM my_table
+WHERE ((title       LIKE '%a%') AND (title       LIKE '%bc%') AND (title       LIKE '%de%'))
+OR    ((description LIKE '%a%') AND (description LIKE '%bc%') AND (description LIKE '%de%'))
+ORDER BY bonus DESC, title ASC, description ASC, rowid ASC
+```
 
 You get the idea.
 
-Funny thing is &#8211; the whole ranking logic doesn't hit performance (at least for small texts in the two columns)!
+Funny thing is  the whole ranking logic doesn't hit performance (at least for small texts in the two columns)!
 
 So, key is:
 

+ 63 - 62
content/posts/2013-11-26-uicolor-from-hex-string-once-again.md

@@ -5,73 +5,74 @@ type: post
 date: 2013-11-26T09:51:37+00:00
 url: /2013/11/uicolor-from-hex-string-once-again/
 yourls_shorturl:
-  - http://mro.name/4h
-
-language: en
+- http://mro.name/4h
 categories:
-  - development
+- en
+- development
 tags:
-  - Cocoa
-  - Hex
-  - NSString
-  - Objective C
-  - UIColor
+- Cocoa
+- Hex
+- NSString
+- Objective C
+- UIColor
 
 ---
-I end up doing this once per year &#8211; at least it's getting leaner each time.
+I end up doing this once per year – at least it's getting leaner each time.
+
+```objc
+static inline NSInteger NSIntegerFromHexDigit(const unichar c)
+{
+  switch( c ) {
+  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
+    return c - '0';
+  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    return c - 'a' + 10;
+  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+    return c - 'A' + 10;
+  default:
+    return -1;
+  }
+}
+
+typedef NSUInteger RGBA32;
+
+/** RGBA hex color matching /^(?:0x|#)?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i
+ */
+static BOOL RGBAFromNSStringHex(NSString *hex, RGBA32 *value)
+{
+  const NSUInteger len = hex.length;
+  if( len < 6 || len > 9 )
+    return NO;
+  unichar buffer[len];
+  [hex getCharacters:buffer range:NSMakeRange(0, len)];
+
+  // check if either 6 or 8 char hex
+  const BOOL hasHashPrefix = buffer[0] == '#';
+  const NSInteger netlen = len - hasHashPrefix;
+  if( netlen != 6 && netlen != 8 )
+    return NO;
+
+  // turn hex to integer
+  NSUInteger ret = 0;
+  assert(sizeof(ret) >= 4); // need at least 4 bytes
+  for( NSInteger i = hasHashPrefix; i < len; i++ ) {
+    const NSInteger v = NSIntegerFromHexDigit(buffer[i]);
+    if( v < 0 )
+      return NO;
+    ret <<= 4;
+    ret |= v;
+  }
+  // if 6-char hex assume alpha 0xFF
+  if( netlen == 6 ) {
+    ret <<= 8;
+    ret |= 0xFF;
+  }
 
-<pre lang="objc" line="1">static inline NSInteger NSIntegerFromHexDigit(const unichar c)
-{
-  switch( c ) {
-  case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
-    return c - '0';
-  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-    return c - 'a' + 10;
-  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-    return c - 'A' + 10;
-  default:
-    return -1;
-  }
-}
-
-typedef NSUInteger RGBA32;
-
-/** RGBA hex color matching /^(?:0x|#)?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i
- */
-static BOOL RGBAFromNSStringHex(NSString *hex, RGBA32 *value)
-{
-  const NSUInteger len = hex.length;
-  if( len &lt; 6 || len &gt; 9 )
-    return NO;
-  unichar buffer[len];
-  [hex getCharacters:buffer range:NSMakeRange(0, len)];
-
-  // check if either 6 or 8 char hex
-  const BOOL hasHashPrefix = buffer[0] == '#';
-  const NSInteger netlen = len - hasHashPrefix;
-  if( netlen != 6 && netlen != 8 )
-    return NO;
-
-  // turn hex to integer
-  NSUInteger ret = 0;
-  assert(sizeof(ret) &gt;= 4); // need at least 4 bytes
-  for( NSInteger i = hasHashPrefix; i &lt; len; i++ ) {
-    const NSInteger v = NSIntegerFromHexDigit(buffer[i]);
-    if( v &lt; 0 )
-      return NO;
-    ret &lt;&lt;= 4;
-    ret |= v;
-  }
-  // if 6-char hex assume alpha 0xFF
-  if( netlen == 6 ) {
-    ret &lt;&lt;= 8;
-    ret |= 0xFF;
-  }
-
-  if( value )
-    *value = ret;
-  return YES;
-}</pre>
+  if( value )
+    *value = ret;
+  return YES;
+}
+```
 
 How to get a [UIColor][1] from here should be straightforward.