Added scripting access to rich text with html content
Added warning when editing rich text in unsupported document formats
Disable text formatting if the file format can’t save it
Changed block mode selection color
Improving overall styling performance
Fixed rich text typing attributes to work like standard macOS
Fixed rich text commands in outline mode
Fixed selection drawing
Scripting support for text formatting looks like this:
tell front document of application "Bike"
set html content of first row to "<p><strong>Hello</strong> world</p>"
end tell
This API is nice because it’s simple to implement and maps directly to Bike’s file format behavior. It’s also very convent for setting a rows text.
It’s less convenient for editing an existing rows text … because to do it right (might be able to fake with simple string manipulation for many cases) you’ll need to parse existing html content make updates to DOM, serialize back to string, and then set new html content. If this is makes things to hard I’ll look at additional scripting API.
I think this version is feature complete for what I want from “Rich text” right now. I would like to release this soon, though I still need updated documentation, screenshots, etc. Please check for bugs and let me know what needs to be done before this release exits preview status.
To get preview releases through Bike’s software update select: Bike > Preferences > General > Include “preview” releases.
(() => {
"use strict";
// HTML parsing example
// Rob Trew @2020
// main :: IO ()
const main = () =>
// Just drop the tags and extract the text leaves,
// in this case.
htmlForest(
"<p><strong>Hello</strong> world</p>"
)
.map(
foldTree(
x => xs => (
Boolean(x.content) ? (
[x.content]
) : []
).concat(xs.flat())
)
);
// ------------------- PARSED HTML -------------------
// htmlForest :: HTML String ->
// [Tree {name::String, content::String}]
const htmlForest = html =>
either(() => [])(x => x.nest)(
dictFromHTML(html)
);
// dictFromHTML :: String -> Either String Tree Dict
const dictFromHTML = html => {
const
error = $(),
node = $.NSXMLDocument.alloc
.initWithXMLStringOptionsError(
html, 0, error
);
return Boolean(error.code) ? (
Left("Not parseable as XML: " + (
`${html}`
))
) : Right(xmlNodeDict(node));
};
// xmlNodeDict :: NSXMLNode -> Node Dict
const xmlNodeDict = xmlNode => {
const
unWrap = ObjC.unwrap,
blnChiln = parseInt(
xmlNode.childCount, 10
) > 0;
return Node({
name: unWrap(xmlNode.name),
content: blnChiln ? (
undefined
) : unWrap(xmlNode.stringValue)
})(
blnChiln ? (
unWrap(xmlNode.children)
.reduce(
(a, x) => a.concat(xmlNodeDict(x)),
[]
)
) : []
);
};
// --------------------- GENERIC ---------------------
// Left :: a -> Either a b
const Left = x => ({
type: "Either",
Left: x
});
// Node :: a -> [Tree a] -> Tree a
const Node = v =>
// Constructor for a Tree node which connects a
// value of some kind to a list of zero or
// more child trees.
xs => ({
type: "Node",
root: v,
nest: xs || []
});
// Right :: b -> Either a b
const Right = x => ({
type: "Either",
Right: x
});
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = fl =>
// Application of the function fl to the
// contents of any Left value in e, or
// the application of fr to its Right value.
fr => e => e.Left ? (
fl(e.Left)
) : fr(e.Right);
// foldTree :: (a -> [b] -> b) -> Tree a -> b
const foldTree = f => {
// The catamorphism on trees. A summary
// value obtained by a depth-first fold.
const go = tree => f(
tree.root
)(
tree.nest.map(go)
);
return go;
};
// sj :: a -> String
const sj = (...args) =>
// Abbreviation of showJSON for quick testing.
// Default indent size is two, which can be
// overriden by any integer supplied as the
// first argument of more than one.
JSON.stringify.apply(
null,
1 < args.length && !isNaN(args[0]) ? [
args[1], null, args[0]
] : [args[0], null, 2]
);
return sj(main());
})();
Expand disclosure triangle to view post-processed parse result
[
[
"Hello",
" world"
]
]
Expand disclosure triangle to view full parse result
Aha, unless you change the editor font in the preferences. I changed mine to Charter, and apply code formatting did nothing. I was expecting it to shift to Menlo or another monospace font as it does when using the system font.
Code-tagged spans are no longer displayed in a monospaced font when the main font is set to something other than System
as soon as we revert to using the System font (with Reset Typography in Preferences) any code-tagged spans immediately become monospaced (and thus visibly distinct) again.
As one of the users that voted for the Rich Text feature, I wanted to try it out but it looks like it requires a license first. Should I wait to try it out once it’s released?
If you buy a license from Hog Bay Software website you’ll get a year of free updates. So you can buy a license now and try the preview, and also get the preview.
Alternatively once the rich text release is ready I’ll post it to the Mac App Store. Then you can try out the rich text by getting a $2.99 monthly subscription. That gives you a cheaper way to try it, and then you can cancel after one month and get a longer term license if you want.
Good find! I’m not sure, but I don’t think this is related to your font (I guess try changing to “System” to see). I think I must have hard coded the UI scale somewhere. Are you using a non retina display or have some non default display scaling?
Ah, you’re right, it’s the display! I’m using a Retina MBP with the lid closed, connected to an Acer X34 monitor at 3440x1440, and the problem disappears if I unplug the external display and use the built-in one.
Bike 1.4 Preview (67).
(And just to rule it out, I also “Reset Typography” and restarted Bike, but it didn’t fix anything.)
I’m trying to add attributes that have a meaning behind them (and ideally map nicely to an HTML attribute). Specific text colors are also problematic when switching between light and dark mode.
Can you describe a little more what you are trying to do?
I do think that eventually Bike will enable what you want. It won’t add ability to set a specific text color, instead it will (I think) allow you to set a specific text attribute that you define (for example maybe priority1, priority2, priority3) and then in your stylesheet you could set a separate color for each priority level).
I don’t have a timeline yet for custom stylesheets. I’ve done a lot of work on them already for the rich text support, but there’s also a big chunk of work that remains to make them user editable. And I’m likely to be working on other features for a while before I get to them.
It seems this may be a bit of a specialist request, but it is something that is always uppermost in my mind when evaluating writing tools. I use colour a lot as a way of visually coding the significance of words, clauses or sections of text. For instance in writing comparative listings of software I will colour advantages of a particular app in green and disadvantages in red. Other significance codings may be broader, using up to 5 or 6 colours. I like how visually immediate such colouring is, turning the text into a form of infographic—or adding a visual layer to the layer of meaning contained within the text. (It is possible that being synasthetic makes this particularly attractive to me.) I prefer using text colour to highlighting since I find highlighting too visually emphatic.
I hope that explains the need. The process is less significant to me. I have used tags to style colours in TaskPaper for a long time, and while I’d prefer to dispense with the inline tags just to create styles, I’d be happy to use scripts or anything else that could be mapped to a keyboard shortcut, so long as the resulting (colour) styles could coexist with bold/italic etc.
I hope this answer to your question is not too wordy for this topic. Feel free to hive it off to its own topic.
Thanks, Nick
Perhaps, in that that context, this application might look like a variety of highlighter pen colors (e.g. perhaps orange, green in addition to yellow), and take the form, for the stylesheet, of distinct classes for the <mark> tag ?
I don’t think that will work. Highlight color is already used for selection highlight color, so it would be confusing to use for Bike’s highlight too.
I’m starting to think that at some point I’ll add a fixed set of highlight color options that are part of the underlying model, similar to how finder has a set of colors for tagging items. Probably this is a future feature, instead of one that I’ll add this release.