Как вставить текст MS Word на любой форум с сохранением форматирования ?

Dragokas

Angry & Scary Developer
Команда форума
Супер-Модератор
Разработчик
Клуб переводчиков
Сообщения
8,030
Решения
14
Реакции
6,805
Привет,

вообщем сильно поднадоела мне проблема со вставкой из MS Word текста на различные форумы (в том числе и в редактор от XenForo).

То кучу лишних строк добавляет сам, то пробелы съедает, то цвета и т.п.

В MS Word удобно (мне) готовить статьи и всё такое прочее.

Сделал (на коленке*) "простое", но более-менее универсальное решение: автозамена форматирования на BB-код с помощью макроса MS Word.

* подразумевается, что макрос настроен для моих нужд, если у Вас более наполеоновские аппетиты, попросите меня - я подкорректирую, что нужно.

Вот что он сейчас умеет заменять на BB-код:

- заменяет размеры шрифта MS Word (10, 12, 14, и 16-й). По-умолчанию, сделано так, чтобы не заменял 12-й шрифт (он выбран у меня как основной для всех документов).
- заменяет гиперссылки
- жирность
- курсив
- цвет красный
- цвет синий
- центрирование
- и любые комбинации этих форматов

Как это работает в целом:
1) Открываете Ваш документ с крутым оформлением, запускаете в нем макрос (ALT + F8, выполнить)
2) Копируете результат в любой простой редактор (блокнот Windows подойдет, можно и Akelpad, N++, и т.п.)
3) Копируете из блокнота текст в редактор любого форума. Победа!

Как это сделать у себя:
1) Вам нужно всего один раз выполнить п.1. этой инструкции: Как создать макрос для MS Word / MS Excel
и вставить такой код макроса:

VB.NET / VBA:
Option Explicit

Private Enum TEXT_PROPERTY
    TEXT_BOLD = 1
    TEXT_ITALIC
    TEXT_SIZE_10 = 10
    TEXT_SIZE_12 = 12
    TEXT_SIZE_14 = 14
    TEXT_SIZE_16 = 16
    TEXT_RED
    TEXT_BLUE
    TEXT_CENTER
End Enum

Private Type POSITION_CONTEXT
    BEG As String
    END As String
End Type

Private Type BB_TAG_CODE
    BOLD            As POSITION_CONTEXT
    ITALIC          As POSITION_CONTEXT
    TEXT_SIZE_10    As POSITION_CONTEXT
    TEXT_SIZE_12    As POSITION_CONTEXT
    TEXT_SIZE_14    As POSITION_CONTEXT
    TEXT_SIZE_16    As POSITION_CONTEXT
    COLOR_RED       As POSITION_CONTEXT
    COLOR_BLUE      As POSITION_CONTEXT
    POS_CENTER      As POSITION_CONTEXT
End Type

Private Const DEFAULT_SIZE = TEXT_SIZE_12   'размер текста по-умолчанию

Public TAG As BB_TAG_CODE

' заполнение соответствий форматирования MS Word и BB-кодам

Private Sub Mapping_Init()
    With TAG
        .BOLD.BEG = "[b]"
        .BOLD.END = "[/b]"
        .ITALIC.BEG = "[i]"
        .ITALIC.END = "[/i]"
        .TEXT_SIZE_10.BEG = "[size=3]"
        .TEXT_SIZE_10.END = "[/size]"
        .TEXT_SIZE_12.BEG = "[size=4]"
        .TEXT_SIZE_12.END = "[/size]"
        .TEXT_SIZE_14.BEG = "[size=5]"
        .TEXT_SIZE_14.END = "[/size]"
        .TEXT_SIZE_16.BEG = "[size=6]"
        .TEXT_SIZE_16.END = "[/size]"
        .COLOR_RED.BEG = "[color=red]"
        .COLOR_RED.END = "[/color]"
        .COLOR_BLUE.BEG = "[color=blue]"
        .COLOR_BLUE.END = "[/color]"
        .POS_CENTER.BEG = "[center]"
        .POS_CENTER.END = "[/center]"
    End With
End Sub


Public Sub A_Replace_Into_BBcode()
    Dim Style1
    Dim Style2
    Dim Style3
    Dim Style4
    Dim Style5
   
    Dim hh As Hyperlink, i&
   
    With ActiveDocument.Hyperlinks
        For i = .Count To 1 Step -1
            Set hh = .Item(i)
            hh.TextToDisplay = "[url=" & hh.Address & "]" & IIf(hh.TextToDisplay = "", "X", hh.TextToDisplay) & "[/url]"
            hh.Delete
        Next
    End With
   
    Call Mapping_Init
   
    For Each Style1 In Array(TEXT_BOLD, 0)
   
        For Each Style2 In Array(TEXT_ITALIC, 0)
       
            For Each Style3 In Array(TEXT_SIZE_10, TEXT_SIZE_12, TEXT_SIZE_14, TEXT_SIZE_16)
           
                For Each Style4 In Array(TEXT_RED, TEXT_BLUE, 0)
               
                    For Each Style5 In Array(TEXT_CENTER, 0)
               
                        StyleToBB Style1, Style2, Style3, Style4, Style5
                       
                    Next
                Next
            Next
        Next
    Next
End Sub

Private Sub StyleToBB(ParamArray Styles())
   
    'ActiveDocument.Range.Select
    'Selection.WholeStory
   
    Dim Style, BB_Beg$, BB_End$, BB_Beg_Concat$, BB_End_Concat$
   
    With Selection.Find
   
        .ClearFormatting
   
        For Each Style In Styles
       
            BB_Beg = ""
            BB_End = ""
       
            Select Case CLng(Style)
           
                Case TEXT_BOLD
                    .Font.BOLD = True
                    .Replacement.Font.BOLD = False
                    BB_Beg = TAG.BOLD.BEG
                    BB_End = TAG.BOLD.END
       
                Case TEXT_ITALIC
                    .Font.ITALIC = True
                    .Replacement.Font.ITALIC = False
                    BB_Beg = TAG.ITALIC.BEG
                    BB_End = TAG.ITALIC.END
               
                Case TEXT_SIZE_10
                    .Font.Size = 10
                    .Replacement.Font.Size = DEFAULT_SIZE
                    BB_Beg = TAG.TEXT_SIZE_10.BEG
                    BB_End = TAG.TEXT_SIZE_10.END
               
                Case TEXT_SIZE_12
                    .Font.Size = 12
                    .Replacement.Font.Size = DEFAULT_SIZE
                    BB_Beg = TAG.TEXT_SIZE_12.BEG
                    BB_End = TAG.TEXT_SIZE_12.END
               
                Case TEXT_SIZE_14
                    .Font.Size = 14
                    .Replacement.Font.Size = DEFAULT_SIZE
                    BB_Beg = TAG.TEXT_SIZE_14.BEG
                    BB_End = TAG.TEXT_SIZE_14.END
                   
                Case TEXT_SIZE_16
                    .Font.Size = 16
                    .Replacement.Font.Size = DEFAULT_SIZE
                    BB_Beg = TAG.TEXT_SIZE_16.BEG
                    BB_End = TAG.TEXT_SIZE_16.END
                   
                Case TEXT_RED
                    .Font.Color = wdColorRed
                    .Replacement.Font.Color = wdColorAutomatic
                    BB_Beg = TAG.COLOR_RED.BEG
                    BB_End = TAG.COLOR_RED.END
                   
                Case TEXT_BLUE
                    .Font.Color = wdColorBlue
                    .Replacement.Font.Color = wdColorAutomatic
                    BB_Beg = TAG.COLOR_BLUE.BEG
                    BB_End = TAG.COLOR_BLUE.END
               
                Case TEXT_CENTER
                    .ParagraphFormat.Alignment = wdAlignParagraphCenter
                    .Replacement.ParagraphFormat.Alignment = wdAlignParagraphLeft
                    BB_Beg = TAG.POS_CENTER.BEG
                    BB_End = TAG.POS_CENTER.END
               
            End Select
           
            If Style <> DEFAULT_SIZE Then
           
                BB_Beg_Concat = BB_Beg & BB_Beg_Concat$
                BB_End_Concat = BB_End_Concat & BB_End
               
            End If
           
        Next
       
        .Replacement.Text = BB_Beg_Concat & "^&" & BB_End_Concat
       
        .Execute FindText:="", Replace:=wdReplaceAll, Wrap:=wdFindContinue
       
    End With
   
End Sub

Всё, макрос будет доступен из-под любого документа.

Примечание: если Вам нужна поддержка других размеров шрифтов, и т.п., не описанного выше, макрос нужно дорабатывать.

Выкладываю также демо (документ с разным суперформатированием и встроенный в него макрос, который вы сразу сможете проверить в работе, не забыв разрешить работу макросов для Вашей версии офиса).

Ах да, название моего макроса в списке будет "A_Replace_Into_BBcode".

Best wishes, Alex.
 

Вложения

Последнее редактирование:
Обнаружился баг с заменой гиперссылок. Старый вариант макроса обновлен.

Внимание! Всегда будьте осторожны при работе со включенными макросами! Не устанавливайте низкий уровень безопасности при включении макросов.
Это может привести к заражению Вашего ПК при открытии документов, загруженных из сети из ненадежных источников.
Выбирайте средний уровень, чтобы всегда контролировать разрешать или нет запуск макросов, либо вообще их отключите, когда Вы больше в них не нуждаетесь.
 
Уважаемый Dragokas!

Макрос - просто замечательный!

И его надо еще совершенствовать не сам по себе, а уже для других штучек.

Могу похвастать, что сам делал примерно такие вещи для вставки на сайт кода HTML-разметки, но по более сложной схеме.

Как у Вас и сказано, набирал свой текст визуально с применением своих стилей (как видите, не только Вы любите набирать в удобном Word'е).

Потом макросом просто осуществлял поиск след. абзаца и вначале и в конце его ставил <p> и </p> одним проходом пока не кончатся абзацы. Потом искал и помечал заголовки.

Другим проходом с поиском форматирования ставил теги <b>, <i>, <u> и так далее.

Получалось удобно.

<td>Так и для таблиц: сначала набирал из абзацев структуру строк или столбцов, а потом одним макросом делал прогон, чтобы обрамить их тегами.</td>

<tr>

<td></td>

<td></td>

<td></td>

</tr>

С Вашим макросом я пока проверил Ваш тестовый док и то, что Вы сейчас читаете: я это тоже набрал в Word'е и применил макрос. Блокнот не использовал - прямо из Word'а.



Поэтому первыми простыми пожеланиями Вашей творческой натуре будут такие:

  1. Добавить вставку таблицы
  2. Обработку "кавычек"
А из более сложных усовершенствований я бы попросил (особенно для себя любимого) такое новаторство. Связано оно со скрытым текстом.

Поясню. Я теги вставлял не просто так, а скрытым текстом, поэтому их видно было только после включения макроса ShowAll. Это позволяет продолжать стилевое форматирование и дальше.

Примечание: кроме того, что тексту тегов назначался стиль скрытый, я его еще и красил в цвет морской волны, чтобы легко отличать от основного текста.

Вообще, это очень интересно: включать и выключать отображение скрытого текста, когда в основном тексте есть такие комментарии или другие знаки не для всех. Между прочим, Ваш макрос обрабатывает и зачеркнутый и скрытый текст, делая его обычным.

Потому вторым плюсом при отображении BB-кодов скрытым текстом будет то, что их можно будет включать-выключать.



Еще для полного счастья я (хотя бы для себя одного) слегка бы анимировал процесс вставки BB-кодов и готов сам обогатить Ваш макрос всплывающими и гаснущими сообщениями, которые как бы поясняют происходящее поступУпенное изменение текста.

Кстати, особое удовольствие доставляет процесс отмены изменений, которые сделал Ваш макрос, потому что замена происходит почти мгновенно, а отмена - ступенями, и становится хорошо видно, как все заменялось задним ходом.
 

Уважаемый Dragokas!

Если бы в макросе было побольше комментариев: какая процедура, что делает, я бы и сам разобрался, а так мне тяжеловато.

Во-первых, очень прошу, покажите, где в макросе сделать изменения, чтобы BB-коды вставлялись вот таким форматом:
Код:
    With Selection.Font
        .Hidden = True
        .Color = wdColorSkyBlue
    End With
Во-вторых, где сделать изменения, чтобы сам стиль слова, то есть, жирность или курсив, не изменялись, а только коды вокруг него ставились?
С учетом моих пожеланий, если BB-коды сделать скрытым текстом, то:
Не надо, чтобы при вставке BB-кодов шрифт становился обычным в самом Word'е: пусть он остается как был - жирным, или курсивом, или подчеркнутым, или цветным.
Иными словами, пусть в Word'е шрифт даже после добавления BB-кодов остается со своим стилем: размером, жирностью и цветом) - а теги пусть будут скрытые+окрашенные. Если выключить скрытый текст, то документ будет выглядеть, как был вначале; а если включить отображение скрытых знаков - текст будет с кодами или тегами.

Еще бы сделать, чтобы макрос работал не со всем текстом, а с выделением или в разделе.

По-моему, кодов с установкой размера шрифта должно быть только два: открытие и закрытие. Это перебор, чтобы еще и размеров на сайте было полно: одного хватит - нечего глаза мылить.

Формат знаков: и жирный, и курсив, и подчеркнутый - и без BB-кодов проходят через форму. Только размер не проходит.
Еще я заметил, что при вставке этих кодов каждый раз повторно вставляются коды размера, который и так уже был проставлен вначале.

Следующее про Блокнот.
При вставке из Word'а в форму на сайте добавляются лишние абзацы, а вылетает из формы текст, в котором знаки абзаца заменены переводом строки.
Следовательно, у Блокнота одна функция - не дать вставить повторные абзацы. Раз такое дело, то в тексте для сайта, казалось бы, и надо вместо абзацев ставить переводы строки. Но Ваш макрос работает не по ним, а по абзацам.

Поэтому:
В Вашем макросе лучше сделать конечный штрих перед копированием в форму: заменить знаки абзаца, знаками перевода строки.
То есть, после вставки всех BB-кодов произвести замену ^p на ^l. И Блокнот не нужен.
Причем, я считаю, что для этого надо выделить отдельный макрос с запросом.
Еще раз повторяю: макрос - великолепный!
Все это я делал раньше отдельными макросами, но с большими затратами на замену по запросу конкретных тегов.
Теперь, надеюсь, будет веселее!

Для примера того, как смотрится текст с BB-кодами скрытым текстом, посылаю этот же текст в приложении.
 

Вложения

Последнее редактирование:
Здравствуйте, auto-teacher !
Спасибо за отзывы и предложения.

По моему скромному мнению, макрос написан физически максимально красиво, так что разобраться в нём не составит труда и без комментариев.
А вот если рассматривать логически, то написан ужасно, т.к. там происходит замена перебором наложений (точнее, подбор последовательности) стилей методом комбинаторики, т.е. если добавить поиск нового стиля, это приведёт к уменьшению скорости работы программы в геометрической прогрессии. Но по-другому, я пока не знаю как.
Если будет новая версия макроса, то постараюсь сделать больше комментариев.

Чтобы добавить замену совершенно нового типа стиля, нужно его описать в программе.
Определиться, в комбинации с какими стилями этот стиль может присутствовать в документе.
Определиться, как будут выглядеть BB-коды для него после замены.

От этого зависит, нужно ли создавать ещё одну ветвь комбинаторики For Each, или достаточно просто вызвать один раз подпрограмму StyleToBB.
Затем описать стиль по примеру константы TEXT_BOLD, пусть это будет TEXT_HIDDEN, просто добавить его в перечисление TEXT_PROPERTY.
Затем описать BB-код замены в Mapping_Init(). И добавить еще один Case в StyleToBB(), указав нужное свойство для замены.

--------------
Я понял, что Вы предложили. Считаю это неплохой вариант, перенести BB-коды в скрытый текст. Хотя, честно говоря, никогда ещё не имел с ним дело. Но с Вашим примером и этой статьей разобрался.
Получается, в таком случае, перед новой заменой придётся сперва удалить весь скрытый текст из документа прежде, чем выполнять замену, иначе BB-коды продублируются.

кодов с установкой размера шрифта должно быть только два: открытие и закрытие.
Себе можете оставить два. Но если посмотреть различные статьи, то там часто используется гораздо больше, чем два, так что здесь я точно ничего менять не планирую, разве только наоборот в большую сторону. 10, 12, 14, 16 - это наиболее часто используемые.
Еще я заметил, что при вставке этих кодов каждый раз повторно вставляются коды размера, который и так уже был проставлен вначале.
Для отладки нужны примеры, образцы.

Формат знаков: и жирный, и курсив, и подчеркнутый - и без BB-кодов проходят через форму. Только размер не проходит.
В инструкции к макросу я обязательным пунктом пометил, что скопированный текст нужно сперва вставить в блокнот, а не сразу на форум.
В таком режиме никакое форматирование не будет воспроизводится в целевой форме форума. Даже если бы я копировал напрямую, то у меня не может быть никаких гарантий, что этот способ будет работать одинаково хорошо со всеми форумами и всеми браузерами. А ведь именно по причине необходимости в полной независимости от проблем ПО/Web мною был создан этот макрос.

При вставке из Word'а в форму на сайте добавляются лишние абзацы, а вылетает из формы текст, в котором знаки абзаца заменены переводом строки. Следовательно, у Блокнота одна функция - не дать вставить повторные абзацы.
Не только. Баги могут быть (и были) самые различные. Почитайте хотя бы 1-й пост. Это я не от балды придумал, а такая проблема действительно была с XenForo. См. тему на оф. сайте: Fixed - Text editor eats up space character
И это только XenForo. Неизвестно, какие и как много других багов будет с другими форумами. Чтобы не делать лишних движений с блокнотом, решить это можно иначе, через манипуляции с буфером.
Правда, Ctrl + C нельзя будет нажимать, а сразу вставлять уже подготовленный в буфере текст в форму форума. Я постараюсь сделать на днях.

Раз такое дело, то в тексте для сайта, казалось бы, и надо вместо абзацев ставить переводы строки. Но Ваш макрос работает не по ним, а по абзацам.
Да, для этого нужен отдельный код макроса. Т.к. это уже замена редактирования, а не форматирования.
Думаю, это хорошая идея, заменять абзац на перевод строки (или даже два?)

С уважением,
Станислав.
 
Последнее редактирование:
Назад
Сверху Снизу