I got this working by using the Repeat component instead of Capture in hourReg and minuteReg.
I'm not sure why that should matter, but Repeat is cleaner. I also got the transform to work by returning a Substring in the transform: of the ampmReg Regex.
import Cocoa
import Foundation
import RegexBuilder
let hourRef = Reference<Substring>()
let minuteRef = Reference<Substring>()
let hourReg = Regex {
Capture(as: hourRef) {
ChoiceOf {
Repeat(.digit, count: 2)
Repeat(.digit, count: 1)
}
}
}
let minuteReg = Regex {
Capture(as: minuteRef) {
ChoiceOf {
Repeat(.digit, count: 2)
Repeat(.digit, count: 1)
}
}
}
let ampmRef = Reference<Substring>()
let ampmReg = Regex {
Capture(as: ampmRef) {
ChoiceOf {
One("am")
One("pm")
One("a.m.")
One("p.m.")
}
} transform: {
return Substring($0.lowercased())
}
}.ignoresCase()
let timeWithoutSec = Regex {
hourReg
One(":")
minuteReg
ZeroOrMore(.whitespace)
ampmReg
}.ignoresCase()
let possibleTime = "1:20pM"
let timeMatchWithout = possibleTime.firstMatch(of: timeWithoutSec)
However, this version requires an 'am', 'pm' , 'a.m.', or 'p.m.' to be part of the string. To make this optional
I tried to change the timeWithoutSec Regex to:
let timeWithoutSec = Regex {
hourReg
One(":")
minuteReg
ZeroOrMore(.whitespace)
ZeroOrMore {
ampmReg
}
}.ignoresCase()
But this results in that odd Regex.Match optional storedCapture contains no some error message.
How can I make the ampmReg optional?
Post
Replies
Boosts
Views
Activity
I just noticed that I could make the error go away if I remove the transform. But why does that matter. I still don't understand that error message.
Unfortunately NSTableView does not respond to layoutIfNeeded. But your suggestion led me into lookingat other possibilities.Instead of doing the selectRowIndexes: after the reloadData I set a BOOL flag, needsReselect.Then in the delegate tableView:objectValueForTableColumn:row: method I put this code:// If we are updating the table content at row 0 and we need to reset the selection to row 0
// then do that now.
if ((rowIndex == 0) && needsReselect) {
// Select row 0.
[objectCoordTable selectRowIndexes: [NSIndexSet indexSetWithIndex: 0] byExtendingSelection: NO];
// Get the rectangle for the table contents.
CGRect r = objectCoordTable.superview.layer.contentsRect;
// Narrow the rect to an area that is part of row 0.
NSRect row0 = NSMakeRect(0.0, r.size.height - 10.0, r.size.width, 5.0);
// Scroll to that rect
[objectCoordTable.superview scrollRectToVisible:row0];
needsReselect = NO;
}This seems a little more obvious that using a dispatch queue and it seems to work. Note that I had to explicitly resetthe scroll as well. I checked, and if I'm not in the middle of the tableView:objectValueForTableColumn: the scolladjusts without need to control it explicitly.It would be nice if there was a delegate method to mark the end of a reloadData, or an NSNotification about it.Thanks for the help.
The May 23 answer is baically the correct answer and the wikipedia reference is what I used to develop my code.Knowing x and y isn't exactly what one needs of course and you don't know what x,y you are looking for either.Instead one wishes to place each glyph a certain distance from the previous glyph, depending of glyphbounding boxes. So what one really needs is the distance along the bezier curve. To address this I usedthe bezier formula to sample a number of points between each segment of the bezier and then approximatethe curve with straight lines whose lengths I use to compute accumulated distance along the the curve.I then find the two points on the bezier that bound the required distance and interpolate to achivethe final x,y. This is an approximation but is plenty good enough if the curve is sampled well enough.