Skip to content

Commit

Permalink
Export Improvement: Allow indenting nested nodes in plain text
Browse files Browse the repository at this point in the history
Added two options:
- IndentUsingTabs
  If checked, the indentation will be with the TAB (#9) characters. If unchecked, multiple spaces
  will be used for each level of indentation. The number of spaces to use if not checked will be the
  one define in "Tab size", in the Note properties.

- NumbTabInPlainText   [only editable in .INI file]
  Allows replacing the TAB character always used when pasting numbering lists as plain text (system conversion) by
  an alternative string. By default a space " " is defined.

The paragraphs of each node will be indented by the value defined in "Indent by" multiplied with its node level,
added to the indentation they may have (as it is done when exporting to other formats).
The resulting value, together with "Increment indents by" (in Tools | Configuration Options.. | Rich Text editor) is
used to determine how much 'tabs' to apply:
  Number of 'tabs' = [Indentation value] div [Increment indents by]

  Ex. Suppose [Increment indents by] = 12 and a paragraph in a node of level 2, not previously indented:
      if [Indent by] = 24  => (0 + (24*2))/12  => indented with 4 'tabs'  (2 'tabs' for each level)

    If the paragraph was previously indented with a value of 14:
	  if [Indent by] = 24  => (14 + (24*2))/12  => indented with 5 'tabs' (2 'tabs' for each level + extra tab)

Added example screenshots in #573 (comment)

* Also in this commit:
  BulletsInPlainText now defaults to '- '
  • Loading branch information
dpradov committed Dec 29, 2023
1 parent 8464b94 commit 292b4d6
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 44 deletions.
16 changes: 6 additions & 10 deletions general/kn_INI.pas
Expand Up @@ -839,9 +839,8 @@ TExportOptionsIniStr = record
FontSizesInHeading,
IndentNestedNodes,
IndentValue,
{
IndentUsingTabs,
}
NumbTabInPlainText,
NodeHeading,
NoteHeading,
SingleNodeFiles,
Expand Down Expand Up @@ -870,9 +869,8 @@ TExportOptionsIniStr = record
FontSizesInHeading : 'FontSizesInHeading';
IndentNestedNodes : 'IndentNestedNodes';
IndentValue : 'IndentValue';
{
IndentUsingTabs : 'IndentUsingTabs';
}
NumbTabInPlainText: 'NumbTabInPlainText';
NodeHeading : 'NodeHeading';
NoteHeading : 'NoteHeading';
SingleNodeFiles : 'SingleNodeFiles';
Expand Down Expand Up @@ -942,7 +940,7 @@ procedure InitializeEditorOptions( var Struct : TEditorOptions );
WordSelect := true;
WordsPerPage := 250;
PlainDefaultPaste:= true;
BulletsInPlainText:= '';
BulletsInPlainText:= '- ';
end;
_SAVE_RESTORE_CARETPOS := Struct.SaveCaretPos;
end; // InitializeEditorOptions
Expand Down Expand Up @@ -1425,7 +1423,7 @@ procedure SaveKeyNoteOptions(
writebool( section, EditorOptionsIniStr.WordSelect, EditorOptions.WordSelect );
writeinteger( section, EditorOptionsIniStr.WordsPerPage, EditorOptions.WordsPerPage );
writebool( section, EditorOptionsIniStr.PlainDefaultPaste, EditorOptions.PlainDefaultPaste);
writestring( section, EditorOptionsIniStr.BulletsInPlainText, EditorOptions.BulletsInPlainText );
writestring( section, EditorOptionsIniStr.BulletsInPlainText, '"' + EditorOptions.BulletsInPlainText + '"' );

section := ClipOptionsIniStr.Section;
writestring( section, ClipOptionsIniStr.WCDivider, ClipOptions.WCDivider );
Expand Down Expand Up @@ -2158,10 +2156,8 @@ procedure InitializeExportOptions( var Struct : TExportOptions );
AutoFontSizesInHeading:= True;
IndentNestedNodes:= False;
IndentValue := 16;

{
IndentUsingTabs := true;
}
IndentUsingTabs:= true;
NumbTabInPlainText:= ' ';
NodeHeading := _DefaultNodeHeading;
NoteHeading := _DefaultNoteHeading;
SingleNodeFiles := true;
Expand Down
3 changes: 1 addition & 2 deletions general/kn_Info.pas
Expand Up @@ -421,9 +421,8 @@ TKNTLocation = record
FontSizesInHeading: string;
IndentNestedNodes : boolean;
IndentValue : integer;
{
IndentUsingTabs : boolean;
}
NumbTabInPlainText: string;
NodeHeading : string;
NoteHeading : string;
SingleNodeFiles : boolean;
Expand Down
44 changes: 34 additions & 10 deletions structure/kn_ExportNew.dfm
Expand Up @@ -70,6 +70,10 @@ object Form_ExportNew: TForm_ExportNew
ImageIndex = -1
StaticPageIndex = -1
TabVisible = True
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object GroupBox_Source: TGroupBox
Left = 2
Top = 5
Expand Down Expand Up @@ -225,6 +229,10 @@ object Form_ExportNew: TForm_ExportNew
ImageIndex = -1
StaticPageIndex = -1
TabVisible = True
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object GroupBox1: TGroupBox
Left = 3
Top = 5
Expand All @@ -233,9 +241,9 @@ object Form_ExportNew: TForm_ExportNew
Caption = ' Optional headings '
TabOrder = 0
object Label3: TLabel
Left = -4
Left = 19
Top = 126
Width = 62
Width = 39
Height = 13
Alignment = taRightJustify
Caption = 'Symbols'
Expand All @@ -251,7 +259,7 @@ object Form_ExportNew: TForm_ExportNew
FocusControl = Edit_Folder
end
object lblIndent: TLabel
Left = 120
Left = 135
Top = 99
Width = 97
Height = 13
Expand Down Expand Up @@ -314,7 +322,7 @@ object Form_ExportNew: TForm_ExportNew
TabOrder = 4
end
object CB_FontSizes: TCheckBox
Left = 143
Left = 131
Top = 73
Width = 80
Height = 17
Expand Down Expand Up @@ -352,7 +360,7 @@ object Form_ExportNew: TForm_ExportNew
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 10
TabOrder = 11
end
object Edit_Symbols: TEdit
Left = 65
Expand All @@ -366,29 +374,41 @@ object Form_ExportNew: TForm_ExportNew
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 9
TabOrder = 10
end
object CB_IndentNodes: TCheckBox
Left = 12
Top = 97
Width = 120
Width = 102
Height = 17
Hint = 'Indent nested nodes (heading and content)'
Caption = 'Indent nodes'
TabOrder = 7
OnClick = CB_IndentNodesClick
end
object Spin_Indent: TSpinEdit
Left = 224
Left = 239
Top = 95
Width = 55
Width = 40
Height = 22
MaxLength = 3
MaxValue = 50
MinValue = 2
TabOrder = 8
TabOrder = 9
Value = 16
end
object CB_UseTab: TCheckBox
Left = 131
Top = 97
Width = 43
Height = 17
Hint =
'Indent using TAB characters'#13#10'(False: use n'#186' spaces defined in No' +
'te'#39's Tab size)'
Caption = 'Tab'
TabOrder = 8
OnClick = CB_IndentNodesClick
end
end
object RG_NodeMode: TRadioGroup
Left = 3
Expand Down Expand Up @@ -430,6 +450,10 @@ object Form_ExportNew: TForm_ExportNew
ImageIndex = -1
StaticPageIndex = -1
TabVisible = True
ExplicitLeft = 0
ExplicitTop = 0
ExplicitWidth = 0
ExplicitHeight = 0
object RG_TreePadVersion: TRadioGroup
Left = 5
Top = 5
Expand Down
109 changes: 87 additions & 22 deletions structure/kn_ExportNew.pas
Expand Up @@ -106,6 +106,7 @@ TForm_ExportNew = class(TForm)
CB_IndentNodes: TCheckBox;
Spin_Indent: TSpinEdit;
lblIndent: TLabel;
CB_UseTab: TCheckBox;
procedure RG_HTMLClick(Sender: TObject);
procedure TB_OpenDlgDirClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
Expand Down Expand Up @@ -140,9 +141,10 @@ TForm_ExportNew = class(TForm)
procedure OptionsToForm;
function Validate : boolean;

function FlushExportFile( const RTF : TTabRichEdit; FN : string ) : boolean;
function FlushExportFile( const RTF : TTabRichEdit; myNote: TTabNote; FN : string ) : boolean;
procedure FlushTreePadData( var tf : TTextfile; const Name : string; const Level : integer; const RTF : TTabRichEdit; const ClearRTF : boolean);
function GetExportFilename( const FN : string ) : string;
procedure PrepareRTFforPlainText (RTFAux : TTabRichEdit; TabSize: integer; RTFIndentValue: integer);

function ConfirmAbort : boolean;

Expand Down Expand Up @@ -407,8 +409,6 @@ procedure TForm_ExportNew.FormCreate(Sender: TObject);
Edit_NodeHead.Items.Add( _DefaultNodeHeading );
Edit_NoteHead.Items.Add( _DefaultNoteHeading );

// Combo_IndentChar.ItemIndex := 0;

for m := low( m ) to high( m ) do
RG_HTML.Items.Add( HTMLExportMethods[m] );

Expand Down Expand Up @@ -515,9 +515,8 @@ procedure TForm_ExportNew.ReadConfig;
ExportOptions.FontSizesInHeading := readstring( section, ExportOptionsIniStr.FontSizesInHeading, ExportOptions.FontSizesInHeading );
ExportOptions.IndentNestedNodes := readbool( section, ExportOptionsIniStr.IndentNestedNodes, ExportOptions.IndentNestedNodes );
ExportOptions.IndentValue := readinteger( section, ExportOptionsIniStr.IndentValue, ExportOptions.IndentValue );
{
ExportOptions.IndentUsingTabs := readbool( section, ExportOptionsIniStr.IndentUsingTabs, ExportOptions.IndentUsingTabs );
}
ExportOptions.NumbTabInPlainText := readstring( section, ExportOptionsIniStr.NumbTabInPlainText, ExportOptions.NumbTabInPlainText );
ExportOptions.ExportPath := readstring( section, ExportOptionsIniStr.ExportPath, ExportOptions.ExportPath );
ExportOptions.NodeHeading := readstring( section, ExportOptionsIniStr.NodeHeading, ExportOptions.NodeHeading );
ExportOptions.NoteHeading := readstring( section, ExportOptionsIniStr.NoteHeading, ExportOptions.NoteHeading );
Expand Down Expand Up @@ -580,9 +579,8 @@ procedure TForm_ExportNew.WriteConfig;
writestring( section, ExportOptionsIniStr.FontSizesInHeading, ExportOptions.FontSizesInHeading );
writebool( section, ExportOptionsIniStr.IndentNestedNodes, ExportOptions.IndentNestedNodes );
writeinteger( section, ExportOptionsIniStr.IndentValue, ExportOptions.IndentValue );
{
writebool( section, ExportOptionsIniStr.IndentUsingTabs, ExportOptions.IndentUsingTabs );
}
writestring( section, ExportOptionsIniStr.NumbTabInPlainText, '"' + ExportOptions.NumbTabInPlainText + '"');
writestring( section, ExportOptionsIniStr.ExportPath, ExportOptions.ExportPath );
writestring( section, ExportOptionsIniStr.NodeHeading, ExportOptions.NodeHeading );
writestring( section, ExportOptionsIniStr.NoteHeading, ExportOptions.NoteHeading );
Expand Down Expand Up @@ -636,6 +634,7 @@ procedure TForm_ExportNew.FormToOptions;
AutoFontSizesInHeading:= CB_FontSizes.Checked;
IndentNestedNodes := CB_IndentNodes.Checked;
IndentValue := Spin_Indent.Value;
IndentUsingTabs := CB_UseTab.Checked;

NodeHeading := Edit_NodeHead.Text;
if ( NodeHeading = '' ) then
Expand All @@ -644,10 +643,6 @@ procedure TForm_ExportNew.FormToOptions;
if ( NoteHeading = '' ) then
NoteHeading := _TokenChar + EXP_NOTENAME;

{
IndentUsingTabs := ( Combo_IndentChar.ItemIndex > 0 );
}

TreePadRTF := ( RG_TreePadVersion.ItemIndex > 0 );
TreePadSingleFile := ( RG_TreePadMode.ItemIndex > 0 );
TreePadForceMaster := ( RG_TreePadMaster.ItemIndex > 0 );
Expand Down Expand Up @@ -691,13 +686,8 @@ procedure TForm_ExportNew.OptionsToForm;
CB_IndentNodes.Checked := IndentNestedNodes;
Spin_Indent.Enabled:= IndentNestedNodes;
LblIndent.Enabled:= IndentNestedNodes;
Spin_Indent.Value := IndentValue;
{
if IndentUsingTabs then
Combo_IndentChar.ItemIndex := 1
else
Combo_IndentChar.ItemIndex := 0;
}
Spin_Indent.Value:= IndentValue;
CB_UseTab.Checked:= IndentUsingTabs;

if TreePadRTF then
RG_TreePadVersion.ItemIndex := 1
Expand Down Expand Up @@ -962,7 +952,7 @@ procedure TForm_ExportNew.PerformExport;
end;
end;

if FlushExportFile( RTFAux, RemoveAccelChar( myNote.Name )) then
if FlushExportFile( RTFAux, myNote, RemoveAccelChar( myNote.Name )) then
inc( ExportedNotes );

finally
Expand Down Expand Up @@ -1084,7 +1074,7 @@ procedure TForm_ExportNew.PerformExport;
RTFAux.SelStart := 0;
RTFAux.PutRtfText(NodeHeadingRTF, true);
end;
if FlushExportFile( RTFAux, myNoteNode.Name ) then
if FlushExportFile( RTFAux, myNote, myNoteNode.Name ) then
inc( ExportedNodes );
end;
end; // case ExportOptions.SingleNodeFiles
Expand Down Expand Up @@ -1122,7 +1112,7 @@ procedure TForm_ExportNew.PerformExport;
end;

end;
if FlushExportFile( RTFAux, RemoveAccelChar( myNote.Name )) then
if FlushExportFile( RTFAux, myNote, RemoveAccelChar( myNote.Name )) then
inc( ExportedNodes, tmpExportedNodes );
end;
end; // ntTree
Expand Down Expand Up @@ -1417,7 +1407,7 @@ function TForm_ExportNew.GetExportFilename( const FN : string ) : string;
end; // GetExportFilename


function TForm_ExportNew.FlushExportFile( const RTF : TTabRichEdit; FN : string ) : boolean;
function TForm_ExportNew.FlushExportFile( const RTF : TTabRichEdit; myNote: TTabNote; FN : string ) : boolean;
var
tmpStream : TMemoryStream;
StreamSize : integer;
Expand All @@ -1436,6 +1426,9 @@ function TForm_ExportNew.FlushExportFile( const RTF : TTabRichEdit; FN : string
case ExportOptions.TargetFormat of
xfPlainText : begin
if ( ext = '' ) then FN := FN + ext_TXT;

PrepareRTFforPlainText(RTF, myNote.TabSize, EditorOptions.IndentInc);

RTF.StreamFormat := sfPlainText;
if not CanSaveAsANSI(RTF.Text) then
Encoding:= TEncoding.UTF8;
Expand Down Expand Up @@ -1466,6 +1459,78 @@ function TForm_ExportNew.FlushExportFile( const RTF : TTabRichEdit; FN : string
end; // FlushExportFile


procedure TForm_ExportNew.PrepareRTFforPlainText (RTFAux : TTabRichEdit; TabSize: integer; RTFIndentValue: integer);
var
L, SS, SS_NL, STab: integer;
FI, LI, LIndent: integer;
StringIndent: string;
NumTabs: integer;
ParaAttrib: TRxParaAttributes;
BulletsPT: string;

begin
RTFAux.SuspendUndo;

BulletsPT:= EditorOptions.BulletsInPlainText;
if BulletsPT = '' then
BulletsPT:= '- ';

SS:= 0;
for L := 0 to RTFAux.Lines.Count-1 do begin
SS:= RTFAux.Perform(EM_LINEINDEX, L, 0);
RTFAux.SelStart:= SS;
ParaAttrib:= RTFAux.Paragraph;
FI:= ParaAttrib.FirstIndent;
LI:= ParaAttrib.LeftIndent;
LIndent:= FI + LI;

if LIndent > 0 then begin
NumTabs:= LIndent div RTFIndentValue;

if ParaAttrib.Numbering <> nsNone then
Dec(NumTabs);

if ExportOptions.IndentUsingTabs then
StringIndent:= StringOfChar (#9, NumTabs)
else
StringIndent:= StringOfChar (' ', NumTabs * TabSize);

if (ParaAttrib.Numbering in [nsNone, nsBullet]) then
RTFAux.SelText := StringIndent;
end;


if ParaAttrib.Numbering = nsBullet then begin
RTFAux.SelStart:= SS + RTFAux.SelLength;
RTFAux.SelText := BulletsPT;
end
else
if ParaAttrib.Numbering <> nsNone then begin
SS_NL:= RTFAux.Perform(EM_LINEINDEX, L+1, 0);
RTFAux.SelLength:= SS_NL - SS -1;
RTFAux.CopyToClipboard;
RTFAux.PasteIRichEditOLE(CF_TEXT);

if ExportOptions.NumbTabInPlainText <> '' then begin
STab:= RTFAux.FindText(#9, SS, 5, []);
if (STab >= 0) then begin
RTFAux.SetSelection(STab, STab+1, false);
RTFAux.SelText := ExportOptions.NumbTabInPlainText;
end;
end;

if LIndent > 0 then begin
RTFAux.SelStart:= SS;
RTFAux.SelText := StringIndent;
end;

end;
end;

RTFAux.ResumeUndo;
end; // PrepareRTFforPlainText


procedure TForm_ExportNew.Button_SelectClick(Sender: TObject);
var
TabSel : TForm_SelectTab;
Expand Down

0 comments on commit 292b4d6

Please sign in to comment.