Skip to main content

Tech

Broken feed

1 min read

In the feed I had this check, the same for displaying posts:

last_updated = time_from_string(post[:datetime])
# Skip post if date is invalid or in the future
next if last_updated == nil || DateTime.now.to_time < last_updated

which worked properly for the site, but for the feed I was getting this error:

undefined method `w3cdtf' for class `ActiveSupport::TimeWithZone`

which was happening when I was setting the item.updated field to last_updated. The fix was pretty easy (and obvious, now, after I fixed it) - just convert the returned object to_time:

def time_from_string(string)
  [...]
  DateTime.new(date_matches[1].to_i, date_matches[2].to_i, date_matches[3].to_i, time[:hour], time[:min], 0, time[:zone]).in_time_zone.to_time
end

Improving the images

2 min read

I have on site several kinds of images, but since I write my posts in Markdown, and I want to make use of its native features, the images created this way have no class. So I had to find a way to style these imgs.

First step, CSS:

img {
  border-radius: 2px;
  -webkit-box-shadow: #777 0 0 3px 1px;
  -moz-box-shadow: #444 0 0 3px 1px; /* color, h-offset, v-offset, blur, spread */
  box-shadow: #777 0 0 7px 0; /* inset is optional */
  
  // This will center the images inside posts.
  &:not([class]) {
    margin: 0 auto;
    display: table;
  }
}

But the problem here is with images that are wider than the article's width. Second step, jQuery:

Continue reading →

Fixing the search #2

25 sec read

Previously I said I had to scan the hrefs for my search-mark spans, but I forgot my assets:

content.scan(/\/assets\/.*?"/).each do |s|
  edited_link = s.gsub('<mark class=\'search\'>', '')
  edited_link.gsub!('</mark>', '')
  content.gsub!(s, edited_link)
end

Sadly, I didn't find a proper way to skip URLs, so I have to scan several times to remove search-mark from them :(

GitUp

25 sec read

I recently stumbled upon GitUp. It's a pretty nice git GUI, with a ton of features, nifty keyboard shortcuts for almost everything, and minimal interface. The only downsides are that it doesn't display the commits next to the working tree, you have to click on them, and that you can't open pull requests on GitHub, like the GitHub Mac app, or SourceTree do. When / if these get implemented, I might just use GitUp as my git GUI.

GitUp screenshot

Terminal improvements for git

1 min read

Improvement #1: adding the current branch name after the current path. Add this in your .bash_profile file:

parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
 
export CLICOLOR=1
export LSCOLORS=GxFxCxDxBxegedabagaced
export PS1='\[\e[0;32m\]\u\[\e[0m\]:\[\e[0;33m\]\w\[\e[0m\]\[\e[0;35m\]$(parse_git_branch)\[\e[0m\]$ '

And the outcome is user:path (branch_name) $ . The user is green, the path is yellow, the branch_name is purple and everything else is white.

Improvement #2: autocompletion for branch names. Again, add this in your .bash_profile file:

if [ -f ~/.git-completion.bash ]; then
  . ~/.git-completion.bash
fi

I find these pretty useful. Actually, I find them indispensable after a prolonged use. Don't forget to tweak the colors to your own preferences.

Fixing the search

1 min read

First of all, I changed the <search-mark> tag to <span class='search-mark'>. Secondly, I'm properly adding the search-mark to all occurrences of the searched term, instead of only the first (silly me). Lastly, I search the content again to remove the search-mark from inside hrefs:

start_index = content.downcase.index(w)
end_index = start_index + w.length
original_occurrence = content[start_index..end_index - 1]
content.gsub!(/#{original_occurrence}/i, '<span class=\'search-mark\'>\0</span>')
content.scan(/href=".*?"/).each do |s|
  edited_link = s.gsub('<span class=\'search-mark\'>', '')
  edited_link.gsub!('</span>', '')
  content.gsub!(s, edited_link)
end

Print calling function

1 min read

Sometimes you need to find out what called a method. StackOverflow helped me find an answer:

public func printCallingFunction() {
  let syms = Thread.callStackSymbols()
	
  if !syms.isEmpty {
    var sourceString = syms[2] as? String ?? ""
    var separatorSet = CharacterSet(characters: " -[]+?.,")
    var array = sourceString
      .componentsSeparated(by: separatorSet)
      .filter() { !$0.isEmpty }
  }
 
  // 3 is the class, 4 is the method.
  print("--- \(array[3]) - \(array[4])");
}

There's also this approach, but I don't really like it:

Continue reading →

Formatters

2 min read

Since creating formatters is very expensive, it's a good idea to have a singleton for them. But what if you have a standard style throughout the app, except a couple of places? Encapsulate it in a Static struct and set the required settings before returning:

struct Utils {
  
  class var numberFormatter: NumberFormatter {
    struct Static {
      static let formatter = NumberFormatter()
    }
  	
    Static.formatter.maximumFractionDigits = 2
    Static.formatter.alwaysShowsDecimalSeparator = false
  		
    return Static.formatter
  }
  
}

Then in the places with a different style:

Continue reading →

Autoresizing mask and frames

Now it seems obvious, and I feel silly about it, but setting a view's autoresizingMask's before setting its frame or bounds, makes the resizing not work properly.

Finally fixed the timezone

3 min read

In a recent change I tried to handle the time zone like this:

def time_from_string(string)
  date_matches = string.match(/(\d{4})-(\d{2})-(\d{2})-(\d{4})/)
  Time.zone = 'Bucharest'
  time_zone = Time.zone.formatted_offset
  # A little hack to account for daylight savings of when the post was created
  time_zone = '+03:00' if Time.strptime("#{date_matches}", '%Y-%m-%d-%H%M').dst?
  time = Date._strptime("#{date_matches[4]} #{time_zone}", '%H%M %:z')
  
  DateTime.new(date_matches[1].to_i, date_matches[2].to_i, date_matches[3].to_i, time[:hour], time[:min], 0, time[:zone]).in_time_zone
end
Continue reading →