Now that the C++ version is nearly a reality, I've started the long-anticipated task of freeing my content from OneNote (& Windows! 馃槃馃帀馃帀)
However, while doing so I noticed one formatting issue. I'm pretty sure this is just "not a supported feature," but wanted to mention it before migrating too much more, in hopes that I just missed something or it's actually a reasonably doable tweak while polishing off gtkmm3.
It seems (?) like it might not be possible to indent whole paragraphs. I think this is a manifestation of #595. If true, I think it means there's no way to have "hierarchical" content, for example like this: https://lnk2.tk/snaps/2020-05-25_22.57.47.png . As you can see on the left, it's very clear that the 2nd & 3rd paragraphs "belong" to the 1st - but this organization is lost in CT. As I use this type indentation virtually everywhere, I was hoping/wondering there might be a way to avoid losing this structure?
A second manifestation of this is in the case of lists; here's the result: https://lnk2.tk/snaps/2020-05-25_22.46.34.png . Whereas list content is typically indented separately from the list item labels, here only the first line of each item is indented, meaning the lines wrap to where the text & labels are "mixed up" together. This can make it quite difficult to locate the items when lists are very long or have variable-length paragraphs (with the typical layout, you can just scroll down & each item "jumps out" with a single number to the left of all the text).
Thanks in advance for any thoughts/ideas :)
About indentation for separate paragraphs. I checked Gtk documentation and it looks like there is a way to make it work. Maybe it is not even hard (like h1, h2, h3, but instead of font size, it will be indentation). The issue here is in keeping this information in files because we decided not to change the file format until C++ fully replace pygtk.
About bullet list indentations. Actually, there is a paragraph indention (for some reason doesn't work in C++, I'll fix. You can check it in pygtk and change it in preferences) that may help when you have one level bullets/numbers. Don't help for second level and more because this indentation is static. It wouldn't be easy to fix:
Maybe it is not even hard
That would be very awesome :)
The issue here is in keeping this information in files because we decided not to change the file format until C++ fully replace pygtk.
Wouldn't it just be a matter of using html-standard "p" tags to denote paragraph-breaks, rather than "br" - which wouldn't affect the file format?
About bullet list indentations. Actually, there is a paragraph indention
Are you referring to Text and Code->Line Wrapping Indentation?
Wouldn't it just be a matter of using html-standard
tags to denote paragraph-breaks, rather than ... which wouldn't affect the file format?
Our format is not related to html at all and based on gtk text presentation, we have to convert loosely html data to that format. To support new text feature, we need to add some data to describe it and code, so it will actually work. Thus it will change our file format.
But I will think about if I can do it.
Are you referring to Text and Code->Line Wrapping Indentation?
Yes
Oops, Github parsed out the tag in my previous comment - I meant to say "html standard "p" tags" :)
Our format is not related to html at all and based on gtk text presentation
Ohhh, understood.
To support new text feature, we need to add some data to describe it and code
Well, I'm not familiar with gtk, but as long as the file reader/writer is implemented so that "extra data" would just be ignored (when rendering) & preserved (when re-saving), isn't it easy to supplement with new characteristics? That's assuming, of course, the file writer has been implemented like that. For example, in C# XML serialization you have ExtensionDataObject (https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.extensiondataobject?view=netcore-3.1) - it's an extra member you put in any classes you'll support serializing/deserializing, so that if the deserializer encounters something it doesn't know what to do with (which would've come from an addition in a future-version of the file format), it just sticks it there, then blindly writes it back to the file when re-saving. Thus, any data - even data not explicitly known by this version of the application - will survive round-tripping. That lets you add whatever you want without breaking compatibility with previous software versions. Old software versions just blindly preserve extra/unknown data. In this case, that would mean the new version could understand the extra data as indentation, while the old version would still successfully read/save it - just not render it. But there would never be data loss.
Text and Code->Line Wrapping Indentation?
Ah...that has side-effects though, i.e. it doesn't just fix the indentation of lists, but also makes the 2nd line of every paragraph be indented.
You are not too lazy to write it all down :) I totally agree, but in our case there are some issues.
I just checked Geary (IDE based on Gtk) and it has auto indent like you want. I'll take a look at its source, maybe it's just a flag in gtk.
You are not too lazy to write it all down :)
Lol...well, I've been eager to escape OneNote, & thus Windows, for several years. And I feel like at long last I'm at last just a millimeter away from being able...so...however I'm able to help! :)
it has auto indent like you want
Just to clarify: you're referring to the ability to indent paragraphs rather than just its 1st line? Like this: https://lnk2.tk/snaps/2020-05-26_15.20.24.png
I'll take a look at its source, maybe it's just a flag in gtk.
That would be amazing. And a great improvement in overall flexibility of the editor, IMO. Thank you!
I checked a few editors based on Gtk, they have the same issue, e.g. bugzilla
One Gtk editor, Geany, although, supports such indention but it uses Scintilla functionality to fix indent, I don't think we are going to use that Scintilla.
I asked gtksourcevew guys, and they said it was not an issue and we would have to write some code ourselves to fix it ((
Actually @txe we potentially could extend our gtksourceview code nodes with Scintilla code nodes in future. Something that I really like in Scintilla is the possibility to select multiple columns such as https://stackoverflow.com/questions/35954882/how-to-implement-scintillanet-column-edit-mode. I use it in Geany and I find it a must have.
Ah - thanks for looking into it. Shame it's not as easy as perhaps initially hoped, but I'm glad to hear it's still possible & that there's interest in the solution from @giuspen, too! :)
In the interim, unfortunately I had to suspend migrating my content over, as the context lost (due to frequent use of indentation / hierarchical content) was a bit too widespread, & I wasn't able to think of another way to rewrite all those notes without materially changing their meaning. So...for now, I guess fingers just crossed that this might still be somewhere on the near-term horizon, & then I can resume moving over & testing :)
Actually @txe we potentially could extend our gtksourceview code nodes with Scintilla code nodes in future.
I just realized: when you refer to code nodes, do you mean code boxes? Or "Rich Text" nodes? Or something else? Because if it's Code Boxes, this actually wouldn't solve the issue of indentation in regular text, right?
I was trying to play around with CherryTree again today to see if I could figure out any way to workaround this (again, to be able to move away from OneNote). I wasn't able, but I did have a thought:
It occurred to me that on the surface, there's already something that sort of behave this way: codeboxes already "act like" paragraph indentation, in that they're a block of text that gets indented as a whole block rather than line by line. Thus, would it be possible to extend this concept to just something like "richtext boxes?" This is more of an internal representation, but basically if you were to select a paragraph & increase its "indent," internally it would be wrapped in something like a 'codebox' (but without a visible border, which resizes to its content, and itself contains regular richtext). Then indenting is just like putting the cursor in front of a codebox and pressing "tab." It moves the whole block to the right. Am I oversimplifying it? :)
@metal450, you are lucky)
A few days ago, I run into how to indent the whole paragraphs. It's pretty simple and can be done by wrapping the text by some custom tag (like bold tag).
FIY, @giuspen , the tag can be created this way:
gtk_text_buffer_create_tag (buffer, "margin-50",
"left_margin", 50, NULL);
So, the main issue here, adding a new tag will break a backward compatibility with pygtk.
Yessssss! Such awesome news :D
As described above, wouldn't adding a new tag simply cause the old version to ignore it / not render it? So it wouldn't actually break backwards compatibility - just that the old version wouldn't be able to render the new feature?
I never do it, so I don't know, but I know that currently it even if the tag is ignored, when after re-resave it will be lost.
There are some ways to fix, we just need to think though edge cases and come up with some solution.
currently it even if the tag is ignored, when after re-resave it will be lost.
Ah - yeah, that's the round-tripping issue I was discussing above. Basically the file just need some additional member - a raw bytestream - so that if it finds unknown data while deserializing it can just dump it there, then re-serialize it when saving, so it'll survive the round trip - even if older versions don't know how to interpret it.
That's the fancy solution though. The super quick/easy solution is to just show a warning. "This file seems to contain formatting that's unknown to this version of CherryTree; if you re-save your file, you may lose that formatting." Simple and done :)
Although I have zero familiarity with gtkmm3, I thought I'd have a quick go at seeing if I could figure out what's going on & help push this forward. As a super dirty proof-of-concept, I tried just making 'strikethrough' also indent - and indeed the style suggested by @txe works :) You can try it with this patch:
diff --git a/future/src/ct/ct_actions_format.cc b/future/src/ct/ct_actions_format.cc
index 15f35c53..150f2ac1 100644
--- a/future/src/ct/ct_actions_format.cc
+++ b/future/src/ct/ct_actions_format.cc
@@ -333,6 +333,14 @@ void CtActions::_apply_tag(const Glib::ustring& tag_property, Glib::ustring prop
}
if (not property_value.empty())
{
+ if (str::startswith(tag_property, "strikethrough"))
+ {
+ auto buf = text_buffer->gobj();
+ gtk_text_buffer_create_tag(buf, "margin-50", "left_margin", 50, NULL);
+ text_buffer->apply_tag_by_name("margin-50", text_buffer->get_iter_at_offset(sel_start_offset),
+ text_buffer->get_iter_at_offset(sel_end_offset));
+ }
+
text_buffer->apply_tag_by_name(_pCtMainWin->get_text_tag_name_exist_or_create(tag_property, property_value),
text_buffer->get_iter_at_offset(sel_start_offset),
text_buffer->get_iter_at_offset(sel_end_offset));
Obviously this isn't any kind of real solution, but you can write a bunch of multi-line text, select it, then click "strikethrough" - and you'll see full-paragraph indentation.
As far as a "real" implementation, from what I can tell, all the possible text tags are created in get_text_tag_name_exist_or_create(). But creating this 'margin' tag via gtk_text_buffer_create_tag requires the text_buffer, which isn't passed into that function. So first, text_buffer needs to be added as a (optional) param. Right? Or should that particular tag be created elsewhere, because it's a special case?
Hey @txe & @giuspen,
Alright, I went ahead & implemented this on my own - will submit a PR in a moment! :)
I added 2 new controls, "indent" & "unindent," with keyboard shortcuts Ctrl+Shift+> and Ctrl+Shift+<. Pressing them repeatedly increases & decreases the indent of the current paragraph. It seems to be fully working on my end, with two caveats: I didn't implement importing/exporting (i.e. html), and of course, there's still the issue @txe mentioned about "forwards-compatibility" with the old cherry tree. It does properly save/restore in the c++ version.
Hopefully you'll consider merging - I can't wait to get started using ct, & this was the _only_ blocking feature for me :)

One other thing that's not yet implementing: pasting formatted text. So fundamentally this is now there & working - the remaining odds and ends:
Most helpful comment
Actually @txe we potentially could extend our gtksourceview code nodes with Scintilla code nodes in future. Something that I really like in Scintilla is the possibility to select multiple columns such as https://stackoverflow.com/questions/35954882/how-to-implement-scintillanet-column-edit-mode. I use it in Geany and I find it a must have.