/** * <p> * Add a single child component to the current list of child components. If * there are no existing child components a new list is created. * </p> * <p> * Note that there are restrictions on which child types can be added to * which parent types. Intermediate nodes are added if necessary; eg, * if a sentence is added to a document, the sentence will be embedded * in a paragraph before it is added * See <code> * DocumentCategory</code> for further information. * </p> * * @param element * the <code>NLGElement</code> to be added. If this is * <code>NULL</code> the method does nothing. */ public virtual void addComponent(NLGElement element) { if (element != null) { ElementCategory thisCategory = Category; ElementCategory category = element.Category; if (category != null && thisCategory is DocumentCategory) { if (((DocumentCategory)thisCategory).hasSubPart(category)) { addElementToComponents(element); } else { NLGElement promotedElement = promote(element); if (promotedElement != null) { addElementToComponents(promotedElement); } else // error condition - add original element so something is visible { addElementToComponents(element); } } } else { addElementToComponents(element); } } }
/** * <p> * Adds a collection of <code>NLGElements</code> to the list of child * components. If there are no existing child components, then a new list is * created. * </p> * <p> * As with <code>addComponents(...)</code> only legitimate child types are * added to the list. * </p> * * @param textComponents * the <code>List</code> of <code>NLGElement</code>s to be added. * If this is <code>NULL</code> the method does nothing. */ public virtual void addComponents <T1>(IList <T1> textComponents) { if (textComponents != null) { ElementCategory thisCategory = Category; List <NLGElement> elementsToAdd = new List <NLGElement>(); ElementCategory category = null; foreach (object eachElement in textComponents) { if (eachElement is NLGElement) { category = ((NLGElement)eachElement).Category; if (category != null && thisCategory is DocumentCategory) { if (((DocumentCategory)thisCategory).hasSubPart(category)) { elementsToAdd.Add((NLGElement)eachElement); ((NLGElement)eachElement).Parent = this; } } } } if (elementsToAdd.Any()) { IList <NLGElement> components = Components; if (components == null) { components = new List <NLGElement>(); } ((List <NLGElement>)components).AddRange(elementsToAdd); setFeature(FEATURE_COMPONENTS, components); } } }
public virtual bool isA(ElementCategory checkCategory) { bool isA = false; if (category != null) { isA = category.Equals(checkCategory); } else if (checkCategory == null) { isA = true; } return(isA); }
/** * <p> * This method determines if the supplied elementCategory forms an immediate * sub-part of <code>this</code> category. The allowed sub-parts for each * <code>this</code> type are outlined below: * </p> * * <ul> * <li><b>DOCUMENT</b>: can contain SECTIONs, PARAGRAPHs, SENTENCEs, * LISTs and ENUMERATED_LISTs. It cannot contain other DOCUMENTs or LIST_ITEMs.</li> * <li><b>SECTION</b>: can contain SECTIONs (referred to as subsections), * PARAGRAPHs, SENTENCEs, LISTs and ENUMERATED_LISTs. It cannot contain DOCUMENTs or * LIST_ITEMs.</li> * <li><b>PARAGRAPH</b>: can contain SENTENCEs, LISTs and ENUMERATED_LISTs. It cannot contain * DOCUMENTs, SECTIONs, other PARAGRAPHs or LIST_ITEMs.</li> * <li><b>SENTENCE</b>: can only contain other forms of * <code>NLGElement</code>s. It cannot contain DOCUMENTs, SECTIONs, * PARAGRAPHs, other SENTENCEs, LISTs, ENUMERATED_LISTs or LIST_ITEMs.</li> * <li><b>LIST</b>: can only contain LIST_ITEMs. It cannot contain * DOCUMENTs, SECTIONs, PARAGRAPHs, SENTENCEs, other LISTs or ENUMERATED_LISTs.</li> * <li><b>ENUMERATED_LIST</b>: can only contain LIST_ITEMs. It cannot contain * DOCUMENTs, SECTIONs, PARAGRAPHs, SENTENCEs, LISTs or other ENUMERATED_LISTs.</li> * <li><b>LIST_ITEMs</b>: can contain PARAGRAPHs, SENTENCEs, LISTs, ENUMERATED_LISTs or other * forms of <code>NLGElement</code>s. It cannot contain DOCUMENTs, SECTIONs, * or LIST_ITEMs.</li> * </ul> * * <p> * For structuring text, this effectively becomes the test for relevant * child types affecting the immediate children. For instance, it is * possible for a DOCUMENT to contain LIST_ITEMs but only if the LIST_ITEMs * are children of LISTs. * </p> * * <p> * A more precise definition of SENTENCE would be that it only contains * PHRASEs. However, this DocumentCategory does not consider these options * as this crosses the boundary between orthographic structure and syntactic * structure. * </p> * * <p> * In pseudo-BNF this can be written as: * </p> * * <pre> * DOCUMENT ::= DOCUMENT_PART* * DOCUMENT_PART ::= SECTION | PARAGRAPH * SECTION ::= DOCUMENT_PART* * PARAGRAPH ::= PARAPGRAPH_PART* * PARAGRAPH_PART ::= SENTENCE | LIST | ENUMERATED_LIST * SENTENCE ::= <NLGElement>* * LIST ::= LIST_ITEM* * ENUMERATED_LIST::= LIST_ITEM* * LIST_ITEM ::= PARAGRAPH | PARAGRAPH_PART | <NLGElement> * </pre> * <p> * Ideally the '*' should be replaced with '+' to represent that one or more * of the components must exist rather than 0 or more. However, the * implementation permits creation of the <code>DocumentElement</code>s with * no children or sub-parts added. * </p> * * @param elementCategory * the category we are checking against. If this is * <code>NULL</code> the method will return <code>false</code>. * @return <code>true</code> if the supplied elementCategory is a sub-part * of <code>this</code> type of category, <code>false</code> * otherwise. */ public bool hasSubPart(ElementCategory elementCategory) { bool subPart = false; if (elementCategory != null) { if (elementCategory is DocumentCategory) { switch (_documentCategory) { case DocumentCategoryEnum.DOCUMENT: subPart = !(elementCategory.Equals(DocumentCategoryEnum.DOCUMENT)) && !(elementCategory.Equals(DocumentCategoryEnum.LIST_ITEM)); break; case DocumentCategoryEnum.SECTION: subPart = elementCategory.Equals(DocumentCategoryEnum.PARAGRAPH) || elementCategory.Equals(DocumentCategoryEnum.SECTION); break; case DocumentCategoryEnum.PARAGRAPH: subPart = elementCategory.Equals(DocumentCategoryEnum.SENTENCE) || elementCategory.Equals(DocumentCategoryEnum.LIST); break; case DocumentCategoryEnum.LIST: subPart = elementCategory.Equals(DocumentCategoryEnum.LIST_ITEM); break; case DocumentCategoryEnum.ENUMERATED_LIST: subPart = elementCategory.Equals(DocumentCategoryEnum.LIST_ITEM); break; default: break; } } else { subPart = _documentCategory.Equals(DocumentCategoryEnum.SENTENCE) || _documentCategory.Equals(DocumentCategoryEnum.LIST_ITEM); } } return(subPart); }
/**********************************************************/ // other methods /**********************************************************/ public override string ToString() { ElementCategory _category = Category; StringBuilder buffer = new StringBuilder("WordElement["); //$NON-NLS-1$ buffer.Append(BaseForm).Append(':'); if (_category != null) { buffer.Append(_category.ToString()); } else { buffer.Append("no category"); //$NON-NLS-1$ } buffer.Append(']'); return(buffer.ToString()); }