Bike: adding Notes capability

I am against notes as some separate field or different mode.
The ideal of a simple outliner is the closer to a piece of paper it is. When you plan something on paper you don’t “Switch into a note mode”, you just write. The same is in Bike atm - I put notes about a point just one level deeper.
On paper, however, you can cross out… and this is what I’d love :wink:

5 Likes

Can’t you just put notes about a point one level deeper in structure? Like this:

OUTLINE

Point 1
Point 2

Notes about point 2

4 Likes

@Jerzy_Golota If you are only concerned with Bike then your suggestion works fine. But in my case I’m typically going from an outliner to something else. Typically that something else is iThoughts (a mind mapping app). Within the realm of mind maps, and OPML, “notes” is a kind of special designation. (Not sure of geek speak for this.)

Put differently, your suggesting results in one more additional node when I go from outline to mind map. Having OPML-compliant notes results in a note embedded within a specific node in the map. It’s an entirely different result. If I did notes as you suggested then I’d end up with a lot of cleaning up to do when transferred to a mind map application (as one example)

1 Like

iThoughts uses the convention (not part of the OPML standard, and introduced, I think, by the writers of OmniOutliner) of a textual _note attribute in addition to the standard text attribute.

The value of _note can be several paras, delimited by 
 (linefeed)

I’m personally not keen on this title + paras structure, which descends, I think from email, and loses some of the power of full and consistent outline structure, but …

a pair of custom import and export scripts for Bike might be able to roundtrip that (OPML -> Bike -> OPML) by:

  1. importing any _note attribute paragraph(s) as initial children of the parent node (without any children themselves, and starting + ending with some kind of parenthesis like ( ... note items ... ) or [ ... note items ... ]
  2. Exporting any (childless and parenthesised) initial children of a Bike item to OPML as the (
 – delimited) value of a _note attribute.

Otherwise, perhaps just use the convention that the first one or more children of any item can be:

  1. childless, and
  2. parenthesised to mark a special role ?

Later, as Bike HTML attributes and format develop, it may be possible for some initial childless children of a note to have a special note format ?
(and make that exportable to an OPML _note attribute ?)

I agree that a script is the right solution for now, and maybe for always.

I agree that a script is the right solution for now, and maybe for always.

I may take a look at sketching out a pair of scripts like that in a day or two.

How are you thinking of doing it? While I think script is right solution here, I also think such a script might be painful to implement at moment, at least from AppleScript scripting context. You would need parse/write OPML.

If I add read/write access to row attributes then might be easier to write scripts that transform outline representation between iThoughts notes form and standard Bike form… and then use Bike’s built in OPML read/write functionality.

Maybe it’s not as hard as I think, or you have another plan. If not I can try to prioritize scripting access to attributes. Let me know.

With NSXMLDocument methods it should be fairly direct – I’ll test that hypothesis to make sure :slight_smile:

e.g. for the simpler case:

Expand disclosure triangle to view JS Source
// treesFromOPML :: OPML String -> [Tree Dict]
const treesFromOPML = strOPML => {
    // A Tree of dictionaries with at least a 'text' key,
    // and potentially some other keys too.
    
    const unwrap = ObjC.unwrap;

    // go :: [NSXMLElement] -> [Tree Dict]
    const go = elems =>
        elems.map(element => {
            const children = unwrap(element.children);
            
            return Node(
                Array.from(unwrap(element.attributes))
                .reduce(
                    (a, x) => Object.assign(
                        a, {
                            [unwrap(x.name)]: unwrap(
                                x.stringValue
                            )
                        }
                    ), {}
                )
            )(
                children ? go(children) : []
            );
        });

    return go(ObjC.unwrap(
        $.NSXMLDocument.alloc.initWithXMLStringOptionsError(
            strOPML, 0, null
        ).rootElement.childAtIndex(1).children
    ));
};

but always grateful for more scripting API …

Ah right. I always forget (and don’t fully understand) how Objective-c stuff is available in that context.

I’ll see how easy it is. I wanted to hold off until there was also a way to access row attributes in the GUI, but now I think might be useful in other cases.

1 Like

@mitchellm what is your typical (or ideal) use case ?

  • You copy from Bike and paste to iThoughts ?
  • Or save the whole file as OPML and import to iThoughts ?
  • Something else ?

@complexpoint Thanks for looking into developing a script! I’ve done a few experiments and it seems the “smoothest” way to do things is to copy from Bike and paste into iThoughts.

I’m a “script dummy” … just learning about Shortcuts now. So once you have something you are happy with I may need a wee bit of hand-holding regarding how to implement it.

1 Like

Copying from Bike as OPML is fine, but it turns out that iThoughts doesn’t know how to paste an OPML clipboard – it only knows how to open an OPML file.

Paste to iThoughts is fine for pure outlines (it reads the plain text part of the clipboard) but for outlines with notes, it’ll have to be a:

  • Save As OPML with Notes, or
  • Save Selection As OPML with Notes

at the Bike end, and a opml file open at the iThoughts end, I’m afraid.


FWIW same goes for MindNode – it can read OPML files, but its clipboard handling is limited (like iThoughts) to plain text + a proprietary app-specific data format which is non-textual.


iThoughts pasteable clipboard content types:

["com.toketaware.ithoughts.itmz", "public.utf8-plain-text"]

MindNode pasteable clipboard content types:

["com.ideasoncanvas.mindnode.canvasObjects", "public.rtf", "public.utf8-plain-text", "public.utf16-external-plain-text"]
Expand disclosure triangle to view JS test code
// Run after copying from an app:
ObjC.import("AppKit");

ObjC.deepUnwrap(
	$.NSPasteboard.generalPasteboard.pasteboardItems.js[0].types
)
1 Like

To add my $0.02 to this – I’m a big fan of notes for outline rows and I use them heavily in my current outliner of choice, Dynalist. I find it really helpful to differentiate between information “about” a row and child rows, and there’s a shortcut (Shift-Enter) to toggle between the row itself and its note, creating it if it doesn’t exist.

One example is when writing up todo lists for projects, where a row representing a task might have both context (why are we doing this, so I don’t forget) and child tasks, and those seem like fundamentally different concepts:

I think an aside element would probably represent that well structurally, but equally adding row styles/tags/you-name-it and just having it as a child row of a certain format (muted, smaller, grey) would probably work okay for my use case – but it wouldn’t feel quite “right” structurally because it’s not really a parent-multiple children relationship. Plus as others have pointed out, having notes as a “first class” concept can also be helpful if you transform the outline into some other kind of document (such as a mindmap).

So a big +1 from me, and I do think it’s the kind of feature that can completely get out of the way of those who don’t want to use it :slight_smile:

2 Likes

Possibly …

tho I notice that in practice, if you copy and paste from annotated OmniOutliner to iThoughts, for example, the annotations just become structural subnodes anyway.


Distinguishing architecturally between different node relationships has a cost – the “notes” of a “subject” are no longer outlinable in that model.

If, instead, we just flag some nodes with special type attributes (e.g. note, as in the very successful TaskPaper model), and make those differences visible through a stylesheet, then we don’t have to lose their outlinability, or add code for two types of editor within one application.

3 Likes

Adding my vote for H1, H2, etc. headings to be available as formatting. In a couple long outlines I have it would help visually separate sections.

2 Likes

I’ll throw my hat in the ring to suggest that you should not add support for H1, H2, H3. The problem is that one’s position in an outline is always relative, whereas heading tags like this always count from the root. This creates a lot of opportunity for time-wasting refactorings, e.g. if you choose to move a subtree higher in the outline…

I think it could make sense to have some kind of heading tag, but there should be no significance to the heading-level; ideally, all headings would be <H1> but perhaps their formatting would depend on how they are nested. This was actually originally the intention of HTML5, but this aspect of HTML5 was never correctly implemented by vendors so it was abandoned (see here for some discussion: HTML 5's headings outline algorithm - ADG). In my personal notes, I have also written about the importance of relative hierarchy: absolute vs. relative hierarchy in document markup languages | Jon Sterling's Forest.

What if there was an option to simply apply automatic heading tags/styling? No manual intervention required when moving content.

Not sure that’s the best option either, but I don’t see a lot of downside.

2 Likes

It sounds potentially cool! Just to say, I have personally been avoiding most formatting except a bit of bold here and there, and find that it works pretty well for me. So I like the simplicity of the tool and its formatting facilities as it is, and hesitate to call for increasing the complexity of this aspect…

1 Like

That’s definitely a cleaner way to do things, and is the model that TaskPaper takes. Maybe it’s what I’ll do in Bike too. The problem though is that it enforces outline structure on your writing which might not always be wanted. For example I could imagine creating an outline structure like:

  • document1
    • H1
    • P
    • H2
  • document2

That is in some parts of my outline I would use outline structure to organize things. In other parts of my outline I would edit using a flat unindented rich text style.

Anyway I’m not working on this yet, but good to think about.

Related it would be very nice to have a clean mapping between Markdown and Bike. So you could open a Markdown file in Bike, make some edits, and then save it back as Markdown. And the hard part is having both the editing version in Bike, and the saved Markdown from Bike look natural to their format/environment.

2 Likes

An important point I agree with and think deserves emphasis. While formatting can add clarity to text¹, the use of which is to embody meaning, it can also project a theatrical effect that upstages meaning. Any formatting added to something as deliberately elegant in its direct and simple handling of words should be carefully weighed against the inherently misleading use of emphatic text formats: we tend to write louder and more emphatically when we don’t write good. To me, Bike is and will always be a writing tool; it is not and will never be a publishing tool. I encourage the developer and the community to only add complexity that helps us write better, think better, and communicate textual meaning better².

¹Someone posted in favor of heading formats for paragraphs because it would help them orient the reader of their outline. My experience with Bike in the single afternoon I used it already has me noting that as a feature request … but I also responded to the discomfort of not having headings by more keenly writing. I’ve concluded that heading formats are necessary — one invents them by proxy with whatever tools one has — but I still think every decision about adding formatting to Bike should be close-shaved by the razor of textual meaning.

²The reader might compare Bike to the popular Web-document publishing app Craft. Craft is beautifully, thoughtfully done: it allows people to publish, with minimal fuss, text on the Web that looks professionally produced. It’s big of speechifying, and is content agnostic: it means good because it looks good. It has at least 10 paragraph formats and 4 character formats. It has 24 pre-set page styles. It uses color everywhere, usually to good effect. They are excellent, different, programs. I find the difference meaningful in this context.

1 Like