Traduci Markdown in Document Object Model (DOM)

Per leggere, manipolare e modificare a livello di codice il contenuto e la formattazione di un documento, è necessario tradurlo in Aspose.Words Document Object Model (DOM).

A differenza dei documenti Word, Markdown non è conforme al DOM descritto nell’articolo Aspose.Words Document Object Model (DOM). Tuttavia, Aspose.Words fornisce il proprio meccanismo per tradurre i documenti Markdown in DOM e viceversa, in modo da poter lavorare con successo con i loro elementi come la formattazione del testo, tabelle, intestazioni e altri.

Questo articolo spiega come le varie funzionalità markdown possono essere tradotte in Aspose.Words DOM e nuovamente in formato Markdown.

Complessità della Traduzione Markdown – DOM – Markdown

La difficoltà principale di questo meccanismo non è solo tradurre Markdown in DOM, ma anche fare la trasformazione inversa – salvare il documento nel formato Markdown con una perdita minima. Ci sono elementi, come le virgolette multilivello, per i quali la trasformazione inversa non è banale.

Il nostro motore di traduzione consente agli utenti non solo di lavorare con elementi complessi in un documento Markdown esistente, ma anche di creare da zero il proprio documento in formato Markdown con la struttura originale. Per creare vari elementi, è necessario utilizzare stili con nomi specifici secondo alcune regole descritte più avanti in questo articolo. Tali stili possono essere creati a livello di codice.

Principi comuni di traduzione

Usiamo la formattazione Font per i blocchi in linea. Quando non esiste una corrispondenza diretta per una caratteristica Markdown in Aspose.Words DOM, utilizziamo uno stile di carattere con un nome che inizia con alcune parole speciali.

Per i blocchi contenitore, utilizziamo l’ereditarietà dello stile per denotare le funzionalità Markdown nidificate. In questo caso, anche quando non sono presenti elementi nidificati, utilizziamo anche stili di paragrafo con un nome che inizia con alcune parole speciali.

Anche gli elenchi puntati e ordinati sono blocchi contenitori in Markdown. Il loro annidamento è rappresentato in DOM allo stesso modo di tutti gli altri blocchi contenitore utilizzando l’ereditarietà dello stile. Tuttavia, inoltre, gli elenchi in DOM hanno una formattazione numerica corrispondente sia nello stile elenco che nella formattazione paragrafo.

Blocchi in linea

Utilizziamo la formattazione Font durante la traduzione delle funzionalità markdown in linea Bold, Italic o Strikethrough.

Funzionalità 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 = True
builder.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 = True
builder.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 = True
builder.writeln("This text will be Strikethrough")

builder.document.save(docs_base.artifacts_dir + "WorkingWithMarkdown.strikethrough_text_example.md")

Utilizziamo uno stile di carattere con un nome che inizia con la parola InlineCode, seguito da un punto (.) opzionale e da un numero di apici inversi (`) per la funzionalità InlineCode. Se viene mancato un certo numero di backtick, per impostazione predefinita verrà utilizzato un backtick.

Funzionalità 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 = inlineCode1BackTicks
builder.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 = inlineCode3BackTicks
builder.writeln("Text with InlineCode style with 3 backtick")

builder.document.save(docs_base.artifacts_dir + "WorkingWithMarkdown.inline_code_example.md")
Autolink
<scheme://domain.com>
<email@domain.com>
La classe FieldHyperlink
# 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")
Link
{1}
{2}
{3}
{4})
Il FieldHyperlink
# 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")
Image
{1}
{2}
{3}
{4})
La classe Shape
# 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.INLINE
shape.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")

Blocchi contenitore

Un documento è una sequenza di blocchi contenitori come intestazioni, paragrafi, elenchi, virgolette e altri. I blocchi contenitore possono essere suddivisi in 2 classi: blocchi foglia e contenitori complessi. I blocchi foglia possono contenere solo contenuto in linea. I contenitori complessi, a loro volta, possono contenere altri blocchi contenitore, inclusi i blocchi Foglia.

Blocchi di foglie

La tabella seguente mostra esempi di utilizzo dei blocchi Leaf Markdown in Aspose.Words:

Funzionalità Markdown Aspose.Words
HorizontalRule
-----
Questo è un semplice paragrafo con una forma di Regola Orizzontale corrispondente:
DocumentBuilder.insert_horizontal_rule()
ATX Heading
# H1, ## H2, ### H3…
ParagraphFormat.style_name = "Heading N", dove (1<= N <= 9).
Questo viene tradotto in uno stile integrato e dovrebbe essere esattamente del modello specificato (non sono ammessi suffissi o prefissi).
Altrimenti sarà solo un normale paragrafo con uno stile corrispondente
Setext Heading
=== (se Titolo di livello 1),
--- (se intestazione di livello 2)
ParagraphFormat.style_name = "SetextHeading[some suffix]", basato sullo stile "Heading N".
Se (N >= 2), verrà utilizzato "Heading 2", altrimenti "Heading 1".
È consentito qualsiasi suffisso, ma l’importatore Aspose.Words utilizza rispettivamente i numeri “1” e “2”
# 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 = False
builder.font.italic = False

setexHeading1 = doc.styles.add(aw.StyleType.PARAGRAPH, "SetexHeading1")
builder.paragraph_format.style = setexHeading1
doc.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 = False
builder.font.italic = False

setexHeading2 = doc.styles.add(aw.StyleType.PARAGRAPH, "SetexHeading2")
builder.paragraph_format.style = setexHeading2
doc.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")
Indented Code ParagraphFormat.style_name = "IndentedCode[some suffix]"
# 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 = indentedCode
builder.writeln("This is an indented code")

builder.document.save(docs_base.artifacts_dir + "WorkingWithMarkdown.indented_code_example.md")
Fenced Code
``` c#
if ()
then
else
```
ParagraphFormat.style_name = "FencedCode[.][info string]"
[.] e [info string] sono facoltativi
# 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 = fencedCode
builder.writeln("This is an fenced code")

fencedCodeWithInfo = builder.document.styles.add(aw.StyleType.PARAGRAPH, "FencedCode.C#")
builder.paragraph_format.style = fencedCodeWithInfo
builder.writeln("This is a fenced code with info string")

builder.document.save(docs_base.artifacts_dir + "WorkingWithMarkdown.fenced_code_example.md")

Contenitori complessi

La tabella seguente mostra esempi di utilizzo dei contenitori complessi Markdown in Aspose.Words:

Funzionalità Markdown Aspose.Words
Quote
> quote,
>> nested quote
ParagraphFormat.style_name = "Quote[some suffix]"
Il suffisso nel nome dello stile è facoltativo, ma l’importatore Aspose.Words utilizza i numeri ordinati 1, 2, 3, …. in caso di virgolette annidate.
L’annidamento è definito tramite gli stili ereditati
# 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 = quoteLevel2
doc.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")
BulletedList
- Item 1
- Item 2
- Item 2a
- Item 2b
Gli elenchi puntati sono rappresentati utilizzando la numerazione dei paragrafi:
ListFormat.apply_bullet_default()
Possono essere presenti 3 tipi di elenchi puntati. Differiscono solo nel formato di numerazione di primissimo livello. Questi sono rispettivamente: '-', '+' o '*'
# 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")
OrderedList
1. Item 1
2. Item 2
1) Item 2a
2) Item 2b
Gli elenchi ordinati sono rappresentati utilizzando la numerazione dei paragrafi:
ListFormat.apply_number_default()
Possono essere presenti 2 indicatori di formato numerico: '.' e ')'. L’indicatore predefinito è '.'
doc = aw.Document()
builder = aw.DocumentBuilder(doc)

builder.list_format.apply_number_default()

builder.writeln("Item 1")
builder.writeln("Item 2")

builder.list_format.list_indent()

builder.writeln("Item 2a")
builder.write("Item 2b")

builder.document.save(docs_base.artifacts_dir + "WorkingWithMarkdown.ordered_list_example.md")

Tabelle

Aspose.Words consente anche di tradurre le tabelle in DOM, come mostrato di seguito:

Funzionalità Markdown Aspose.Words
Table
a\ | b
-\ | -
c\ | d
Classi Table, Row e Cell
# 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")

Guarda anche