Subversion Repositories Scribus

Rev

Rev 23996 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
23992 craig 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
/***************************************************************************
8
                                                         -------------------
9
        begin                : Wed Aug 19 2020
10
        copyright            : (C) 2020 by Craig Bradney
11
        email                : cbradney@scribus.info
12
 ***************************************************************************/
13
#include "markdownim.h"
14
 
15
#include <QApplication>
16
#include <QByteArray>
17
#include <QTextBlock>
18
#include <QTextBlockFormat>
19
#include <QTextCharFormat>
20
#include <QTextDocument>
21
#include <QTextFrameFormat>
22
#include <QTextListFormat>
23
 
24
#include "prefsmanager.h"
25
#include "scribus.h"
26
#include "scribusdoc.h"
27
#include "styles/charstyle.h"
28
#include "styles/paragraphstyle.h"
29
 
30
QString FileFormatName()
31
{
32
        return QObject::tr("MarkDown Document");
33
}
34
 
35
QStringList FileExtensions()
36
{
37
        return QStringList("md");
38
}
39
 
40
void GetText2(const QString& filename, const QString& encoding, bool textOnly, bool prefix, bool append, PageItem *textItem)
41
{
42
        MarkDownIm* markdownim = new MarkDownIm(filename, textItem, textOnly, prefix, append);
43
        delete markdownim;
44
}
45
 
46
MarkDownIm::MarkDownIm(const QString& fileName, PageItem *textItem, bool textOnly, bool prefix, bool append)
47
{
48
        m_Doc = textItem->doc();
49
        m_item = textItem;
50
        m_textOnly = textOnly;
51
        m_prefixName = prefix;
52
        m_append = append;
53
 
54
        QFile f(fileName);
55
        if (!f.open(QIODevice::ReadOnly))
56
                return;
57
 
58
        QByteArray data = f.readAll();
59
        f.close();
60
 
61
        m_importedText.setMarkdown(data, QTextDocument::MarkdownDialectGitHub);
62
        if (!append)
63
        {
64
                QString defaultParagraphStyle = CommonStrings::DefaultParagraphStyle;
65
                ParagraphStyle newStyle;
66
                newStyle.setDefaultStyle(false);
67
                newStyle.setParent(defaultParagraphStyle);
68
                m_item->itemText.clear();
69
                m_item->itemText.setDefaultStyle(newStyle);
70
        }
71
        parseMarkDown();
72
        m_item->itemText.trim();
73
        m_item->itemText.invalidateLayout();
74
}
75
 
76
void MarkDownIm::parseMarkDown()
77
{
78
        struct styleStruct
79
        {
80
                int start;
81
                int length;
82
                QString styleName;
83
        };
84
        QList<styleStruct> styleApplicationList;
85
 
86
        StyleSet<ParagraphStyle> newParaStyleSet;
87
        StyleSet<CharStyle> newCharStyleSet;
88
        defaultParagraphStyle.setParent(CommonStrings::DefaultParagraphStyle);
89
        defaultParagraphStyle.charStyle().setParent(CommonStrings::DefaultCharacterStyle);
90
        defaultParagraphStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
91
        m_item->itemText.clear();
92
        m_item->itemText.setDefaultStyle(defaultParagraphStyle);
93
 
94
        int blockCount = m_importedText.blockCount();
95
        for (int i = 0; i < blockCount; i++)
96
        {
97
                QTextBlock curblk = m_importedText.findBlockByNumber(i);
98
                if (!curblk.isValid())
99
                        continue;
100
                styleApplicationList.clear();
101
                currentParagraphStyle = defaultParagraphStyle;
102
                if (!m_textOnly)
103
                {
104
                        //Check for and create Heading styles
105
                        int headingLevel = curblk.blockFormat().headingLevel();
106
                        if (headingLevel > 0)
107
                        {
108
                                QString headingName=QString("Heading %1").arg(headingLevel);
109
                                if (!newParaStyleSet.contains(headingName))
110
                                {
111
                                        ParagraphStyle newParaStyle;
112
                                        newParaStyle.setParent(CommonStrings::DefaultParagraphStyle);
113
                                        newParaStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
114
                                        newParaStyle.setContext(m_item->itemText.defaultStyle().context());
115
                                        newParaStyle.charStyle().setFontSize(20 * (7-headingLevel) + newParaStyle.charStyle().fontSize());
116
                                        QString styleName;
117
                                        if (m_prefixName)
118
                                                styleName=m_item->itemName() + "_";
119
                                        styleName+=headingName;
120
                                        newParaStyle.setName(styleName);
121
                                        newParaStyleSet.create(newParaStyle);
122
                                        currentParagraphStyle = newParaStyle;
123
                                }
124
                                else
125
                                        currentParagraphStyle = newParaStyleSet.get(headingName);
126
                        }
127
 
128
                        for (QTextBlock::iterator it = curblk.begin(); !(it.atEnd()); ++it)
129
                        {
130
                                QTextFragment currentFragment = it.fragment();
131
                                if (currentFragment.isValid())
132
                                {
133
                                        if (currentFragment.charFormat().isValid())
134
                                        {
135
                                                QTextCharFormat cf = currentFragment.charFormat();
136
                                                bool charFormatFound = false;
137
                                                CharStyle cs;
138
                                                cs.setParent(CommonStrings::DefaultCharacterStyle);
139
                                                cs.setContext(m_item->itemText.defaultStyle().context());
140
                                                QString styleName;
141
                                                if (m_prefixName)
142
                                                        styleName=m_item->itemName() + "_";
143
                                                StyleFlag s(cs.effects());
144
                                                if (cf.fontStrikeOut())
145
                                                {
146
                                                        charFormatFound = true;
147
                                                        styleName+="Strikethrough";
148
                                                        cs.setName(styleName);
149
                                                        s |= ScStyle_Strikethrough;
150
                                                        cs.setFeatures(s.featureList());
151
                                                }
152
                                                //Bold and Italic
153
                                                bool isBold = cf.fontWeight() == QFont::Bold;
154
                                                bool isItalic = cf.fontItalic();
155
                                                if ((isBold && headingLevel == 0) || isItalic)
156
                                                {
157
                                                        charFormatFound = true;
158
                                                        if (isBold)
159
                                                                styleName+="Bold";
160
                                                        if (isItalic)
161
                                                                styleName+="Italic";
162
                                                        cs.setName(styleName);
163
                                                        QString family(m_item->itemText.charStyle(m_item->itemText.length()).font().family());
164
                                                        if (!family.isEmpty())
165
                                                        {
166
                                                                QStringList slist = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts.fontMap[family];
167
                                                                if (isBold)
168
                                                                {
169
                                                                        if (isItalic)
170
                                                                        {
171
                                                                                if (slist.contains("Bold Italic"))
172
                                                                                        cs.setFont(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[family + " Bold Italic"]);
173
                                                                        }
174
                                                                        else if (slist.contains("Bold"))
175
                                                                                cs.setFont(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[family + " Bold"]);
176
                                                                }
177
                                                                else
178
                                                                {
179
                                                                        if (isItalic)
180
                                                                        {
181
                                                                                if (slist.contains("Italic"))
182
                                                                                        cs.setFont(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[family + " Italic"]);
183
                                                                        }
184
                                                                        else if (slist.contains("Regular"))
185
                                                                                cs.setFont(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[family + " Regular"]);
186
                                                                }
187
                                                        }
188
                                                }
189
                                                if (charFormatFound)
190
                                                {
191
                                                        newCharStyleSet.create(cs);
192
                                                        styleStruct ss;
193
                                                        ss.start = currentFragment.position();
194
                                                        ss.length = currentFragment.length();
195
                                                        ss.styleName = cs.name();
196
                                                        styleApplicationList.append(ss);
197
                                                }
198
                                        }
199
                                }
200
                        }
201
                }
202
 
203
                ParagraphStyle paraStyle;
204
                paraStyle.setParent(currentParagraphStyle.name());
205
                m_item->itemText.insertChars(m_item->itemText.length(), curblk.text());
206
                m_item->itemText.insertChars(m_item->itemText.length(), SpecialChars::PARSEP);
207
                if (!m_textOnly)
208
                {
209
                        m_item->itemText.applyStyle(m_item->itemText.length() - 1, paraStyle);
210
                        for (int i = 0; i < styleApplicationList.size(); ++i)
211
                        {
212
                                CharStyle charStyle;
213
                                charStyle.setParent(styleApplicationList.at(i).styleName);
214
                                m_item->itemText.applyCharStyle(styleApplicationList.at(i).start, styleApplicationList.at(i).length, charStyle);
215
                        }
216
                }
217
        }
218
        if (!m_textOnly)
219
        {
220
                m_Doc->redefineStyles(newParaStyleSet, false);
221
                m_Doc->redefineCharStyles(newCharStyleSet, false);
222
        }
223
}
224
 
225