1# *************************************************************
2#
3#  Licensed to the Apache Software Foundation (ASF) under one
4#  or more contributor license agreements.  See the NOTICE file
5#  distributed with this work for additional information
6#  regarding copyright ownership.  The ASF licenses this file
7#  to you under the Apache License, Version 2.0 (the
8#  "License"); you may not use this file except in compliance
9#  with the License.  You may obtain a copy of the License at
10#
11#    http://www.apache.org/licenses/LICENSE-2.0
12#
13#  Unless required by applicable law or agreed to in writing,
14#  software distributed under the License is distributed on an
15#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16#  KIND, either express or implied.  See the License for the
17#  specific language governing permissions and limitations
18#  under the License.
19#
20# *************************************************************
21All paragraphs in tables:
22
23    sprms:
24           0x2416 (sprmPFInTable)    indicates a paragraph is in a table
25           0x6649 (sprmPTableDepth)  demarks the nesting depth of the paragraph
26
27paragraph at nesting depth 1:
28
29    end of cell:        0x7
30    end of row:         0x7 + sprm 0x2417(sprmFTtp)
31
32    the end of a row has its own 0x7
33
34paragraphs at nesting depth > 1;
35
36    end of cell:      0xd + sprm 0x244b(sprmPCell)
37    end of row        0xd + sprm 0x244b(sprmPCell) + sprm 0x244c(sprmPRow)
38
39    the end of a row has its own 0xd
40
41Algorithm to detect table structure:
42
43Datastructures:
44
45RowData<Handle>:
46        int getCellCount()
47            // return number of cells in row
48        Handle getStart(i)
49               // get handle for start of cell i
50        Handle getEnd(i)
51               // get handle for end off cell i
52        Properties getProperties()
53                   // return properties of row
54
55TableData<Handle>:
56        void addCell(Handle start, Handle end)
57             // insert cell starting at start and ending at end into the
58             // current row
59        void endRow(properties)
60             // end current row and save properties for that row, begin new row
61        int getRowCount
62            // return number of rows in table
63        RowData<Handle> getRow(i)
64                        // get data for row i
65
66prevTableDepth
67        depth in table hierarchy of previous paragraph
68
69curTableDepth
70        depth in table hierarchy of current paragraph
71
72bInCell
73        true if current paragraph is in a cell
74
75bEndCell
76        true if current paragraph if the last paragraph of a cell
77
78bEndRow
79        true if current paragraph is the end of a row
80
81paragraphHandle
82          handle for current paragraph
83
84initial:
85        create stack of TableData<Handle>
86
87final:
88        handle remaining TableData<Handle> on stack
89
90creating StreamHandler:
91         push new TableData<Handle> on stack
92
93destroying StreamHandler:
94           handle TableData<Handle> on top of stack
95           pop TableData<Handle> from stack
96
97StreamHandler::substream:
98         push new TableData<Handle> on stack
99         handle TableData<Handle> on top of stack
100         pop TableData<Handle> from stack
101
102starting paragraph group:
103         paragraphHandle = currentHandle;
104         bInCell = false;
105         bCellEnd = false;
106         bRowEnd = false;
107
108ending paragraph group:
109       difference = curTableDepth - prevTableDepth
110
111       if (difference > 0)
112          push difference new TableData<Handle> onto stack
113       else if (difference < 0)
114       {
115            repeat difference times
116            {
117                   handle top of stack
118                   pop stack
119            }
120       }
121       precTableDepth = curTableDepth
122
123       if (bInCell)
124       {
125          if (handleStart is null)
126             handleStart = paragraphHandle;
127
128          if (bCellEnd)
129          {
130                stack.top().addCell(handleStart, paragraphHandle);
131                clear handleStart
132          }
133
134          if (bRowEnd)
135          {
136                stack.top().endRow(properties)
137          }
138
139
140in StreamHandler::props:
141   save properties
142
143PropertiesHandler::sprm:
144        sprm 0x6649:
145             save value in curTableDepth
146        sprm 0x2416:
147             bInCell = true
148        sprm 0x244b:
149             bCellEnd = true
150        sprm 0x2417:
151             bRowEnd = true
152
153text:
154        0x7:
155                bCellEnd = true
156