Para ler, manipular e modificar programaticamente o conteúdo e a formatação de um documento, você precisa traduzi-lo para Aspose.Words Document Object Model (DOM).
Ao contrário dos documentos do Word, o Markdown não está em conformidade com o DOM descrito no artigo Aspose.Words Document Object Model (DOM). No entanto, Aspose.Words fornece seu próprio mecanismo para traduzir documentos Markdown para DOM e vice-versa, para que possamos trabalhar com sucesso com seus elementos como formatação de texto, tabelas, cabeçalhos e outros.
Este artigo explica como os vários recursos markdown podem ser traduzidos para Aspose.Words DOM e de volta para o formato Markdown.
Complexidade da tradução Markdown – DOM – Markdown
A principal dificuldade desse mecanismo não é apenas traduzir Markdown para DOM, mas também fazer a transformação reversa – salvar o documento de volta no formato Markdown com perda mínima. Existem elementos, como cotações multiníveis, para os quais a transformação reversa não é trivial.
Nosso mecanismo de tradução permite aos usuários não apenas trabalhar com elementos complexos em um documento Markdown existente, mas também criar seu próprio documento no formato Markdown com a estrutura original do zero. Para criar vários elementos, você precisa usar estilos com nomes específicos de acordo com certas regras descritas posteriormente neste artigo. Esses estilos podem ser criados programaticamente.
Princípios Comuns de Tradução
Usamos formatação Font para blocos embutidos. Quando não há correspondência direta para um recurso Markdown no Aspose.Words DOM, usamos um estilo de caractere com um nome que começa com algumas palavras especiais.
Para blocos de contêiner, usamos herança de estilo para denotar recursos Markdown aninhados. Neste caso, mesmo quando não há recursos aninhados, também usamos estilos de parágrafo com um nome que começa com algumas palavras especiais.
Listas com marcadores e ordenadas também são blocos de contêineres no Markdown. Seu aninhamento é representado em DOM da mesma forma que para todos os outros blocos contêineres usando herança de estilo. No entanto, além disso, as listas em DOM têm formatação de número correspondente no estilo de lista ou na formatação de parágrafo.
Blocos embutidos
Usamos a formatação Font ao traduzir recursos Bold, Italic ou Strikethrough markdown inline.
Recurso Markdown
Aspose.Words
Bold {1}
Font.bold = True
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Make the text Bold.builder.font.bold=Truebuilder.writeln("This text will be Bold")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.bold_text_example.md")
Italic *italic text*
Font.italic = True
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Make the text Italic.builder.font.italic=Truebuilder.writeln("This text will be Italic")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.italic_text_example.md")
Strikethrough ~Strikethrough text~
Font.strike_through = True
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Make the text Strikethrough.builder.font.strike_through=Truebuilder.writeln("This text will be Strikethrough")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.strikethrough_text_example.md")
Usamos um estilo de caractere com um nome que começa com a palavra InlineCode, seguido por um ponto opcional (.) e um número de crases (`) para o recurso InlineCode. Se vários crases forem perdidos, um crase será usado por padrão.
Recurso Markdown
Aspose.Words
InlineCode {1}
Font.style_name = "InlineCode[.][N]"
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Number of backticks is missed, one backtick will be used by default.inlineCode1BackTicks=builder.document.styles.add(aw.StyleType.CHARACTER,"InlineCode")builder.font.style=inlineCode1BackTicksbuilder.writeln("Text with InlineCode style with 1 backtick")# There will be 3 backticks.inlineCode3BackTicks=builder.document.styles.add(aw.StyleType.CHARACTER,"InlineCode.3")builder.font.style=inlineCode3BackTicksbuilder.writeln("Text with InlineCode style with 3 backtick")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.inline_code_example.md")
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Insert hyperlink.builder.insert_hyperlink("https://www.aspose.com","https://www.aspose.com",False);builder.insert_hyperlink("email@aspose.com","mailto:email@aspose.com",False);builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.autolink_example.md")
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Insert hyperlink.builder.insert_hyperlink("Aspose","https://www.aspose.com",False)builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.link_example.md")
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Insert image.shape=aw.drawing.Shape(builder.document,aw.drawing.ShapeType.IMAGE)shape.wrap_type=aw.drawing.WrapType.INLINEshape.image_data.source_full_name="/attachment/1456/pic001.png"shape.image_data.title="title"builder.insert_node(shape)builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.image_example.md")
Blocos de contêiner
Um documento é uma sequência de blocos contêineres, como títulos, parágrafos, listas, citações e outros. Os blocos de contêineres podem ser divididos em 2 classes: blocos de folhas e contêineres complexos. Os blocos folha só podem conter conteúdo embutido. Contêineres complexos, por sua vez, podem conter outros blocos de contêineres, incluindo blocos Leaf.
Blocos de folhas
A tabela abaixo mostra exemplos de uso de blocos Markdown Leaf em Aspose.Words:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ParagraphFormat.style_name = "Heading N", onde (1≤ N ≤ 9). Isso é traduzido em um estilo integrado e deve seguir exatamente o padrão especificado (sem sufixos ou prefixos são permitidos). Caso contrário, será apenas um parágrafo normal com um estilo correspondente
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Setext Heading === (se o título for nível 1), --- (se título nível 2)
ParagraphFormat.style_name = "SetextHeading[some suffix]", baseado no estilo "Heading N". Se (N ≥ 2), então será usado "Heading 2", caso contrário, "Heading 1". Qualquer sufixo é permitido, mas o importador Aspose.Words usa os números “1” e “2”, respectivamente
# Use a document builder to add content to the document.doc=aw.Document()builder=aw.DocumentBuilder(doc)builder.paragraph_format.style_name="Heading 1"builder.writeln("This is an H1 tag")# Reset styles from the previous paragraph to not combine styles between paragraphs.builder.font.bold=Falsebuilder.font.italic=FalsesetexHeading1=doc.styles.add(aw.StyleType.PARAGRAPH,"SetexHeading1")builder.paragraph_format.style=setexHeading1doc.styles.get_by_name("SetexHeading1").base_style_name="Heading 1"builder.writeln("Setex Heading level 1")builder.paragraph_format.style=doc.styles.get_by_name("Heading 3")builder.writeln("This is an H3 tag")# Reset styles from the previous paragraph to not combine styles between paragraphs.builder.font.bold=Falsebuilder.font.italic=FalsesetexHeading2=doc.styles.add(aw.StyleType.PARAGRAPH,"SetexHeading2")builder.paragraph_format.style=setexHeading2doc.styles.get_by_name("SetexHeading2").base_style_name="Heading 3"# Setex heading level will be reset to 2 if the base paragraph has a Heading level greater than 2.builder.writeln("Setex Heading level 2")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.setext_heading_example.md")
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()indentedCode=builder.document.styles.add(aw.StyleType.PARAGRAPH,"IndentedCode")builder.paragraph_format.style=indentedCodebuilder.writeln("This is an indented code")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.indented_code_example.md")
Fenced Code
```c#if()thenelse```
ParagraphFormat.style_name = "FencedCode[.][info string]" O [.] e o [info string] são opcionais
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()fencedCode=builder.document.styles.add(aw.StyleType.PARAGRAPH,"FencedCode")builder.paragraph_format.style=fencedCodebuilder.writeln("This is an fenced code")fencedCodeWithInfo=builder.document.styles.add(aw.StyleType.PARAGRAPH,"FencedCode.C#")builder.paragraph_format.style=fencedCodeWithInfobuilder.writeln("This is a fenced code with info string")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.fenced_code_example.md")
Contêineres Complexos
A tabela abaixo mostra exemplos de uso de contêineres complexos Markdown em Aspose.Words:
Recurso Markdown
Aspose.Words
Quote > quote, >> nested quote
ParagraphFormat.style_name = "Quote[some suffix]" O sufixo no nome do estilo é opcional, mas o importador Aspose.Words usa os números ordenados 1, 2, 3,…. no caso de aspas aninhadas. O aninhamento é definido através dos estilos herdados
# Use a document builder to add content to the document.doc=aw.Document()builder=aw.DocumentBuilder(doc)# By default a document stores blockquote style for the first level.builder.paragraph_format.style_name="Quote"builder.writeln("Blockquote")# Create styles for nested levels through style inheritance.quoteLevel2=doc.styles.add(aw.StyleType.PARAGRAPH,"Quote1")builder.paragraph_format.style=quoteLevel2doc.styles.get_by_name("Quote1").base_style_name="Quote"builder.writeln("1. Nested blockquote")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.quote_example.md")
As listas com marcadores são representadas usando numeração de parágrafo: ListFormat.apply_bullet_default() Pode haver 3 tipos de listas com marcadores. Eles são diferenciados apenas em um formato de numeração de primeiro nível. São eles: '-', '+' ou '*' respectivamente
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()builder.list_format.apply_bullet_default()builder.list_format.list.list_levels[0].number_format="-"builder.writeln("Item 1")builder.writeln("Item 2")builder.list_format.list_indent()builder.writeln("Item 2a")builder.writeln("Item 2b")builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.bulleted_list_example.md")
As listas ordenadas são representadas usando numeração de parágrafo: ListFormat.apply_number_default() Pode haver 2 marcadores de formato numérico: '.' e ')'. O marcador padrão é '.'
# Use a document builder to add content to the document.builder=aw.DocumentBuilder()# Add the first row.builder.insert_cell()builder.writeln("a")builder.insert_cell()builder.writeln("b")builder.end_row()# Add the second row.builder.insert_cell()builder.writeln("c")builder.insert_cell()builder.writeln("d")builder.end_table()builder.document.save(docs_base.artifacts_dir+"WorkingWithMarkdown.ordered_list_table.md")