1 /************************************************************************/
2 /*									*/
3 /*  Calculate page number and ref fields.				*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docBufConfig.h"
8 
9 #   include	<string.h>
10 #   include	<stdio.h>
11 
12 #   include	<appDebugon.h>
13 
14 #   include	<utilBase26.h>
15 #   include	<utilRoman.h>
16 #   include	<docPagerefField.h>
17 #   include	"docBuf.h"
18 #   include	"docDebug.h"
19 #   include	"docEvalField.h"
20 #   include	"docParaParticules.h"
21 #   include	"docRecalculateFields.h"
22 #   include	<docTreeType.h>
23 
24 /************************************************************************/
25 /*									*/
26 /*  Evaluate page number related fields.				*/
27 /*									*/
28 /************************************************************************/
29 
30 /************************************************************************/
31 /*									*/
32 /*  Format a page number to be used in a certain paragraph.		*/
33 /*									*/
34 /************************************************************************/
35 
docGetPageNumberOffset(const BufferItem * sectNode)36 static int docGetPageNumberOffset(	const BufferItem *	sectNode )
37     {
38     if  ( ! sectNode->biParent )
39 	{ XDEB(sectNode->biParent); return 0;	}
40 
41     while( sectNode->biNumberInParent > 0 )
42 	{
43 	if  ( sectNode->biSectRestartPageNumbers )
44 	    { break;	}
45 
46 	sectNode= sectNode->biParent->biChildren[sectNode->biNumberInParent- 1];
47 	}
48 
49     if  ( sectNode->biSectRestartPageNumbers )
50 	{
51 	return sectNode->biTopPosition.lpPage- sectNode->biSectStartPageNumber;
52 	}
53     else{ return sectNode->biTopPosition.lpPage; }
54     }
55 
docFormatPageNumber(char * target,int targetSize,const BufferItem * sectNode,int pageNumber)56 static void docFormatPageNumber(	char *			target,
57 					int			targetSize,
58 					const BufferItem *	sectNode,
59 					int			pageNumber )
60     {
61     int			style= sectNode->biSectPageNumberStyle;
62 
63     if  ( targetSize < 20 )
64 	{ LDEB(targetSize); strcpy( target, "?" ); return;	}
65 
66     pageNumber -= docGetPageNumberOffset( sectNode );
67 
68     switch( style )
69 	{
70 	default:
71 	    LDEB(style);
72 	    /*FALLTHROUGH*/
73 
74 	case DOCpgnDEC:
75 	    sprintf( target, "%d", pageNumber+ 1 );
76 	    break;
77 
78 	case DOCpgnUCLTR:
79 	    if  ( utilBase26String( target, targetSize, pageNumber+ 1, 1 ) )
80 		{ LDEB(pageNumber); return ;	}
81 	    break;
82 
83 	case DOCpgnLCLTR:
84 	    if  ( utilBase26String( target, targetSize, pageNumber+ 1, 0 ) )
85 		{ LDEB(pageNumber); return ;	}
86 	    break;
87 
88 	case DOCpgnUCRM:
89 	    if  ( utilRomanString( target, targetSize, pageNumber+ 1, 1 ) )
90 		{ sprintf( target, "UCRM:%d", pageNumber+ 1 );	}
91 	    break;
92 
93 	case DOCpgnLCRM:
94 	    if  ( utilRomanString( target, targetSize, pageNumber+ 1, 0 ) )
95 		{ sprintf( target, "lcrm:%d", pageNumber+ 1 );	}
96 	    break;
97 	}
98 
99     return;
100     }
101 
102 /************************************************************************/
103 /*									*/
104 /*  Return the value of a pageref field.				*/
105 /*									*/
106 /************************************************************************/
107 
docCalculatePagerefFieldString(int * pCalculated,MemoryBuffer * mbResult,const DocumentField * dfRef,const RecalculateFields * rf)108 int docCalculatePagerefFieldString(
109 				int *				pCalculated,
110 				MemoryBuffer *			mbResult,
111 				const DocumentField *		dfRef,
112 				const RecalculateFields *	rf )
113     {
114     char			scratch[100+1];
115     BufferDocument *		bd= rf->rfDocument;
116     BufferItem *		bodyNode= bd->bdBody.dtRoot;
117     DocumentField *		dfMark;
118     int				pageNumber;
119     int				i;
120     const BufferItem *		sectNode= (const BufferItem *)0;
121 
122     PagerefField		pf;
123 
124     int				n;
125 
126     docInitPagerefField( &pf );
127 
128     if  ( docGetPagerefField( &pf, dfRef ) )
129 	{ LDEB(1); *pCalculated= 0; goto ready;	}
130 
131     n= docFindBookmarkField( &dfMark, &(bd->bdFieldList), &(pf.pfBookmark) );
132     if  ( n < 0 )
133 	{
134 	/* SLDEB(utilMemoryBufferGetString(&(pf.pfBookmark)),n); */
135 	*pCalculated= 0; goto ready;
136 	}
137 
138     pageNumber= dfMark->dfPage;
139 
140     for ( i= 0; i < bodyNode->biChildCount; i++ )
141 	{
142 	sectNode= bodyNode->biChildren[i];
143 	if  ( sectNode->biBelowPosition.lpPage >= pageNumber )
144 	    { break;	}
145 	}
146 
147     if  ( i >= bodyNode->biChildCount )
148 	{ LDEB(pageNumber); *pCalculated= 0; goto ready;	}
149 
150     docFormatPageNumber( scratch, sizeof(scratch)-1, sectNode, pageNumber );
151 
152     utilMemoryBufferAppendBytes( mbResult,
153 			    (unsigned char *)scratch, strlen( scratch ) );
154     *pCalculated= 1;
155 
156   ready:
157 
158     docCleanPagerefField( &pf );
159 
160     return 0;
161     }
162 
163 /************************************************************************/
164 /*									*/
165 /*  Return the value of a page/numpages field.				*/
166 /*									*/
167 /************************************************************************/
168 
docCalculatePageFieldString(int * pCalculated,MemoryBuffer * mbResult,const DocumentField * df,const RecalculateFields * rf)169 int docCalculatePageFieldString(
170 				int *				pCalculated,
171 				MemoryBuffer *			mbResult,
172 				const DocumentField *		df,
173 				const RecalculateFields *	rf )
174     {
175     char		scratch[100+1];
176     DocumentTree  *	dt;
177     BufferItem *	bodySectNode= (BufferItem *)0;
178     int			page= rf->rfBodySectPage;
179 
180     if  ( ! docIsHeaderType( df->dfSelectionScope.ssTreeType )	&&
181 	  ! docIsFooterType( df->dfSelectionScope.ssTreeType )	)
182 	{
183 	DocumentPosition		dp;
184 
185 	if  ( docPositionForEditPosition( &dp, &(df->dfHeadPosition),
186 							    rf->rfTree ) )
187 	    { LDEB(df->dfHeadPosition.epParaNr);	}
188 	else{
189 	    int			line;
190 	    int			flags= 0;
191 	    const int		lastOne= PARAfindFIRST;
192 
193 	    if  ( docFindLineOfPosition( &line, &flags, &dp, lastOne ) )
194 		{ LDEB(dp.dpStroff);	}
195 	    else{ page= dp.dpNode->biParaLines[line].tlTopPosition.lpPage; }
196 	    }
197 	}
198 
199     if  ( docGetRootOfSelectionScope( &dt, &bodySectNode,
200 					(BufferDocument *)rf->rfDocument,
201 					&(df->dfSelectionScope) )	||
202 	  ! bodySectNode					)
203 	{ XDEB(bodySectNode); *pCalculated= 0; return 0;	}
204 
205     docFormatPageNumber( scratch, sizeof(scratch)-1, bodySectNode, page );
206     utilMemoryBufferAppendBytes( mbResult,
207 			    (unsigned char *)scratch, strlen( scratch ) );
208 
209     *pCalculated= 1; return 0;
210     }
211 
docCalculateNumpagesFieldString(int * pCalculated,MemoryBuffer * mbResult,const DocumentField * df,const RecalculateFields * rf)212 int docCalculateNumpagesFieldString(
213 				int *				pCalculated,
214 				MemoryBuffer *			mbResult,
215 				const DocumentField *		df,
216 				const RecalculateFields *	rf )
217     {
218     char		scratch[100+1];
219     BufferItem *	bodyNode= rf->rfDocument->bdBody.dtRoot;
220 
221     sprintf( scratch, "%d", bodyNode->biBelowPosition.lpPage+ 1 );
222     utilMemoryBufferAppendBytes( mbResult,
223 			    (unsigned char *)scratch, strlen( scratch ) );
224 
225     *pCalculated= 1; return 0;
226     }
227 
228