Moving footnotes to the end of a document
Moving footnotes to the end of a document
How would you recommend moving footnotes to the end of a document? I can already click on a footnote number in text and pull it up. But I need to bring all footnotes to the end of a document. Thanks.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Moving footnotes to the end of a document
Do you want to convert footnotes to endnotes? All of them, or only the selected note? Undoable by the user?
Re: Moving footnotes to the end of a document
Basically convert all footnotes to end notes and not undo able it needs to be permanent.
Here is what we are doing. We bring in an RTF document to RichViewEdit. Parse through various parts that will be future topic sections. Now each topic section may have footnotes. We need to then add those footnotes to the end of the topic section.
So I'm working with two RichViewEdits lets call them RVE-whole and RVE-topic
RVE-whole has the whole document with various areas like <:> this indicates a new topic section.
I've already broken down the RVE-whole into topic sections now that topic section is loaded in RVE-topic and then further modified then saved to an SQL database. So here in RVE-topic I need to take the footnotes and move them to the end. I could load the footnotes into another RVE-footnote or RTFStream then add that content to the end of RVE-topic.
My concern is how to go through all the footnotes in that topic section. Do I just run through all the "items" check if it has a footnote and then add it to RVE-footnote. Once all items have been processed add that to RVE-topic? Thoughts?
By the way most of this is already done mainly need to move footnotes to end and have them still be connected to their numbers. (I would love to renumber them per section but understand if that would get really complicated.)
Here is what we are doing. We bring in an RTF document to RichViewEdit. Parse through various parts that will be future topic sections. Now each topic section may have footnotes. We need to then add those footnotes to the end of the topic section.
So I'm working with two RichViewEdits lets call them RVE-whole and RVE-topic
RVE-whole has the whole document with various areas like <:> this indicates a new topic section.
I've already broken down the RVE-whole into topic sections now that topic section is loaded in RVE-topic and then further modified then saved to an SQL database. So here in RVE-topic I need to take the footnotes and move them to the end. I could load the footnotes into another RVE-footnote or RTFStream then add that content to the end of RVE-topic.
My concern is how to go through all the footnotes in that topic section. Do I just run through all the "items" check if it has a footnote and then add it to RVE-footnote. Once all items have been processed add that to RVE-topic? Thoughts?
By the way most of this is already done mainly need to move footnotes to end and have them still be connected to their numbers. (I would love to renumber them per section but understand if that would get really complicated.)
Re: Moving footnotes to the end of a document
I got quite a ways but I'm having trouble with a footnote number inside of a table. (I thought I had seen something in the forum about this but I can't find it.)
Here is my code:
Here is my code:
Code: Select all
note_cnt := 0;
for notes_i := 0 to RichViewEditClean.ItemCount-1 do
if RichViewEditClean.GetItem(notes_i) is TCustomRVNoteItemInfo then
begin
//Add footnote(s):
if FootNoteBool = False then RichViewEditClean.AppendFrom(footnoteRVE);
//Add bookmark to a number here.
inc(note_cnt);
RichViewEditClean.Add(#10,0);
RichViewEditClean.AddCheckpoint('fn' + IntToStr(note_cnt), True, 'fn' + IntToStr(note_cnt));
RichViewEditClean.Add(IntToStr(note_cnt),1);
AddNote(RichViewEditClean.GetItem(notes_i) as TCustomRVNoteItemInfo);
//Remove footnote from RichViewEditClean.GetItem(notes_i)
RichViewEditClean.SetSelectionBounds(notes_i, RichViewEditClean.GetOffsBeforeItem(notes_i), notes_i, RichViewEditClean.GetOffsBeforeItem(notes_i));
RichViewEditClean.DeleteItems(notes_i, 1);
//Set item as a bookmark link
RichViewEditClean.InsertText(IntToStr(note_cnt), TRUE);
RichViewEditClean.SearchTextW(IntToStr(note_cnt), [rvseoMatchCase, rvseoDown, rvseoMultiItem]);
RichViewEditClean.ApplyStyleConversion(CONVERT_TO_SUPER_HYPERTEXT);
//tw://[self]?tid=1#fn1-
SetTargetToSelection('tw://[self]?tid=' +IntToStr(topic_sub_i) + '#fn' + IntToStr(note_cnt)+'-');
FootNoteBool := True;
end;
RichViewEditClean.Format;
-
- Posts: 9
- Joined: Thu Dec 27, 2018 1:48 am
Re: Moving footnotes to the end of a document
To access the table cells, you need:jgkoehn wrote: ↑Thu Mar 26, 2020 9:31 pm I got quite a ways but I'm having trouble with a footnote number inside of a table. (I thought I had seen something in the forum about this but I can't find it.)
Here is my code:
Code: Select all
note_cnt := 0; for notes_i := 0 to RichViewEditClean.ItemCount-1 do if RichViewEditClean.GetItem(notes_i) is TCustomRVNoteItemInfo then begin //Add footnote(s): if FootNoteBool = False then RichViewEditClean.AppendFrom(footnoteRVE); //Add bookmark to a number here. inc(note_cnt); RichViewEditClean.Add(#10,0); RichViewEditClean.AddCheckpoint('fn' + IntToStr(note_cnt), True, 'fn' + IntToStr(note_cnt)); RichViewEditClean.Add(IntToStr(note_cnt),1); AddNote(RichViewEditClean.GetItem(notes_i) as TCustomRVNoteItemInfo); //Remove footnote from RichViewEditClean.GetItem(notes_i) RichViewEditClean.SetSelectionBounds(notes_i, RichViewEditClean.GetOffsBeforeItem(notes_i), notes_i, RichViewEditClean.GetOffsBeforeItem(notes_i)); RichViewEditClean.DeleteItems(notes_i, 1); //Set item as a bookmark link RichViewEditClean.InsertText(IntToStr(note_cnt), TRUE); RichViewEditClean.SearchTextW(IntToStr(note_cnt), [rvseoMatchCase, rvseoDown, rvseoMultiItem]); RichViewEditClean.ApplyStyleConversion(CONVERT_TO_SUPER_HYPERTEXT); //tw://[self]?tid=1#fn1- SetTargetToSelection('tw://[self]?tid=' +IntToStr(topic_sub_i) + '#fn' + IntToStr(note_cnt)+'-'); FootNoteBool := True; end; RichViewEditClean.Format;
Code: Select all
DoSomething( RichViewEditClean.RVData );
Code: Select all
procedure DoSomething(RVData: TCustomRVData);
var
i, r, c : Integer;
table: TRVTableItemInfo;
begin
i := RVData.ItemCount - 1;
while i >= 0 do
begin
if RVData.GetItemStyle( i ) in [ rvsFootnote, rvsEndnote, rvsSidenote, rvsTextBox ] then
begin
// your code
end
else if RVData.GetItemStyle( i ) = rvsTable then
begin
table := TRVTableItemInfo( RVData.GetItem( i ) );
for r := 0 to ( table.Rows.Count - 1 ) do
for c := 0 to ( table.Rows[r].Count - 1 ) do
if ( table.Cells[ r, c ] <> nil ) then
DoSomething( table.Cells[ r, c ].GetRVData );
end;
Dec(i);
end;
end;
Re: Moving footnotes to the end of a document
Thank you that is very helpful!
In the table data however I need to be able to edit it. If I save it to a RVFStream so I can load it in a RichViewEditor to eidt it gets quite complicated because the Stream wants various information.
Is there a simple way to load the table info or edit the table info? I can grab the footnote which is excellent but I need to swap out the footnote number in the table.
In the table data however I need to be able to edit it. If I save it to a RVFStream so I can load it in a RichViewEditor to eidt it gets quite complicated because the Stream wants various information.
Is there a simple way to load the table info or edit the table info? I can grab the footnote which is excellent but I need to swap out the footnote number in the table.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Moving footnotes to the end of a document
Sorry for the delay, I yesterday returned from a hospital (nothing serious, but it took some time).
Your original code has several problems
1) Do not use AppendFrom, this method can copy not all kinds of items. Instead, save the document to a stream and use AppendRVFFromStream.
2) You use a mix of viewer-style methods (Add, AddCheckpoint, DeleteItems) and editing methods (InsertText, ApplyStyleConversion). It is highly not recommended. If you do not need a possibility to undo this operation, I recommend to use only viewer-style methods. There is no method to insert a text item at the specified location, but there is a function RVInsertString from RVInsertItems.pas.
My code will be in the text message.
Your original code has several problems
1) Do not use AppendFrom, this method can copy not all kinds of items. Instead, save the document to a stream and use AppendRVFFromStream.
2) You use a mix of viewer-style methods (Add, AddCheckpoint, DeleteItems) and editing methods (InsertText, ApplyStyleConversion). It is highly not recommended. If you do not need a possibility to undo this operation, I recommend to use only viewer-style methods. There is no method to insert a text item at the specified location, but there is a function RVInsertString from RVInsertItems.pas.
My code will be in the text message.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Moving footnotes to the end of a document
Code: Select all
uses RVTable, RVNote, CRVData, RVInsertItems;
// Adds Note's text to the end of document containing RVData.
// note_cnt will be inserted before the Note's text.
procedure AddNoteInfo(RVData: TCustomRVData; Note: TCustomRVNoteItemInfo;
note_cnt: Integer);
var
Stream: TMemoryStream;
RootRVData: TCustomRVData;
Color: TColor;
begin
RootRVData := RVData.GetAbsoluteRootData;
Stream := TMemoryStream.Create;
try
RootRVData.AddCheckpoint('fn' + IntToStr(note_cnt), True, 'fn' + IntToStr(note_cnt));
RootRVData.AddNL(IntToStr(note_cnt), RVGetNoteTextStyleNo(RVData.GetRVStyle, 0), 0);
RootRVData.AddNL(' ',0);
Note.Document.SaveRVFToStream(Stream);
Stream.Position := 0;
RootRVData.AppendRVFFromStream(Stream, -1, Color, nil);
finally
Stream.Free;
end;
end;
// Deletes the ItemNo-th item from RVData
procedure DeleteNote(RVData: TCustomRVData; ItemNo: Integer);
var
FNL: Boolean;
begin
FNL := RVData.IsFromNewLine(ItemNo);
RVData.DeleteItems(ItemNo, 1);
if RVData.ItemCount = 0 then
begin
RVData.AddNL('', 0, 0);
exit;
end;
if FNL and (ItemNo < RVData.ItemCount) then
RVData.GetItem(ItemNo).SameAsPrev := False;
end;
// Returns the index of text style in RVStyle. This style has all properties
// of the StyleNo-th style, but it is hypertext, blue and underlined
function GetNoteHypertextStyleNo(RVStyle: TRVStyle; StyleNo: Integer): Integer;
var
TextStyle: TFontInfo;
begin
TextStyle := TFontInfo.Create(nil);
try
TextStyle.Assign(RVStyle.TextStyles[StyleNo]);
TextStyle.Color := clBlue;
TextStyle.Style := TextStyle.Style + [fsUnderline];
TextStyle.Jump := True;
Result := RVStyle.FindTextStyle(TextStyle);
finally
TextStyle.Free;
end;
end;
// Converts a note (the ItemNo-th item in RVData) to a hyperlink
procedure ConvertNoteToText(RVData: TCustomRVData; ItemNo, note_cnt: Integer);
var
ParaNo, StyleNo: Integer;
begin
if RVData.IsFromNewLine(ItemNo) then
ParaNo := RVData.GetItemPara(ItemNo)
else
ParaNo := -1;
StyleNo := GetNoteHypertextStyleNo(RVData.GetRVStyle,
TCustomRVNoteItemInfo(RVData.GetItem(ItemNo)).TextStyleNo);
RVData.DeleteItems(ItemNo, 1);
RVInsertString(RVData, ItemNo, IntToStr(note_cnt), StyleNo, ParaNo,
'tw://[self]?tid=SOMETHING#fn' + IntToStr(note_cnt)+'-');
end;
// Converts all notes in RVData (and all tables inside it) to hyperlinks,
// and add their text to the end of the root document
procedure ProcessNotes(RVData: TCustomRVData; var note_cnt: Integer);
var
i, r, c: Integer;
Table: TRVTableItemInfo;
begin
for i := RVData.ItemCount - 1 downto 0 do
if RVData.GetItem(i) is TRVTableItemInfo then
begin
Table := TRVTableItemInfo(RVData.GetItem(i));
for r := 0 to Table.RowCount - 1 do
for c := 0 to Table.ColCount - 1 do
if Table.Cells[r, c] <> nil then
ProcessNotes(Table.Cells[r, c].GetRVData, note_cnt);
end
else if RVData.GetItem(i) is TCustomRVNoteItemInfo then
begin
inc(note_cnt);
AddNoteInfo(RVData, TCustomRVNoteItemInfo(RVData.GetItem(i)), note_cnt);
ConvertNoteToText(RVData, i, note_cnt);
end;
end;
// Delete all note references from RVData. They may appear when we copied
// note documents to the end of the document
procedure DeleteNoteRefs(RVData: TCustomRVData);
var
i: Integer;
begin
for i := RVData.ItemCount - 1 downto 0 do
if RVData.GetItem(i) is TRVNoteReferenceItemInfo then
DeleteNote(RVData, i);
end;
// How to use
procedure TForm3.ToolButton12Click(Sender: TObject);
var
note_cnt: Integer;
begin
note_cnt := 0;
ProcessNotes(RichViewEdit1.RVData, note_cnt);
if note_cnt > 0 then
begin
DeleteNoteRefs(RichViewEdit1.RVData);
RichViewEdit1.ClearUndo;
RichViewEdit1.Format;
end;
end;
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Moving footnotes to the end of a document
But the simplest solution would be a conversion of all footnotes (TRVFootnoteItemInfo) to endnotes (TRVEndnoteItemInfo).
Re: Moving footnotes to the end of a document
Sounds like a good idea since endnotes are in document. How can I do this?
Would this also update the numbers? Since I am basically turning the document into multiple smaller documents and savig it to an sqlite.
Would this also update the numbers? Since I am basically turning the document into multiple smaller documents and savig it to an sqlite.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Moving footnotes to the end of a document
Endnotes are numbered sequentially. But you can define the number for some endnote (or all endnotes) explicitly (in the endnote constructor, specify the number in StartFrom parameter, and pass True to Reset parameter).
By default, endnotes are numbered using lower Roman numbers (i, ii, iii, etc.). You can change the numbering style in RVStyle.EndnoteNumbering property.
Like footnotes, endnotes are not shown in TRichView. They are visible only on printing/print preview (and in ScaleRichView editor).
By default, endnotes are numbered using lower Roman numbers (i, ii, iii, etc.). You can change the numbering style in RVStyle.EndnoteNumbering property.
Like footnotes, endnotes are not shown in TRichView. They are visible only on printing/print preview (and in ScaleRichView editor).
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Re: Moving footnotes to the end of a document
Here is the code for converting all footnotes to endnotes.
Code: Select all
uses RVNote, CRVData, RVInsertItems;
// Converts the footnote (the ItemNo-th item in RVData) to an endnote
procedure FootnoteToEndnote(RVData: TCustomRVData; ItemNo: Integer);
var
Stream: TMemoryStream;
Footnote: TRVFootnoteItemInfo;
Endnote: TRVEndnoteItemInfo;
S: TRVUnicodeString;
begin
Footnote := RVData.GetItem(ItemNo) as TRVFootnoteItemInfo;
Endnote := TRVEndnoteItemInfo.CreateEx(RVData, Footnote.TextStyleNo, Footnote.StartFrom,
Footnote.Reset);
if RVData.IsFromNewLine(ItemNo) then
Endnote.ParaNo := Footnote.ParaNo
else
Endnote.ParaNo := -1;
Stream := TMemoryStream.Create;
try
S := RVData.GetItemTextW(ItemNo);
Footnote.Document.SaveRVFToStream(Stream);
Stream.Position := 0;
Endnote.Document.LoadRVFFromStream(Stream);
finally
Stream.Free;
end;
RVData.DeleteItems(ItemNo, 1);
RVInsertItem(RVData, ItemNo, S, Endnote);
RVData.AddSeqInList(ItemNo);
end;
// Converts all footnotes in RVData (and all tables inside it) to endnotes
procedure ProcessNotes(RVData: TCustomRVData);
var
i, r, c: Integer;
Table: TRVTableItemInfo;
begin
for i := RVData.ItemCount - 1 downto 0 do
if RVData.GetItem(i) is TRVTableItemInfo then
begin
Table := TRVTableItemInfo(RVData.GetItem(i));
for r := 0 to Table.RowCount - 1 do
for c := 0 to Table.ColCount - 1 do
if Table.Cells[r, c] <> nil then
ProcessNotes(Table.Cells[r, c].GetRVData);
end
else if RVData.GetItem(i) is TRVFootnoteItemInfo then
begin
FootnoteToEndnote(RVData, i);
end;
end;
// How to use
procedure TForm3.ToolButton12Click(Sender: TObject);
begin
ProcessNotes(RichViewEdit1.RVData);
RichViewEdit1.ClearUndo;
RichViewEdit1.Format;
end;
Re: Moving footnotes to the end of a document
Thank you very much. That will make the process easlet.
Re: Moving footnotes to the end of a document
Oh, I missed that endnotes are not show in the TRichView.
That is what I need. so I will check your previous code. Thanks again
That is what I need. so I will check your previous code. Thanks again
Re: Moving footnotes to the end of a document
The previous code is working excellently. Thank you.