I need to copy text from one PowerPoint presentation to another. However, I have problems copying special symbols, such as smileys, which appear in the target presentation as empty boxes. Looking at the Open XML file in the original presentation, I can see that the Run containing the smiley has a "SymbolFont" attribute:
<a:sym typeface="Wingdings" />
However, in VBA, Shape.TextFrame2.TextRange2.Font =the Font of that Run - shows Arial.
How can I determine the SymbolFont of a text Run using VBA or C# (not XML)?
Then I could specify that SymbolFont in the target presentation.
Perhaps there other ways for copying the text that do not involve XML?
Note that this problem happens not only with Smileys; other special characters may show different SymbolFonts, such as:
<a:symTypeface = "Symbol", PitchFamily = 18, CharacterSet = 2>
Code example:
getRuns(TextRange2 paragraph)
{
foreach(TextRange2 run in paragraph.get_Runs(-1,-1))
_myRuns.Add(new MyRun {_text=run.Text, _font=run.Font} );
}
copyRunsToParagraph(TextRange2 paragraph)
{
foreach(MyRun run in _myRuns)
paragraph=paragraph.InsertAfter(run._text);
}
Note: Run.Font seems to return only the Latin font, not the Symbol font, e.g., Arial but not Wingdings. As I wrote, different symbols may have different SymbolFonts, so always using Wingdings does not work.
This can't be done in VBA.
Related
There are some problems when working with Excel using VBA.
If there is a cell containing several words, each of which has its own font, color, etc, if I'm stuffing some transformations above the line inside the cell, in this case I do the repl, the styles are lost for individual words; the entire string in the cell takes one style.
The question is: How do I make a replacement for certain words, so that the rest of the words do not change styles?
There is the option to go over the entire line and remember the styles of each character in the collection, and then after making the replacements, and other actions with the string, assign all the styles again, character-by-symbol, but this is long and costly, since there is a lot of text and lots of files.
I am not able to paste the entirety of my code, but the crux is that I have a textbox in PPT 2013, myTb, that I have (programmatically) pasted some text into. I now want to perform the following two actions:
See if the original text was the PPT 'body default' font (e.g. 'Calibri (body)' vs. 'Calibri' in the MS Ribbon)
If it was the body default, set the new text to also be the body default.
I can't seem to figure either part out, even though I have experimented with reading/writing from/to most of the Shape.TextFrame[n].TextRange.Font.Name... fields. I also had two confounding points to ask about, regarding the Shape.TextFrame.TextRange.Font.NameComplexScript field:
This field does not seem to be a 'complete' indicator of body-default vs non-body-default font. The reason is that if this textbox is originally the body-default ('Calibri (body)'), it will read '+mn-cs', but then I can change the font to the non-default variant ('Calibri'), and it still reads '+mn-cs'.
I then proceed to change the textbox to an entirely different font, which changes this field to the font's name as expected. However, if I then change back to the body-default font (or any other font, for that matter), this field remains on the previous font's name.
To set the font to the body or heading font, you need to use a weird bit of syntax:
{object}.Font.Name = "+" + FontType + "-" + FontLang
Where:
FontType is "mj" or "mn" for Major (headings) or Minor (body) respectively.
FontLang is "lt", "cs" or "ea" for Latin, Complex Scripts or East Asian
For example to set the font to the theme's body text font for Latin text:
ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange.Font.Name = "+mn-lt"
A bit late to the party, but I found this in case anyone needs it.
Edit: This is C# code, using the Interop PowerPoint namespace.
string headingsThemeFont = Globals.ThisAddIn.Application.ActivePresentation.SlideMaster.Theme.ThemeFontScheme.MajorFont.Item(MsoFontLanguageIndex.msoThemeLatin).Name;
string bodyThemeFont = Globals.ThisAddIn.Application.ActivePresentation.SlideMaster.Theme.ThemeFontScheme.MinorFont.Item(MsoFontLanguageIndex.msoThemeLatin).Name;
VBA Noob here. I take my python programming notes in a word document since I can import images into it and align/format text quickly. Any code pasted into this document comes up as a spelling error. I'm trying to find a way to ignore spelling errors within a selected text area so I don't have to deal with ignoring each spelling error line of code individually. I don't want to turn off spell check in the document.
Ideally, I'd able to write a macro that read:
Selection.ShowSpellingErrors = True
but ShowSpellingErrors() can only be used with ActiveDocument. I was able to a record a macro that ignored spelling errors with:
Selection.LanguageID = wdEnglishUS
Selection.NoProofing = True
However, any new text I type into this also doesn't get proofed, which is something I don't want. I want to be able to write new text and see any errors I make. Thanks for any help!
Not a VBA Macro, but I think this answer may be relevant to your problem anyway.
Try creating a style for code which does not include spell check. Anything with this style does not get spell checked, while the rest of the document does. Sometimes I find the code shows the red underline, but if you run spell check it should just disappear without needing to be 'fixed'.
Create a new style, in the modify formatting dialog, go to Format > Language:
Tick the 'Do not check spelling or grammar' checkbox:
Highlight your code and use the new style. Any text not in this style will still be spellchecked:
Is there any way when programming MS Word to list the points in the text where a change in character style occurs?
I'm programmatically trying to analyze a paragraph to retrieve all the contiguous blocks of text that have the same style - in other words, split the paragraph at the points where the text style changes. At the moment the way I'm doing it is to take each character and compare its style with the previous character - if the name of the style is different, I know I've found a point to split the results at. That works but is horrendously inefficient (for every character, you have to do a full string comparison of the style name). I'm wondering if there's a way in the Word object model to solve this problem without comparing every character?
The approximate code I'm currently using is as follows (It's C# code: I'm using COM Interop against Word 2003, but I'd be equally happy with a solution in VBA since once I know in principle how to do it, converting to C# should be easy. )
// used to store the results as we go
StringBuilder currentText = new StringBuilder();
string currentStyle = null;
// range contains the Range I want to split up
foreach (Range charRng in range.Characters)
{
string style = charRng.get_Style().NameLocal;
if (style == currentStyle)
{
currentText.Append(charRng.Text);
}
else
{
AddTextBlockToMyResults(currentStyle, currentText.ToString());
currentText = new StringBuilder(charRng.Text);
currentStyle = style;
}
}
AddTextBlockToMyResults(currentStyle, currentText.ToString());
What version(s) of Office were used to create the Word docs?
If it's Office 2007 or later (or, you can convert the docs to that format) then an office document is really just a .zip archive. If you open a .docx file with an archive utility like WinRAR, you'll see that it has a directory structure like:
_rels
customXml
docProps
word
|_ document.xml
That document.xml is an Open Office XML file that contains all the text and reference to styles in your Word doc. I bet you could parse that XML a heck of a lot faster than doing what you're doing now.
I have a large book written in Microsoft Word and want to create a macro that will find all text using a predefined style and convert that text to an inline image. This text will be in Arabic and generally no longer than 4-5 lines. Is this possible?
UPDATE: Here's an example to show what I'm referring to:
I want to replace that entire line in Arabic with an image (as if I cropped this attached image to only include the Arabic and then replaced the line in Arabic with the image).
The reason I want a macro or script to do this is because there are hundreds of such lines and updating them one by one is cumbersome plus that will make modifications difficult later on.
UPDATE2: I found an interesting option here: http://windowssecrets.com/forums/showthread.php/31344-Convert-Text-to-an-Image-of-Text-in-VBA-(Office-2000-Sr1a)
It looks like you can cut a piece of text and then "Paste Special" as an image. So if there's a way to automate that that might work.
This is not an answer although I hope it will grow into a community answer. At the moment it is an exploration of what is required to solve the problem.
I know from the discussion when this question was posted on Super User that Abdullah wishes to publish his book on Kindle. So the question is really about how to get a document in English and Arabic ready for publication as an e-Book.
The Kindle does not support Arabic. The number of languages it does support is slowly increasing but there is no evidence I can find that Amazon has plans to add Arabic in the foreseeable future.
The format behind an Amazon e-Book is a cut down version of HTML. If a Word document containing Arabic letters is exported to HTML, the Arabic letters are included as character entities; for example: “ﭐ &#amp;64337; ﭒ ﭓ”. Importing the original Word or the HTML version to Kindle, results in the leading bits being discarded so these characters are displayed as P, Q, R and S instead of “ﭐ ﭑ ﭒ ﭓ (Alef Wasla isolated form, Alef Wasla final form, Beeh Wasla isolated form and Beeh Wasla final form).
I have tried Abdullah’s idea of saving some Arabic letters in a PNG file and creating an HTML file containing <p> … </p> <img src= “Arabic.png” > <p> … </p>. The appearance of this file on my Kindle 2 is perfectly acceptable so this has the potential to be a solution. The question is: how can the necessary conversions be performed?
We need to extract each Arabic string from either the Word document or its HTML equivalent and import it into a program that can convert them to PNG files.
The only way that I know of automating this would be to copy each string to a slide within PowerPoint. With PowerPoint’s SaveAs option it is possible to save each slide as a separate PNG file. The slides are named: SLIDE1.PNG, SLIDE2.PNG, SLIDE3.PNG and so on in sequence which would allow a macro to relate the results to the original strings. It would then be possible to replace the Arabic strings in the HTML file with the image elements. None of this would be too difficult to automate but there is a problem with the slides all being the size of the PowerPoint page. The page could be made smallish but what we need is for each slide to be cropped to just bigger than that slide’s text. I cannot think of any way of automating this cropping.
Does anyone have a better approach than converting each Arabic phrase to a PNG file?
I have been looking for PNG editors with some sort of command line interface but can find nothing that would be easier than using PowerPoint. Does anyone know of an alternative to PowerPoint?
Does anyone have any suggestions for automating the cropping of each image? When a string is placed in a PowerPoint slide it is possible to set its width to, say, 6.5cm (which looks good on my Kindle) and get the height determined by PowerPoint. This could be saved for later use if anyone knows how to use it.
Implementing solution
Pending any suggestions for improving the approach described above, the following outlines how I would implement it.
I would not attempt to process the Word document. I would save it as a Web Page, Filtered HTML file, which is a required step on the way to creating a Kindle eBook, and process that.
Within the HTML file created from my test document, the Arabic phrase comes out as:
<p class="MsoNormal"></p>
<p class="MsoNormal" align="center" style="text-align:center"><span dir="RTL"
style="font-size:24.0pt;font-family:Arial">
ﭐﭑﭒﭓﭔﭕ
ﭖﭗﺁﺂﻼﻻ
ﻺﻹﻞﻊﻋﻌ
</span><span style="font-size:24.0pt"></span></p>
<p class="MsoNormal"></p>
<p class="MsoNormal"></p>
I assume Abdullah's document will result in something similar. Note 1: the above is a random collection of Arabic letters. Note 2: they are held left-to-right in reading sequence even though, when displayed or printed, they are read right-to-left.
The whole of this block will have to be replaced with something like:
<br><imc src="xxxx.png"><br>
where the file xxxx.png holds an image of the Arabic text.
The file names, such as xxxx.png, could be systematic (A001.png, A002.png, ...) but I would have thought that transliterating the first ten or twenty characters of the phrase from the Arabic to English alphabets and using the result, with a numeric suffix, as the file name would be more convenient.
I would hold the records necessary to manage the process in an Excel worksheet. I would place the VBA code in the same workbook.
The steps in the conversion process that I envisage are:
VBA macro to extract Arabic strings from latest HTML file and add new strings to the Excel worksheet. (More about the Excel worksheet later.)
VBA macro to create PowerPoint file, with one slide per new string, and use SaveAs in PNG format to create one PNG file per slide before discarding the PowerPoint file.
Human to crop each PNG file. (There appears to be no way of automating the cropping so this task will be minimised by use of data in the Excel worksheet.)
VBA macro to rename each slide from SLIDEnnn.PNG to its permanent name and to record the permanent name in the Excel worksheet.
VBA macro to update the latest HTML file by replacing the block containing the Arabic phrase with the appropriate HTML IMG element.
The Excel worksheet needs two columns: Arabic phrase and PNG file name. If there is any risk of the worksheet being sorted between steps 2 and 4, we may need a sequence number as well.
Macro 1 will extract an Arabic phrase from the HTML file, look down the list in the worksheet for this phrase and add the phrase at the bottom if it is not already present.
Macro 2 will look for phrases in the worksheet that do not have a PNG file name. These new phrases are the ones to be written to the PowerPoint presentation. That is, a phrase only goes into this process once.
Task 3, cropping each PNG file, will be a pain. All I can say is that it will only be once per phrase.
Macro 4 will assume that the SLIDE001.PNG, SLIDE002.PNG, … are in the sequence of phrases without PNG files in the worksheet. If this might not be true (because the worksheet has been sorted) we will either need a sequence number or to retain the PowerPoint file. The macro will assign a unique name to each new phrase, record this name in the worksheet and rename the PNG file.
Macro 5 creates a new copy of the latest HTML file using the contents of the worksheet to determine which phrase to replace with which PNG file.
This process is not ideal but it will achieve the desired result and has no obvious complications. Any suggestions for improving it?
Before you begin these instructions, press record in the Microsoft Word macro editor, so you can see what the VBA code is.
I'm wondering if this will be easier if you convert the docx file to .rtf (rich text format) and replace that line with an image? Go to File > Save As.. > name it "old.rtf", then replace the line with an image and Save As.. again and name it "new.rtf" and then download Beyond Compare or your favorite diff program to see what happened. It should be easy to do this pro-grammatically if you choose to. I think working in text would be easier than Microsoft's binary format unless you can find a good library to modify their doc or docx formats.
Sub CopySelPasteAsPicture()
' Take a picture of a selection and paste it at the
' document end
With Selection
.CopyAsPicture
End With
ActiveDocument.Content.Select
With Selection
.Collapse Direction:=wdCollapseEnd
.TypeParagraph
.TypeParagraph
.PasteSpecial DataType:=wdPasteMetafilePicture
End With
End Sub