Exemple #1
0
void MainWindow::highlightListItems()
{
    QTextCursor cursor = editor->textCursor();
    QTextList *list = cursor.currentList();

    if (!list)
        return;

    cursor.beginEditBlock();
//! [0]
    for (int index = 0; index < list->count(); ++index) {
        QTextBlock listItem = list->item(index);
//! [0]
        QTextBlockFormat newBlockFormat = listItem.blockFormat();
        newBlockFormat.setBackground(Qt::lightGray);
        QTextCursor itemCursor = cursor;
        itemCursor.setPosition(listItem.position());
        //itemCursor.movePosition(QTextCursor::StartOfBlock);
        itemCursor.movePosition(QTextCursor::EndOfBlock,
                                QTextCursor::KeepAnchor);
        itemCursor.setBlockFormat(newBlockFormat);
        /*
//! [1]
        processListItem(listItem);
//! [1]
        */
//! [2]
    }
//! [2]
    cursor.endEditBlock();
}
Exemple #2
0
void HtmlExporter::emitBlock( const QTextBlock &block )
{
    // save and later restore, in case we 'change' the default format by
    // emitting block char format information

    // NOTE the bottom line is commented, to use default charFormat, which can be set from outside.
    //QTextCharFormat oldDefaultCharFormat = defaultCharFormat;

    QString blockTag;
    bool isBlockQuote = false;
    const QTextBlockFormat blockFormat = block.blockFormat();

    if ( blockFormat.hasProperty( BilboTextFormat::IsBlockQuote ) && 
         blockFormat.boolProperty( BilboTextFormat::IsBlockQuote ) ) {
        isBlockQuote = true;
    }
    QTextList *list = block.textList();
    if ( list ) {
        if ( list->itemNumber( block ) == 0 ) { // first item? emit <ul> or appropriate
//    qDebug() << "first item" << endl;
            if ( isBlockQuote ) {
                html += QLatin1String( "<blockquote>" );
            }
            const QTextListFormat format = list->format();
            const int style = format.style();
            switch ( style ) {
                case QTextListFormat::ListDecimal:
                    html += QLatin1String( "<ol" );
                    break;
                case QTextListFormat::ListDisc:
                    html += QLatin1String( "<ul" );
                    break;
                case QTextListFormat::ListCircle:
                    html += QLatin1String( "<ul type=\"circle\"" );
                    break;
                case QTextListFormat::ListSquare:
                    html += QLatin1String( "<ul type=\"square\"" );
                    break;
                case QTextListFormat::ListLowerAlpha:
                    html += QLatin1String( "<ol type=\"a\"" );
                    break;
                case QTextListFormat::ListUpperAlpha:
                    html += QLatin1String( "<ol type=\"A\"" );
                    break;
                default:
                    html += QLatin1String( "<ul" ); // ### should not happen
                    //qDebug() << html;
            }
            /*
            if (format.hasProperty(QTextFormat::ListIndent)) {
                html += QLatin1String(" style=\"-qt-list-indent: ");
                html += QString::number(format.indent());
                html += QLatin1String(";\"");
            }*/

            html += QLatin1Char( '>' );
        }
        blockTag = QLatin1String( "li" );
//         html += QLatin1String( "<li " );
    }

//     const QTextBlockFormat blockFormat = block.blockFormat();
    if ( blockFormat.hasProperty( QTextFormat::BlockTrailingHorizontalRulerWidth ) ) { 
        if ( ( blockFormat.hasProperty( BilboTextFormat::IsHtmlTagSign ) ) && 
            ( blockFormat.boolProperty( BilboTextFormat::IsHtmlTagSign ) ) ) {
            html += QLatin1String( "<!--split-->" );
            return;
        } else {
            html += QLatin1String( "<hr" );
    
            QTextLength width = blockFormat.lengthProperty( QTextFormat::BlockTrailingHorizontalRulerWidth );
            if ( width.type() != QTextLength::VariableLength ) {
                emitTextLength( "width", width );
            } else {
                html += QLatin1Char( ' ' );
            }
    
            html += QLatin1String( "/>" );
            return;
        }
    }

    const bool pre = blockFormat.nonBreakableLines();
    if ( pre ) {
//   qDebug() << "NonBreakable lines" << endl;
//         if (list) {
//             html += QLatin1Char('>');
//   }
//         html += QLatin1String( "<pre" );
//         emitBlockAttributes( block );
//         html += QLatin1Char( '>' );
        blockTag = QLatin1String( "pre" );

    } else {
        if (!list) {
            if ( isBlockQuote ) {
                html += QLatin1String( "<blockquote>" );
            }

            if ( ( blockFormat.hasProperty( BilboTextFormat::HtmlHeading ) ) && (
                blockFormat.intProperty( BilboTextFormat::HtmlHeading ) ) ) {
                const int index = blockFormat.intProperty( BilboTextFormat::HtmlHeading );
                blockTag = QLatin1Char( 'h' ) + QString::number( index );
            } else {
                //html += QLatin1String("<div");
//                 html += QLatin1String( "<p" );
                blockTag = QLatin1String( "p" );
            }
        }
    }
    if ( !blockTag.isEmpty() ) {
        html += QLatin1Char( '<' ) + blockTag;
        emitBlockAttributes( block );
        html += QLatin1Char( '>' );
    }

    QTextBlock::Iterator it = block.begin();

    for ( ; !it.atEnd(); ++it ) {
        emitFragment( it.fragment(), blockFormat );
    }

    if ( !blockTag.isEmpty() ) {
        html += QLatin1String( "</" ) + blockTag + QLatin1String( ">\n" );
    }

//     if ( pre ) {
//         html += QLatin1String( "</pre>\n" );
//     } else {
//         if ( list ) {
//             html += QLatin1String( "</li>\n" );
//         } else {
//             if ( blockFormat::boolProperty( BilboTextFormat::IsHtmlHeading ) ) {
//                 const int index = format.intProperty( QTextFormat::FontSizeAdjustment );
//                 switch ( index ) {
//                     case -2:
//                        html += QLatin1String( "</h6>" );
//                        break;
//                     case -1:
//                        html += QLatin1String( "</h5>" );
//                        break;
//                     case 0:
//                        html += QLatin1String( "</h4>" );
//                        break;
//                     case 1:
//                        html += QLatin1String( "</h3>" );
//                        break;
//                     case 2:
//                        html += QLatin1String( "<h2" );
//                        break;
//                     case 3:
//                        html += QLatin1String( "<h1" );
//                        break;
//                 }
//             } else {
//                 html += QLatin1String( "</p>\n" );
//             }
//         }
//     }
    // HACK html.replace( QRegExp("<br[\\s]*/>[\\n]*<br[\\s]*/>[\\n]*"),"<br />&nbsp;<br />" );

    if ( list ) {
        if ( list->itemNumber( block ) == list->count() - 1 ) { // last item? close list
            if ( isOrderedList( list->format().style() ) ) {
                html += QLatin1String( "</ol>\n" );
            } else {
                html += QLatin1String( "</ul>\n" );
            }
            if ( isBlockQuote ) {
                html += QLatin1String( "</blockquote>\n" );
            }
        }
    } else {
        if ( isBlockQuote ) {
            html += QLatin1String( "</blockquote>\n" );
        }
    }
    // NOTE the bottom line is commented, to use default charFormat, which can be set from outside.
    //defaultCharFormat = oldDefaultCharFormat;
}
Exemple #3
0
void QGithubMarkdown::read(const QByteArray &markdown, QTextDocument *target)
{
	doc = target;
	doc->clear();
	cursor = QTextCursor(doc);
	cursor.beginEditBlock();
	const QList<Token> tokens = tokenize(clean(QString::fromUtf8(markdown)));
	const QList<Paragraph> paragraphs = paragraphize(tokens);
	const auto paralists = listize(paragraphs);
	//std::for_each(paragraphs.begin(), paragraphs.end(), [](const Paragraph &item){qDebug() << item;});
	bool firstBlock = true;
	for (const auto paralist : paralists)
	{
		auto insertTokens = [&](const QList<Token> &tokens, const QTextCharFormat &format, const bool isCode)
		{
			QTextCharFormat fmt(format);
			QTextCharFormat codeFmt(format);
			codeFmt.setFontFamily("Monospace");
			QListIterator<Token> iterator(tokens);
			while (iterator.hasNext())
			{
				const Token token = iterator.next();
				if (isCode)
				{
					cursor.insertText(token.source);
				}
				else
				{
					if (token.type == Token::Bold)
					{
						if (fmt.fontWeight() == QFont::Bold)
						{
							fmt.setFontWeight(QFont::Normal);
						}
						else
						{
							fmt.setFontWeight(QFont::Bold);
						}
					}
					else if (token.type == Token::Italic)
					{
						fmt.setFontItalic(!fmt.fontItalic());
					}
					else if (token.type == Token::InlineCodeDelimiter)
					{
						while (iterator.hasNext())
						{
							const Token next = iterator.next();
							if (next.type == Token::InlineCodeDelimiter)
							{
								break;
							}
							else
							{
								cursor.insertText(token.source, codeFmt);
							}
						}
					}
					else if (token.type == Token::Character)
					{
						cursor.insertText(token.content.toChar(), fmt);
					}
					else
					{
						cursor.insertText(token.source, fmt);
					}
				}
			}
		};

		if (paralist.second.indent == -1)
		{
			const Paragraph paragraph = paralist.first;
			QTextCharFormat charFmt;
			QTextBlockFormat blockFmt;
			blockFmt.setBottomMargin(5.0f);
			if (Paragraph::FirstHeading <= paragraph.type && paragraph.type <= Paragraph::LastHeading)
			{
				charFmt.setFontPointSize(sizeMap[paragraph.type]);
			}
			else if (paragraph.type == Paragraph::Quote)
			{
				blockFmt.setIndent(1);
			}
			else if (paragraph.type == Paragraph::Code)
			{
				blockFmt.setNonBreakableLines(true);
				charFmt.setFontFamily("Monospace");
			}

			if (!firstBlock)
			{
				cursor.insertBlock();
			}
			else
			{
				firstBlock = false;
			}
			cursor.setBlockFormat(blockFmt);
			cursor.block().setUserState(paragraph.type);
			insertTokens(paragraph.tokens, charFmt, paragraph.type == Paragraph::Code);
		}
		else
		{
			const List list = paralist.second;
			qDebug() << "##########################" << list.indent << list.ordered;
			std::for_each(list.paragraphs.begin(), list.paragraphs.end(), [](const Paragraph &item){qDebug() << item;});
			cursor.setBlockFormat(QTextBlockFormat());
			cursor.setBlockCharFormat(QTextCharFormat());
			QTextListFormat listFormat;
			listFormat.setStyle(list.ordered ? QTextListFormat::ListDecimal : QTextListFormat::ListDisc);
			listFormat.setIndent(list.indent);
			QTextList *l = cursor.insertList(listFormat);
			qDebug() << "inserting list" << list.indent;
			bool firstBlock = true;
			for (const Paragraph &paragraph : list.paragraphs)
			{
				if (firstBlock)
				{
					firstBlock = false;
				}
				else
				{
					cursor.insertBlock();
					qDebug() << "inserting block";
				}
				insertTokens(paragraph.tokens, QTextCharFormat(), false);
				qDebug() << l->count();
				l->add(cursor.block());
				qDebug() << l->count();
				qDebug() << "inserting characters";
			}
		}
	}
	cursor.endEditBlock();
	qDebug() << doc->toHtml();
}
void KoTextWriter::write(const QTextDocument *document, int from, int to)
{
    d->document = const_cast<QTextDocument*>(document);
    d->styleManager = KoTextDocument(document).styleManager();

    QTextBlock fromblock = document->findBlock(from);
    QTextBlock toblock = document->findBlock(to);

    QTextCursor fromcursor(fromblock);

    QTextTable *currentTable = fromcursor.currentTable();
    QTextList *currentList = fromcursor.currentList();

    // NOTE even better would be if we create a new table/list out of multiple selected
    // tablecells/listitems that contain only the selected cells/items. But following
    // at least enables copying a whole list/table while still being able to copy/paste
    // only parts of the text within a list/table (see also bug 275990).
    if (currentTable || currentList) {
        if (from == 0 && to < 0) {
            // save everything means also save current table and list
            currentTable = 0;
            currentList = 0;
        } else {
            QTextCursor tocursor(toblock);
            //fromcursor.setPosition(from, QTextCursor::KeepAnchor);
            tocursor.setPosition(to, QTextCursor::KeepAnchor);

            if (!fromcursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor)) {
                fromcursor = QTextCursor();
            }
            if (!tocursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor)) {
                tocursor = QTextCursor();
            }

            // save the whole table if all cells are selected
            if (currentTable) {
                QTextTableCell fromcell = currentTable->cellAt(from);
                QTextTableCell tocell = currentTable->cellAt(to);
                if ((fromcursor.isNull() || fromcursor.currentTable() != currentTable) &&
                    (tocursor.isNull() || tocursor.currentTable() != currentTable) &&
                    fromcell.column() == 0 && fromcell.row() == 0 &&
                    tocell.column() == currentTable->columns()-1 && tocell.row() == currentTable->rows()-1
                ) {
                    currentTable = 0;
                }
            }

            // save the whole list if all list-items are selected
            if (currentList) {
                int fromindex = currentList->itemNumber(fromblock);
                int toindex = currentList->itemNumber(toblock);
                if ((fromcursor.isNull() || fromcursor.currentList() != currentList) &&
                    (tocursor.isNull() || tocursor.currentList() != currentList) &&
                    fromindex <= 0 && (toindex < 0 || toindex == currentList->count()-1)
                ) {
                    currentList = 0;
                }
            }
        }
    }

    QHash<QTextList *, QString> listStyles = d->saveListStyles(fromblock, to);
    d->globalFrom = from;
    d->globalTo = to;
    d->writeBlocks(const_cast<QTextDocument *>(document), from, to, listStyles, currentTable, currentList);
}