protected override void Write(OpenXMLRenderer renderer, CodeBlock obj) { renderer.PushParagraphFormat(FormatStyle.CodeBlock); var paragraph = renderer.PushNewParagraph(); if (obj.Inline != null) { // there was a post-processor which has already processed the lines in this code block renderer.WriteChildren(obj.Inline); } else // there was no post-processor - we have to do the writing of the code lines { // original code: renderer.WriteLeafRawLines(obj); // Expand this call directly here in order to be able to include tags var lines = obj.Lines; if (lines.Lines != null) { var slices = lines.Lines; for (var i = 0; i < lines.Count; i++) { var run = renderer.Push(new Run(new DocumentFormat.OpenXml.Wordprocessing.Text() { Text = slices[i].Slice.ToString(), Space = SpaceProcessingModeValues.Preserve })); renderer.PopTo(run); if (i < lines.Count - 1) { run = renderer.Push(new Run(new Break())); renderer.PopTo(run); } } } } renderer.PopTo(paragraph); renderer.PopParagraphFormat(); }
/// <summary> /// Creates a list instace be creating a (nonabstract) numbering instance. This is an element with a unique number (which is returned) /// that refers to the abstract numbering definition. /// </summary> /// <param name="renderer">The renderer.</param> /// <returns>The unique identifer. Is used afterwards in the list.</returns> public int AddNonabstractNumberId(OpenXMLRenderer renderer) { var _wordDocument = renderer._wordDocument; NumberingDefinitionsPart numberingPart = _wordDocument.MainDocumentPart.NumberingDefinitionsPart; var abstractNumberId = _currentAbstractNumberingDefinition.AbstractNumberId; // Insert an NumberingInstance into the numbering part numbering list. The order seems to matter or it will not pass the // Open XML SDK Productity Tools validation test. AbstractNum comes first and then NumberingInstance and we want to // insert this AFTER the last NumberingInstance and AFTER all the AbstractNum entries or we will get a validation error. var numberId = numberingPart.Numbering.Elements <NumberingInstance>().Count() + 1; var numberingInstance1 = new NumberingInstance() { NumberID = numberId }; var abstractNumId1 = new AbstractNumId() { Val = abstractNumberId }; numberingInstance1.Append(abstractNumId1); if (numberId == 1) { numberingPart.Numbering.Append(numberingInstance1); } else { var lastNumberingInstance = numberingPart.Numbering.Elements <NumberingInstance>().Last(); numberingPart.Numbering.InsertAfter(numberingInstance1, lastNumberingInstance); } return(numberId); }
protected override void Write(OpenXMLRenderer renderer, MathInline obj) { var text = obj.Content.Text.Substring(obj.Content.Start, obj.Content.Length); if (string.IsNullOrEmpty(text)) { return; } TexFormula formula = null; try { formula = _formulaParser.Parse(text); } catch (Exception) { return; } var mathRenderer = new MathRendering.OpenXMLWpfMathRenderer(); var mathObj = (DocumentFormat.OpenXml.OpenXmlCompositeElement)mathRenderer.Render(formula.RootAtom); renderer.Push(mathObj); renderer.PopTo(mathObj); }
/// <inheritdoc/> protected override void Write(OpenXMLRenderer renderer, LiteralInline obj) { if (obj.Content.IsEmpty) { return; } if (renderer.CurrentFigureCaptionListIndex.HasValue && Includes(obj.Span, renderer.FigureCaptionList[renderer.CurrentFigureCaptionListIndex.Value].Number.Position, renderer.FigureCaptionList[renderer.CurrentFigureCaptionListIndex.Value].Number.Count) ) { // we are inside a figure caption, and the use of automatic figure numbering was chosen WriteFigureCaptionLiteralInline(renderer, obj); } else if ( renderer.CurrentFigureLinkListIndex.HasValue && Includes(obj.Span, renderer.FigureLinkList[renderer.CurrentFigureLinkListIndex.Value].Number.Position, renderer.FigureLinkList[renderer.CurrentFigureLinkListIndex.Value].Number.Count) ) { // we are inside a link to a figure, and the use of automatic figure numbering was chosen WriteFigureLinkLiteralInline(renderer, obj); } else { // Write a normal inline var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = obj.Content.ToString() }); renderer.PopTo(run); } }
protected override void Write(OpenXMLRenderer renderer, EmphasisInline obj) { int nPushed = 0; switch (obj.DelimiterChar) { case '*': case '_': if (obj.IsDouble) { renderer.PushInlineFormat(OpenXMLRenderer.InlineFormat.Bold); ++nPushed; } else { renderer.PushInlineFormat(OpenXMLRenderer.InlineFormat.Italic); ++nPushed; } break; case '~': if (obj.IsDouble) { renderer.PushInlineFormat(OpenXMLRenderer.InlineFormat.Strikethrough); ++nPushed; } else { renderer.PushInlineFormat(OpenXMLRenderer.InlineFormat.Subscript); ++nPushed; } break; case '^': renderer.PushInlineFormat(OpenXMLRenderer.InlineFormat.Superscript); ++nPushed; break; case '+': // Inserted style { renderer.PushInlineFormat(OpenXMLRenderer.InlineFormat.Underline); ++nPushed; } break; case '=': // Marked style break; } renderer.WriteChildren(obj); for (int i = 0; i < nPushed; ++i) { renderer.PopInlineFormat(); } }
/// <summary> /// Exports the specified <see cref="TextDocument"/> to an external markdown file. /// </summary> /// <param name="document">The document to export.</param> /// <param name="fileName">Full name of the Maml file to export to. Note that if exporting to multiple Maml files, /// this is the base file name only; the file names will be derived from this name.</param> /// <param name="errors">A list that collects error messages.</param> public void Export(TextDocument document, string fileName, List <MarkdownError> errors = null) { if (null == document) { throw new ArgumentNullException(nameof(document)); } if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException(nameof(fileName)); } var basePathName = Path.GetDirectoryName(fileName); if (ExpandChildDocuments) { document = ChildDocumentExpander.ExpandDocumentToNewDocument(document, errors: errors); } if (RenumerateFigures) { document.SourceText = FigureRenumerator.RenumerateFigures(document.SourceText); } // now export the markdown document as Maml file(s) // first parse it with Markdig var pipeline = new MarkdownPipelineBuilder(); pipeline = MarkdownUtilities.UseSupportedExtensions(pipeline); var markdownDocument = Markdig.Markdown.Parse(document.SourceText, pipeline.Build()); var renderer = new OpenXMLRenderer( wordDocumentFileName: OutputFileName, localImages: document.Images, textDocumentFolder: document.Folder ); if (MaximumImageWidth.HasValue) { renderer.MaxImageWidthIn96thInch = MaximumImageWidth.Value.AsValueIn(Altaxo.Units.Length.Inch.Instance) * 96.0; } if (MaximumImageHeight.HasValue) { renderer.MaxImageHeigthIn96thInch = MaximumImageHeight.Value.AsValueIn(Altaxo.Units.Length.Inch.Instance) * 96.0; } if (null != ThemeName) { renderer.ThemeName = ThemeName; } renderer.RemoveOldContentsOfTemplateFile = RemoveOldContentsOfTemplateFile; renderer.ImageResolution = ImageResolutionDpi; renderer.UseAutomaticFigureNumbering = UseAutomaticFigureNumbering; renderer.DoNotFormatFigureLinksAsHyperlinks = DoNotFormatFigureLinksAsHyperlinks; renderer.Render(markdownDocument); }
protected override void Write(OpenXMLRenderer renderer, ParagraphBlock obj) { var paragraph = renderer.PushNewParagraph(); renderer.WriteLeafInline(obj); renderer.PopTo(paragraph); renderer.AddBookmarkIfNeccessary(obj, paragraph); }
protected override void Write(OpenXMLRenderer renderer, HeadingBlock obj) { FormatStyle id; switch (obj.Level) { case 1: id = FormatStyle.Heading1; break; case 2: id = FormatStyle.Heading2; break; case 3: id = FormatStyle.Heading3; break; case 4: id = FormatStyle.Heading4; break; case 5: id = FormatStyle.Heading5; break; case 6: id = FormatStyle.Heading6; break; case 7: id = FormatStyle.Heading7; break; case 8: id = FormatStyle.Heading8; break; case 9: id = FormatStyle.Heading9; break; default: throw new NotImplementedException(); } renderer.PushParagraphFormat(id); var paragraph = renderer.PushNewParagraph(); renderer.WriteLeafInline(obj); renderer.PopTo(paragraph); renderer.PopParagraphFormat(); renderer.AddBookmarkIfNeccessary(obj, paragraph); }
protected override void Write(OpenXMLRenderer renderer, AutolinkInline obj) { var hyperlink = new Hyperlink(new Run(new DocumentFormat.OpenXml.Wordprocessing.Text(obj.Url))) { DocLocation = obj.Url }; renderer.Push(hyperlink); renderer.PopTo(hyperlink); }
protected override void Write(OpenXMLRenderer renderer, HtmlEntityInline obj) { var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = obj.Transcoded.Text }); renderer.PopTo(run); }
protected override void Write(OpenXMLRenderer renderer, DelimiterInline obj) { var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = obj.ToLiteral() }); renderer.WriteChildren(obj); renderer.PopTo(run); }
private static void WriteFigureLinkLiteralInline(OpenXMLRenderer renderer, LiteralInline obj) { var text = obj.Content.ToString(); var numberPosition = renderer.FigureLinkList[renderer.CurrentFigureLinkListIndex.Value].Number.Position; var numberLength = renderer.FigureLinkList[renderer.CurrentFigureLinkListIndex.Value].Number.Count; var textBeforeNumber = text.Substring(0, numberPosition - obj.Span.Start); var textAfterNumber = text.Substring(numberPosition + numberLength - obj.Span.Start); var figureCaptionIndex = renderer.FigureLinkList[renderer.CurrentFigureLinkListIndex.Value].CaptionListIndex; var bookmarkId = GetBookmarkId(renderer, figureCaptionIndex); if (!string.IsNullOrEmpty(textBeforeNumber)) { var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = textBeforeNumber }); renderer.PopTo(run); } { var bookmarkRef = "_REF" + bookmarkId.ToString(System.Globalization.CultureInfo.InvariantCulture); var field = renderer.Push(new SimpleField { Instruction = $" REF {bookmarkRef} \\h " }); var captionNumber = renderer.FigureCaptionIndices[figureCaptionIndex]; // include the number var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = captionNumber.ToString() }); // renderer.ApplyStyleToRun(StyleDictionary.IdToName[FormatStyle.Link], run); // Note: This would not work - word is not formatting the text as hyperlink if the text is, like here, inside a field renderer.PopTo(field); } if (!string.IsNullOrEmpty(textAfterNumber)) { var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = textAfterNumber }); renderer.PopTo(run); } }
/// <summary> /// Adds the level to abstract numbering definition. /// </summary> /// <param name="renderer">The renderer.</param> /// <param name="level">The level to add (1..9).</param> /// <param name="isOrdered">If set to <c>true</c>, the list items will start with a number. If set to false, the items will start with a bullet.</param> private void AddLevelToAbstractNumberingDefinition(OpenXMLRenderer renderer, int level, bool isOrdered) { var presentLevels = _currentAbstractNumberingDefinition.ChildElements.OfType <Level>().Count(); if (level <= presentLevels) { return; } var levelDef = GenerateLevel(level, isOrdered); if (null != levelDef) { _currentAbstractNumberingDefinition.AppendChild(levelDef); } }
/// <summary> /// Writes the <see cref="ListBlock"/> to the specified renderer. /// </summary> /// <param name="renderer">The renderer.</param> /// <param name="listBlock">The list block to write.</param> protected override void Write(OpenXMLRenderer renderer, ListBlock listBlock) { // https://stackoverflow.com/questions/1940911/openxml-2-sdk-word-document-create-bulleted-list-programmatically // Get the level of this list block int level = 0; ContainerBlock b = listBlock; while (null != b) { if (b is ListBlock) { ++level; } b = b.Parent; } // Note: currently, we have for each list an own abstract numbering definition // This is not neccessary: if the structure of the list is the same than that of a list before, // in theory we can use the same abstract numbering definition for that. if (1 == level) { // Add an abstract numbering definition // An abstract numbering definition is a definition of the numbering styles of the different levels of a list // and can be used for multiple lists _currentAbstractNumberingDefinition = AddAbstractNumberingDefinition(renderer); // Add an Number Id // The number id is a unique instance, that refers to the abstract numbering definition // and is used by our current list _currentNonabstractNumberingId = AddNonabstractNumberId(renderer); } AddLevelToAbstractNumberingDefinition(renderer, level, listBlock.IsOrdered); AddListItems(renderer, listBlock, level, _currentNonabstractNumberingId); if (1 == level) { _currentAbstractNumberingDefinition = null; _currentNonabstractNumberingId = 0; } }
protected override void Write(OpenXMLRenderer renderer, Markdig.Extensions.Figures.FigureCaption obj) { if (null != renderer.FigureCaptionList) { var idx = renderer.FigureCaptionList.FindIndex(x => object.ReferenceEquals(x.FigureCaption, obj)); if (idx >= 0) { renderer.CurrentFigureCaptionListIndex = idx; } } renderer.PushParagraphFormat(FormatStyle.Caption); var paragraph = renderer.PushNewParagraph(); renderer.WriteLeafInline(obj); renderer.PopTo(paragraph); renderer.PopParagraphFormat(); renderer.CurrentFigureCaptionListIndex = null; }
protected override void Write(OpenXMLRenderer renderer, ThematicBreakBlock obj) { var paragraph = renderer.PushNewParagraph(); var paraProperties = paragraph.ChildElements.FirstOrDefault() as ParagraphProperties; if (null == paraProperties) { paraProperties = paragraph.AppendChild(new ParagraphProperties()); } var paraBorders = new ParagraphBorders(); var bottom = new BottomBorder() { Val = BorderValues.Single, Color = "auto", Size = 12, Space = 1 }; paraBorders.Append(bottom); paraProperties.Append(paraBorders); renderer.PopTo(paragraph); }
/// <summary> /// Adds the list items. /// </summary> /// <param name="renderer">The renderer.</param> /// <param name="listBlock">The list block for which the items should be added.</param> /// <param name="level">The current level of this list (1= main list, 2 = first sub list, etc.)</param> /// <param name="numberId">The unique identifier identifying this list. Note: it is the same identifier independent on the level.</param> public void AddListItems(OpenXMLRenderer renderer, ListBlock listBlock, int level, int numberId) { foreach (var item in listBlock) { // Create items for paragraph properties renderer.PushParagraphFormat(FormatStyle.ListParagraph); renderer.NumberingProperties = new NumberingProperties(new NumberingLevelReference() { Val = level - 1 }, new NumberingId() { Val = numberId }); var listItem = (ListItemBlock)item; renderer.WriteChildren(listItem); renderer.NumberingProperties = null; renderer.PopParagraphFormat(); } }
protected override void Write(OpenXMLRenderer renderer, CodeInline obj) { { var run = renderer.PushNewRun(); renderer.ApplyStyleToRun(StyleDictionary.IdToName[FormatStyle.CodeInline], run); var runProp = run.ChildElements[0] as RunProperties; runProp.AppendChild(new CharacterScale { Val = 25 }); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = "\u202F" }); renderer.PopTo(run); } { var run = renderer.PushNewRun(); renderer.ApplyStyleToRun(StyleDictionary.IdToName[FormatStyle.CodeInline], run); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = obj.Content.ToString().Replace(" ", "\u00A0") }); // change spaces against fixed spaces renderer.PopTo(run); } { var run = renderer.PushNewRun(); renderer.ApplyStyleToRun(StyleDictionary.IdToName[FormatStyle.CodeInline], run); var runProp = run.ChildElements[0] as RunProperties; runProp.AppendChild(new CharacterScale { Val = 25 }); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = "\u202F" }); renderer.PopTo(run); } }
/// <summary> /// Adds the abstract numbering definition. The abstract numbering definition can be thought of as the list class, which can have multiple instances. /// In this definition the styles of the different list levels will be defined, but here we add the definitions part only. /// The level definitions will be added to this on demand later. /// </summary> /// <param name="renderer">The renderer.</param> /// <returns>The abstract numbering definition.</returns> private AbstractNum AddAbstractNumberingDefinition(OpenXMLRenderer renderer) { var _wordDocument = renderer._wordDocument; // Introduce bulleted numbering in case it will be needed at some point NumberingDefinitionsPart numberingPart = _wordDocument.MainDocumentPart.NumberingDefinitionsPart; if (numberingPart == null) { numberingPart = _wordDocument.MainDocumentPart.AddNewPart <NumberingDefinitionsPart>("NumberingDefinitionsPart001"); var element = new Numbering(); element.Save(numberingPart); } // Insert an AbstractNum into the numbering part numbering list. // The order seems to matter or it will not pass the // Open XML SDK Productity Tools validation test. // AbstractNum comes first and then NumberingInstance and we want to // insert this AFTER the last AbstractNum and BEFORE the first NumberingInstance or we will get a validation error. var abstractNumberId = numberingPart.Numbering.Elements <AbstractNum>().Count() + 1; var abstractNum1 = new AbstractNum() { AbstractNumberId = abstractNumberId }; abstractNum1.AppendChild(new MultiLevelType() { Val = MultiLevelValues.HybridMultilevel }); if (abstractNumberId == 1) { numberingPart.Numbering.Append(abstractNum1); } else { AbstractNum lastAbstractNum = numberingPart.Numbering.Elements <AbstractNum>().Last(); numberingPart.Numbering.InsertAfter(abstractNum1, lastAbstractNum); } return(abstractNum1); }
protected override void Write(OpenXMLRenderer renderer, LineBreakInline obj) { if (obj.IsHard) { var element = renderer.Peek(); if (element is W.Paragraph) { var run = renderer.Push(new W.Run()); run.AppendChild(new W.Break()); renderer.PopTo(run); } else { var paragraph = renderer.Push(new W.Paragraph()); renderer.PopTo(paragraph); } } else // neither hard nor backslash -> but we have to add a space at least { var element = renderer.Peek(); if (element is W.Paragraph) { var run = renderer.PushNewRun(); run.AppendChild(new W.Text() { Space = SpaceProcessingModeValues.Preserve, Text = " " }); renderer.PopTo(run); } else // this should not happen, because we already are in a paragraph { var paragraph = renderer.Push(new W.Paragraph()); renderer.PopTo(paragraph); } } }
protected override void Write(OpenXMLRenderer renderer, MathBlock obj) { string text = string.Empty; // obj.Content.Text.Substring(obj.Content.Start, obj.Content.Length); for (int i = 0; i < obj.Lines.Count; ++i) { var l = obj.Lines.Lines[i]; text += l.Slice.Text.Substring(l.Slice.Start, l.Slice.Length); } if (string.IsNullOrEmpty(text)) { return; } TexFormula formula = null; try { formula = _formulaParser.Parse(text); } catch (Exception) { return; } var mathRenderer = new MathRendering.OpenXMLWpfMathRenderer(); var mathObj = (DocumentFormat.OpenXml.OpenXmlCompositeElement)mathRenderer.Render(formula.RootAtom); var wordParagraph = renderer.PushNewParagraph(); // this is a Word paragraph renderer.Push(new Paragraph()); // Attention this is a __Math__ paragraph! renderer.Push(mathObj); renderer.PopTo(wordParagraph); }
private static void WriteFigureCaptionLiteralInline(OpenXMLRenderer renderer, LiteralInline obj) { // This is probably a figure caption, and maybe the category identifier and the number needs to be replaced by special elements // Split the text in text before the number, and after the number var text = obj.Content.ToString(); var numberPosition = renderer.FigureCaptionList[renderer.CurrentFigureCaptionListIndex.Value].Number.Position; var numberLength = renderer.FigureCaptionList[renderer.CurrentFigureCaptionListIndex.Value].Number.Count; var categoryName = renderer.FigureCaptionList[renderer.CurrentFigureCaptionListIndex.Value].Category.Name; var textBeforeNumber = text.Substring(0, numberPosition - obj.Span.Start); var textAfterNumber = text.Substring(numberPosition + numberLength - obj.Span.Start); if (!string.IsNullOrEmpty(textBeforeNumber)) { var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = textBeforeNumber }); renderer.PopTo(run); } var para = renderer.Peek(); var bookmarkId = GetBookmarkId(renderer, renderer.CurrentFigureCaptionListIndex.Value); { var bookmarkStart = new BookmarkStart { Id = bookmarkId.ToString(System.Globalization.CultureInfo.InvariantCulture), Name = "_REF" + bookmarkId.ToString(System.Globalization.CultureInfo.InvariantCulture) }; para.AppendChild(bookmarkStart); } { var field = renderer.Push(new SimpleField { Instruction = $" SEQ {categoryName} \\* ARABIC " }); // include the number var captionNumber = renderer.FigureCaptionIndices[renderer.CurrentFigureCaptionListIndex.Value]; var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = captionNumber.ToString() }); renderer.PopTo(field); } { var bookmarkEnd = new BookmarkEnd() { Id = bookmarkId.ToString(System.Globalization.CultureInfo.InvariantCulture) }; para.AppendChild(bookmarkEnd); } if (!string.IsNullOrEmpty(textAfterNumber)) { var run = renderer.PushNewRun(); run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text() { Space = SpaceProcessingModeValues.Preserve, Text = textAfterNumber }); renderer.PopTo(run); } }
private static long GetBookmarkId(OpenXMLRenderer renderer, int figureCaptionIndex) { return((renderer.FigureLinkRandom + 97L * figureCaptionIndex) % 1000000); }
protected override void Write(OpenXMLRenderer renderer, md.Table mdTable) { // Create an empty table. var table = renderer.Push(new Table()); // Create a TableProperties object and specify its border information. var tblProp = new TableProperties( new TableBorders( new TopBorder() { Val = new EnumValue <BorderValues>(BorderValues.Single), Size = 4 }, new BottomBorder() { Val = new EnumValue <BorderValues>(BorderValues.Single), Size = 4 }, new LeftBorder() { Val = new EnumValue <BorderValues>(BorderValues.Single), Size = 4 }, new RightBorder() { Val = new EnumValue <BorderValues>(BorderValues.Single), Size = 4 }, new InsideHorizontalBorder() { Val = new EnumValue <BorderValues>(BorderValues.Single), Size = 4 }, new InsideVerticalBorder() { Val = new EnumValue <BorderValues>(BorderValues.Single), Size = 4 } ) ); // Append the TableProperties object to the empty table. table.AppendChild <TableProperties>(tblProp); foreach (md.TableRow mdRow in mdTable) { // Create a row. var wRow = renderer.Push(new TableRow()); for (var i = 0; i < mdRow.Count; i++) { var cellObj = mdRow[i]; var mdCell = (md.TableCell)cellObj; // Create a cell. var wTableCell = renderer.Push(new TableCell()); wTableCell.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Auto })); // Specify the width property of the table cell. renderer.Write(mdCell); // Apply horizontal alignment var horizontalJustification = JustificationValues.Left; if (mdTable.ColumnDefinitions != null) { var columnIndex = mdCell.ColumnIndex < 0 || mdCell.ColumnIndex >= mdTable.ColumnDefinitions.Count ? i : mdCell.ColumnIndex; columnIndex = columnIndex >= mdTable.ColumnDefinitions.Count ? mdTable.ColumnDefinitions.Count - 1 : columnIndex; var alignment = mdTable.ColumnDefinitions[columnIndex].Alignment; if (alignment.HasValue) { switch (alignment) { case md.TableColumnAlign.Center: horizontalJustification = JustificationValues.Center; break; case md.TableColumnAlign.Right: horizontalJustification = JustificationValues.Right; break; case md.TableColumnAlign.Left: horizontalJustification = JustificationValues.Left; break; } } } if (horizontalJustification != JustificationValues.Left) { foreach (var paragraph in wTableCell.ChildElements.OfType <Paragraph>()) { var pp = paragraph.ChildElements.OfType <ParagraphProperties>().FirstOrDefault() ?? paragraph.PrependChild(new ParagraphProperties()); pp.AppendChild(new Justification { Val = horizontalJustification }); } } renderer.PopTo(wTableCell); } renderer.PopTo(wRow); } renderer.PopTo(table); }
protected override void Write(OpenXMLRenderer renderer, QuoteBlock obj) { renderer.PushParagraphFormat(FormatStyle.QuoteBlock); renderer.WriteChildren(obj); renderer.PopParagraphFormat(); }
protected override void Write(OpenXMLRenderer renderer, Markdig.Extensions.Figures.Figure obj) { renderer.WriteChildren(obj); }
/// <inheritdoc/> protected override void Write(OpenXMLRenderer renderer, LinkInline link) { var url = link.GetDynamicUrl != null?link.GetDynamicUrl() ?? link.Url : link.Url; if (link.IsImage) { RenderImage(renderer, link, url); renderer.AddBookmarkIfNeccessary(link); } else // link is not an image { if (Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute)) { ++_linkIndex; //var nextId = renderer._wordDocument.MainDocumentPart.Parts.Count() + 1; var rId = "lkId" + _linkIndex.ToString(System.Globalization.CultureInfo.InvariantCulture); renderer._wordDocument.MainDocumentPart.AddHyperlinkRelationship(new System.Uri(url, System.UriKind.Absolute), true, rId); var hyperlink = new Hyperlink() { Id = rId }; renderer.Push(hyperlink); renderer.WriteChildren(link); foreach (var run in hyperlink.ChildElements.OfType <Run>()) { renderer.ApplyStyleToRun(StyleDictionary.IdToName[FormatStyle.Link], run); } renderer.PopTo(hyperlink); } else if (!string.IsNullOrEmpty(url) && url.StartsWith("#")) // not a well formed Uri String - then it is probably a fragment reference { if (null != renderer.FigureLinkList) { var idx = renderer.FigureLinkList.FindIndex(x => object.ReferenceEquals(x.Link, link)); if (idx >= 0) { renderer.CurrentFigureLinkListIndex = idx; } } var hyperlink = new Hyperlink() { Anchor = url.Substring(1) }; renderer.Push(hyperlink); renderer.WriteChildren(link); if (!renderer.CurrentFigureLinkListIndex.HasValue || !renderer.DoNotFormatFigureLinksAsHyperlinks) { foreach (var run in hyperlink.ChildElements.OfType <Run>()) { renderer.ApplyStyleToRun(StyleDictionary.IdToName[FormatStyle.Link], run); } } renderer.PopTo(hyperlink); renderer.CurrentFigureLinkListIndex = null; } } }
private void AddImageToBody(OpenXMLRenderer renderer, string relationshipId, ImageRenderToStreamResult streamResult, double?width, double?height) { bool changeAspect = false; long cx; long cy; if (width.HasValue && height.HasValue) { changeAspect = true; cx = (long)(width.Value * 9525); cy = (long)(height.Value * 9525); } else if (width.HasValue) { double aspectYX = streamResult.PixelsY * streamResult.DpiX / (streamResult.PixelsX * streamResult.DpiY); cx = (long)(width.Value * 9525); cy = (long)(width.Value * 9525 * aspectYX); } else if (height.HasValue) { double aspectXY = streamResult.PixelsX * streamResult.DpiY / (streamResult.PixelsY * streamResult.DpiX); cy = (long)(height.Value * 9525); cx = (long)(height.Value * 9525 * aspectXY); } else { cx = (long)(914400 * streamResult.PixelsX / streamResult.DpiX); cy = (long)(914400 * streamResult.PixelsY / streamResult.DpiY); } // limit the image size if set in the renderer. if (renderer.MaxImageWidthIn96thInch.HasValue && renderer.MaxImageHeigthIn96thInch.HasValue) { double cxmax = renderer.MaxImageWidthIn96thInch.Value * 9525; double cymax = renderer.MaxImageHeigthIn96thInch.Value * 9525; var r = Math.Min(cxmax / cx, cymax / cy); if (r < 1) { cx = (long)(r * cx); cy = (long)(r * cy); } } else if (renderer.MaxImageWidthIn96thInch.HasValue) { double cxmax = renderer.MaxImageWidthIn96thInch.Value * 9525; if (cx > cxmax) { cy = (long)(cy * (cxmax / cx)); cx = (long)cxmax; } } else if (renderer.MaxImageHeigthIn96thInch.HasValue) { double cymax = renderer.MaxImageHeigthIn96thInch.Value * 9525; if (cy > cymax) { cx = (long)(cx * (cymax / cy)); cy = (long)cymax; } } ++_figureIndex; var drawing = new DocumentFormat.OpenXml.Wordprocessing.Drawing( new DW.Inline( new DW.Extent() { Cx = cx, Cy = cy }, new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new DW.DocProperties() { Id = _figureIndex, Name = "Figure " + _figureIndex.ToString(System.Globalization.CultureInfo.InvariantCulture), Description = streamResult.NameHint }, new DW.NonVisualGraphicFrameDrawingProperties( new A.GraphicFrameLocks() { NoChangeAspect = !changeAspect }), new A.Graphic( new A.GraphicData( new PIC.Picture( new PIC.NonVisualPictureProperties( new PIC.NonVisualDrawingProperties() { Id = 0U, Name = streamResult.NameHint }, new PIC.NonVisualPictureDrawingProperties()), new PIC.BlipFill( new A.Blip( new A.BlipExtensionList( new A.BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" }) ) { Embed = relationshipId, CompressionState = A.BlipCompressionValues.Print }, new A.Stretch( new A.FillRectangle())), new PIC.ShapeProperties( new A.Transform2D( new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = cx, Cy = cy }), new A.PresetGeometry( new A.AdjustValueList() ) { Preset = A.ShapeTypeValues.Rectangle })) ) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }) ) { DistanceFromTop = 0U, DistanceFromBottom = 0U, DistanceFromLeft = 0U, DistanceFromRight = 0U }); var run = renderer.Push(new Run()); run.AppendChild(drawing); renderer.PopTo(run); }
private void RenderImage(OpenXMLRenderer renderer, LinkInline link, string url) { using (var imageStream = new MemoryStream()) { var streamResult = renderer.ImageProvider.GetImageStream(imageStream, url, renderer.ImageResolution, renderer.TextDocumentFolderLocation, renderer.LocalImages); if (!streamResult.IsValid) { Current.Console.WriteLine("Error resolving image url {0}: {1}", url, streamResult.ErrorMessage); return; } double?width = null, height = null; if (link.ContainsData(typeof(Markdig.Renderers.Html.HtmlAttributes))) { var htmlAttributes = (Markdig.Renderers.Html.HtmlAttributes)link.GetData(typeof(Markdig.Renderers.Html.HtmlAttributes)); if (null != htmlAttributes.Properties) { foreach (var entry in htmlAttributes.Properties) { switch (entry.Key.ToLowerInvariant()) { case "width": width = GetLength(entry.Value); break; case "height": height = GetLength(entry.Value); break; } } } } ImagePartType imgPartType = ImagePartType.Jpeg; switch (streamResult.Extension.ToLowerInvariant()) { case ".bmp": imgPartType = ImagePartType.Bmp; break; case ".emf": imgPartType = ImagePartType.Emf; break; case ".gif": imgPartType = ImagePartType.Gif; break; case ".ico": imgPartType = ImagePartType.Icon; break; case ".jpg": case ".jpeg": imgPartType = ImagePartType.Jpeg; break; case ".pcx": imgPartType = ImagePartType.Pcx; break; case ".png": imgPartType = ImagePartType.Png; break; case ".tif": case ".tiff": imgPartType = ImagePartType.Tiff; break; case ".wmf": imgPartType = ImagePartType.Wmf; break; default: throw new NotImplementedException(); } MainDocumentPart mainPart = renderer._wordDocument.MainDocumentPart; ImagePart imagePart = mainPart.AddImagePart(imgPartType); imageStream.Seek(0, SeekOrigin.Begin); imagePart.FeedData(imageStream); AddImageToBody(renderer, mainPart.GetIdOfPart(imagePart), streamResult, width, height); } }