static void fixTrailingParagraphs(ListStack *stack, int minIlvl) { if (stack->top == NULL) return;; DFNode *li = stack->top->element->last; if (li == NULL) return;; DFNode *child = li->first; // Move to first element while ((child != NULL) && (child->tag < MIN_ELEMENT_TAG)) child = child->next; if (child != NULL) { // Adjust indentation of first element if ((stack->top != NULL) && (child->tag >= MIN_ELEMENT_TAG)) { double pct = stack->top->dimensions.marginLeftPct; adjustMarginLeft(child,-pct,1); } // Skip past first element child = child->next; } DFNode *preceding = (child != NULL) ? child->prev : NULL; DFNode *parent = li; while (child != NULL) { ListDimensions dimensions = paragraphIndent(child); if (!isEmptyParagraph(child) || (minIlvl < 0)) { while ((stack->top != NULL) && (stack->top->ilvl >= minIlvl) && (dimensions.totalPct < stack->top->dimensions.totalPct - 0.001)) { assert(stack->top != NULL); preceding = stack->top->element; parent = stack->top->element->parent; ListStackPop(stack); } } if ((stack->top != NULL) && (child->tag >= MIN_ELEMENT_TAG)) { double pct = stack->top->dimensions.marginLeftPct; adjustMarginLeft(child,-pct,0); } DFNode *next = child->next; DFInsertBefore(parent,child,preceding ? preceding->next : NULL); preceding = child; child = next; } }
void ModifiedFlood (location_t here) { direction_t direction; cost_t smallestCost; ListReset(); ListAdd (here); while (!ListIsEmpty()) { here = ListStackPop(); if (Cost (here) == 0) { continue; } direction = SmallestNeighbourDirection (here); smallestCost = Cost (Neighbour (here, direction)); SetDirection (here, direction); if (Cost (here) != smallestCost + 1) { SetCost (here, smallestCost + 1); AddOpenNeighboursToList (here); } } }
static void ListStackPopToAboveIlvl(ListStack *stack, int ilvl) { while ((stack->top != NULL) && (stack->top->ilvl >= ilvl)) ListStackPop(stack); }
static void Word_fixListSingle(WordConverter *conv, DFNode *node) { ListStack stack; bzero(&stack,sizeof(ListStack)); DFNode *next; for (DFNode *child = node->first; child != NULL; child = next) { next = child->next; int isListItem = 0; if (child->tag == HTML_P) { DFNode *elem = child; const char *numIdStr = DFGetAttribute(elem,WORD_NUMID); const char *ilvlStr = DFGetAttribute(elem,WORD_ILVL); DFRemoveAttribute(elem,WORD_NUMID); DFRemoveAttribute(elem,WORD_ILVL); // A numId of 0 means that there is no numbering applied to this paragraph if ((numIdStr != NULL) && (atoi(numIdStr) == 0)) { numIdStr = NULL; ilvlStr = NULL; } if ((numIdStr != NULL) && (ilvlStr != NULL)) { isListItem = 1; int numId = atoi(numIdStr); int ilvl = atoi(ilvlStr); ListDimensions dimensions = listIndent(conv,numIdStr,ilvlStr); // Find the list at the same ilvl, and check if it has the same numId. If not, we're // starting a new list. ListFrame *sameLevelFrame = NULL; for (ListFrame *frame = stack.top; frame != NULL; frame = frame->parent) { if (frame->ilvl == ilvl) sameLevelFrame = frame; } if ((sameLevelFrame != NULL) && (sameLevelFrame->numId != numId)) fixTrailingParagraphs(&stack,ilvl); else fixTrailingParagraphs(&stack,ilvl+1); if ((stack.top != NULL) && (stack.top->numId != numId)) ListStackPopToAboveIlvl(&stack,ilvl); else if ((stack.top != NULL) && (stack.top->ilvl > ilvl)) ListStackPopToAboveIlvl(&stack,ilvl+1); if ((stack.top == NULL) || (stack.top->numId != numId) || (stack.top->ilvl < ilvl)) { WordConcreteNum *num = WordNumberingConcreteWithId(conv->numbering,numIdStr); // may be NULL WordNumLevel *level = WordConcreteNumGetLevel(num,ilvl); // may be NULL const char *type = WordNumLevelToListStyleType(level); // may be NULL Tag tag; if (DFStringEquals(type,"disc") || DFStringEquals(type,"circle") || DFStringEquals(type,"square")) tag = HTML_UL; else tag = HTML_OL; DFNode *element = DFCreateElement(conv->html,tag); if (type != NULL) DFFormatAttribute(element,HTML_STYLE,"list-style-type: %s",type); if (stack.top != NULL) { DFNode *li; if (stack.top->element->last != NULL) li = stack.top->element->last; else li = DFCreateChildElement(stack.top->element,HTML_LI); DFAppendChild(li,element); } else { DFInsertBefore(node,element,child); } ListStackPushFrame(&stack,element,numId,ilvl,dimensions); } } } if (stack.top != NULL) { DFNode *li; if ((stack.top->element->last != NULL) && !isListItem) li = stack.top->element->last; else li = DFCreateChildElement(stack.top->element,HTML_LI); DFAppendChild(li,child); } } fixTrailingParagraphs(&stack,-1); while (stack.top != NULL) ListStackPop(&stack); }