Translate Markdown to Document Object Model (DOM)

Aby programowo odczytywać, manipulować i modyfikować zawartość i formatowanie dokumentu, należy przetłumaczyć go na model obiektowy dokumentu Aspose.Words (DOM).

W przeciwieństwie do dokumentów Word, Markdown nie jest zgodny z DOM opisanym w Aspose.Words Obiektowy Model Dokumentu (DOM) artykuł. Jednak Aspose.Words zapewnia własny mechanizm tłumaczenia dokumentów Markdown na DOM iz powrotem, dzięki czemu możemy z powodzeniem pracować z ich elementami, takimi jak formatowanie tekstu, tabele, nagłówki i inne.

W tym artykule wyjaśniono, w jaki sposób różne funkcje markdown można przetłumaczyć na Aspose.Words DOM iz powrotem do formatu Markdown.

Złożoność tłumaczenia Markdown – DOM – Markdown

Główną trudnością tego mechanizmu jest nie tylko przetłumaczenie Markdown na DOM, ale także wykonanie odwrotnej transformacji – zapisanie dokumentu z powrotem do formatu Markdown przy minimalnych stratach. Istnieją elementy, takie jak cudzysłowy wielopoziomowe, dla których odwrotna transformacja nie jest trywialna.

Nasz silnik tłumaczeń pozwala użytkownikom nie tylko pracować ze złożonymi elementami w istniejącym dokumencie Markdown, ale także tworzyć własny dokument w formacie Markdown z oryginalną strukturą od podstaw. Aby utworzyć różne elementy, musisz użyć stylów o określonych nazwach zgodnie z pewnymi zasadami opisanymi w dalszej części tego artykułu. Takie style można tworzyć programowo.

Wspólne Zasady Tłumaczenia

Używamy formatowania Font dla bloków wbudowanych. Gdy nie ma bezpośredniej korespondencji dla funkcji Markdown w Aspose.Words DOM, używamy stylu znaków o nazwie zaczynającej się od niektórych specjalnych słów.

W przypadku bloków kontenerów używamy dziedziczenia stylów do oznaczania zagnieżdżonych funkcji Markdown. W takim przypadku, nawet jeśli nie ma funkcji zagnieżdżonych, używamy również stylów akapitów o nazwie zaczynającej się od niektórych specjalnych słów.

Listy punktowane i uporządkowane są również blokami kontenerów w Markdown. Ich zagnieżdżanie jest reprezentowane w DOM w taki sam sposób, jak w przypadku wszystkich innych bloków kontenerów wykorzystujących dziedziczenie stylu. Jednak dodatkowo listy w DOM odpowiadały formatowaniu liczb w stylu listy lub formatowaniu akapitu.

Bloki Inline

Używamy formatowania Font podczas tłumaczenia funkcji Bold, Italic lub Strikethrough inline markdown.

Markdown funkcja Aspose.Words
Bold
**bold text**
get_Font()->set_Bold(true)
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// Make the text Bold.
builder->get_Font()->set_Bold(true);
builder->Writeln(u"This text will be Bold");
Italic
*italic text*
get_Font()->set_Italic(true)
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// Make the text Italic.
builder->get_Font()->set_Italic(true);
builder->Writeln(u"This text will be Italic");
Strikethrough
~Strikethrough text~
get_Font()->set_StrikeThrough(true)
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// Make the text Strikethrough.
builder->get_Font()->set_StrikeThrough(true);
builder->Writeln(u"This text will be Strikethrough");

Używamy stylu znaków o nazwie zaczynającej się od słowa InlineCode, po którym następuje opcjonalna kropka (.) i liczba backticks (`) dla funkcji InlineCode. Jeśli zostanie pominięta liczba backticks, domyślnie zostanie użyty jeden backtick.

Markdown funkcja Aspose.Words
InlineCode
**inline code**
get_Font()->set_StyleName(u"InlineCode[.][N]")
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// Number of backticks is missed, one backtick will be used by default.
auto inlineCode1BackTicks = builder->get_Document()->get_Styles->Add(StyleType::Character, u"InlineCode");
builder->get_Font()->set_Style(inlineCode1BackTicks);
builder->Writeln(u"Text with InlineCode style with 1 backtick");
// There will be 3 backticks.
auto inlineCode3BackTicks = builder->get_Document()->get_Styles->Add(StyleType::Character, u"InlineCode.3");
builder->get_Font()->set_Style(inlineCode3BackTicks);
builder->Writeln(u"Text with InlineCode style with 3 backtick");
Autolink
<scheme://domain.com>
<email@domain.com>
Klasa FieldHyperlink.
Link
[link text](url)
[link text](<url>"title")
[link text](url 'title')
[link text](url (title))
Klasa FieldHyperlink.
Image
![](url)
![alt text](<url>"title")
![alt text](url ‘title’)
![alt text](url (title))
Klasa Shape.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// Insert image.
auto shape = System::MakeObject<Shape>(doc, ShapeType::Image);
shape->set_WrapType(WrapType::Inline);
shape->get_ImageData()->set_SourceFullName(u"/attachment/1456/pic001.png");
shape->get_ImageData()->set_Title(u"title");
builder->InsertNode(shape);

Bloki Kontenerowe

Dokument to sekwencja bloków kontenerów, takich jak nagłówki, akapity, listy, cudzysłowy i inne. Bloki kontenerowe można podzielić na 2 klasy: bloki liściowe i złożone Pojemniki. Bloki liści mogą zawierać tylko zawartość wbudowaną. Z kolei złożone pojemniki mogą zawierać inne bloki kontenerów, w tym bloki liści.

Bloki Liści

Poniższa tabela przedstawia przykłady użycia Markdown bloków liści w Aspose.Words:

Markdown funkcja Aspose.Words
HorizontalRule
-----
To jest prosty akapit o odpowiednim kształcie HorizontalRule:
DocumentBuilder::InsertHorizontalRule()
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// Insert horizontal rule.
builder->InsertHorizontalRule();
ATX Heading
# H1, ## H2, ### H3…
get_ParagraphFormat()->set_StyleName(u"Heading N"), gdzie (1<= N <= 9).
Jest to tłumaczone na wbudowany styl i powinno mieć dokładnie określony wzór (nie są dozwolone żadne przyrostki ani przedrostki).
W przeciwnym razie będzie to zwykły akapit z odpowiednim stylem.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// By default Heading styles in Word may have Bold and Italic formatting.
// If we do not want to be emphasized, set these properties explicitly to false.
builder->get_Font()->set_Bold(false);
builder->get_Font()->set_Italic(false);
builder->get_ParagraphFormat()->set_StyleName(u"Heading 1");
builder->Writeln(u"This is an H1 tag");
Setext Heading
=== (if Heading level 1),
--- (if Heading level 2)
get_ParagraphFormat->set_StyleName(u"SetextHeading[some suffix]"), Na podstawie stylu “Nagłówek N”.
Jeśli (N >= 2), wówczas zostanie użyty " Heading 2", w przeciwnym razie " Heading 1".
Każdy przyrostek jest dozwolony, ale importer Aspose.Words używa odpowiednio liczb “1” i “2”.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
builder->get_ParagraphFormat()->set_StyleName(u"Heading 1");
builder->Writeln(u"This is an H1 tag");
// Reset styles from the previous paragraph to not combine styles between paragraphs.
builder->get_Font()->set_Bold(false);
builder->get_Font()->set_Italic(false);
auto setexHeading1 = builder->get_Document()->get_Styles->Add(StyleType::Paragraph, u"SetextHeading1");
builder->get_ParagraphFormat()->set_Style(setexHeading1);
doc->get_Styles()->idx_get(u"SetextHeading1")->set_BaseStyleName(u"Heading 1");
builder->Writeln(u"Setext Heading level 1");
builder->get_ParagraphFormat()->set_Style(doc->get_Styles()->idx_get(u"Heading 3"));
builder->Writeln(u"This is an H3 tag");
// Reset styles from the previous paragraph to not combine styles between paragraphs.
builder->get_Font()->set_Bold(false);
builder->get_Font()->set_Italic(false);
auto setexHeading2 = builder->get_Document()->get_Styles->Add(StyleType::Paragraph, u"SetextHeading2");
builder->get_ParagraphFormat()->set_Style(setexHeading2);
doc->get_Styles()->idx_get(u"SetextHeading2")->set_BaseStyleName(u"Heading 3");
// Setex heading level will be reset to 2 if the base paragraph has a Heading level greater than 2.
builder->Writeln(u"Setext Heading level 2");
Indented Code get_ParagraphFormat->set_StyleName(u"IndentedCode[some suffix]")
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
auto indentedCode = builder->get_Document()->get_Styles->Add(StyleType::Paragraph, u"IndentedCode");
builder->get_ParagraphFormat()->set_StyleName(indentedCode);
builder->Writeln(u"This is an indented code");
Fenced Code
``` c#
if ()
then
else
```
get_ParagraphFormat()->set_StyleName(u"FencedCode[.][info string]")
[.] i [info string] są opcjonalne.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
auto fencedCode = builder->get_Document()->get_Styles->Add(StyleType::Paragraph, u"FencedCode");
builder->get_ParagraphFormat()->set_StyleName(fencedCode);
builder->Writeln(u"This is an fenced code");
auto fencedCodeWithInfo = builder->get_Document()->get_Styles->Add(StyleType::Paragraph, u"FencedCode.C#");
builder->get_ParagraphFormat()->set_StyleName(fencedCodeWithInfo);
builder->Writeln(u"This is a fenced code with info string");

Złożone Kontenery

Poniższa tabela przedstawia przykłady użycia Markdown złożonych kontenerów w Aspose.Words:

Markdown funkcja Aspose.Words
Quote
> quote,
>> nested quote
get_ParagraphFormat()->set_StyleName(u"Quote[some suffix]")
przyrostek w nazwie stylu jest opcjonalny, ale importer Aspose.Words używa uporządkowanych liczb 1, 2, 3, …. w przypadku zagnieżdżonych cytatów.
Zagnieżdżanie jest definiowane za pomocą odziedziczonych stylów.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto doc = System::MakeObject<Document>();
auto builder = System::MakeObject<DocumentBuilder>(doc);
// By default a document stores blockquote style for the first level.
builder->get_ParagraphFormat()->set_StyleName(u"Quote");
builder->Writeln(u"Blockquote");
// Create styles for nested levels through style inheritance.
auto quoteLevel2 = builder->get_Document()->get_Styles->Add(StyleType::Paragraph, u"Quote1");
builder->get_ParagraphFormat()->set_StyleName(quoteLevel2);
builder->get_Document()->get_Styles->idx_get(u"Quote1")->set_BaseStyleName(u"Quote");
builder->Writeln(u"1. Nested blockquote");
BulletedList
- Item 1
- Item 2
- Item 2a
- Item 2b
Listy punktowane są reprezentowane za pomocą numeracji akapitów:
get_ListFormat()->ApplyBulletDefault()
mogą istnieć 3 typy list punktowanych. Różnią się tylko w formacie numeracji pierwszego poziomu. Są to odpowiednio: ‘-’, ‘+’ lub ‘*’.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
builder->get_ListFormat()->ApplyBulletDefault();
builder->get_ListFormat()->get_List()->get_ListLevels()->idx_get(0)->set_NumberFormat(u"-");
builder->Writeln(u"Item 1");
builder->Writeln(u"Item 2");
builder->get_ListFormat()->ListIndent();
builder->Writeln(u"Item 2a");
builder->Writeln(u"Item 2b");
OrderedList
1. Item 1
2. Item 2
1) Item 2a
2) Item 2b
Uporządkowane listy są reprezentowane za pomocą numeracji akapitów:
get_ListFormat()->ApplyNumberDefault()
mogą istnieć 2 znaczniki formatu liczb: ‘.’ i ‘)’. Domyślnym znacznikiem jest ‘.’.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
builder->get_ListFormat()->ApplyBulletDefault();
builder->get_ListFormat()->get_List()->get_ListLevels()->idx_get(0)->set_NumberFormat(System::String::Format(u"{0}.", (char16_t)0));
builder->get_ListFormat()->get_List()->get_ListLevels()->idx_get(1)->set_NumberFormat(System::String::Format(u"{0}.", (char16_t)1));
builder->Writeln(u"Item 1");
builder->Writeln(u"Item 2");
builder->get_ListFormat()->ListIndent();
builder->Writeln(u"Item 2a");
builder->Writeln(u"Item 2b");

Tabele

Aspose.Words umożliwia również tłumaczenie tabel na DOM, Jak pokazano poniżej:

Markdown funkcja Aspose.Words
Table
a|b
-|-
c|d
Table, Row i Cell klasy.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Use a document builder to add content to the document.
auto builder = System::MakeObject<DocumentBuilder>();
// Add the first row.
builder->InsertCell();
builder->Writeln(u"a");
builder->InsertCell();
builder->Writeln(u"b");
// Add the second row.
builder->InsertCell();
builder->Writeln(u"c");
builder->InsertCell();
builder->Writeln(u"d");

Zobacz także