scanny / python-pptx

Create Open XML PowerPoint documents in Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Set/change font color when working with Hyperlinks is impossible

Mike3285 opened this issue · comments

Looks like it's not possible to set the color of the font if an hyperlink is present in the same run.

Here is my relevant code:

text_frame = shape.text_frame
p = text_frame.paragraphs[0]
# adding hyperlink
r = p.runs[0]
hlink = r.hyperlink
my_url = data["d_url"]
hlink.address = my_url

r.font.bold = False
r.font.italic = False
r.font.underline = False

r.font.color.rgb = RGBColor(0x00, 0x00, 0x00) # Black

This will still use the "hyperlink theme color" for the link, ignoring my setting.

Please suggest me how to change the hyperlink color or correct me if I am wrong

Do you actually want one hyperlink to look different from the rest? Other than "visited" versus "not" ? That would generally be considered poor for usability.

I just want all the text in the presentation to have the same formatting, both visited and not visited, for hyperlinks and normal text

So the question becomes how to set the hyperlink colours - for visited and unvisited - across the board.

Glad I clarified - but I, personally, don't know how to do this.

Seeing if you can do it from the PowerPoint UI is a good start. If you can't that's a pretty strong indicator it's not supported and if you can it's an absolute indicator the format supports it.

The you can make a short PPTX that doesn't have a custom color, edit it with PowerPoint to color it, save it as a different name, then inspect the XML to see what's different. That's a reliable method to narrow down the XML portion anyway.

@scanny do you know where the theme stuff is stored - and how to edit it (in python-pptx)? Actually, where it's stored would narrow down the XML search space.

(To be honest - as I don't actually need this function in md2pptx - I doubt I'll have the time to prototype anything.)

IIRC there is a theme part, so it would be in the package, probably something like ppt/theme.xml. You could unzip -l a PPTX file to see if you see something like that in there. I don't believe we have a proxy part in the code for that though.

It's been a while, but I vaguely remember that being a pretty simple part, like not that many different element types and not very long.

@Mike3285 If that's where this setting (visited/not-visited link color) is stored then you could accomplish this by using a customized "template" presentation that you gave the color setting you want by hand using the PowerPoint UI. So like: prs = Presentation("my-customized-template.pptx") instead of prs = Presentation() in your code.

This link from Microsoft suggests it can be done in the UI - so must be doable in the file.

But, and this is more hopeful, you can override a hyperlink's colour explicitly. Here is the XML for a run in slide1.xml (in this case):

            <a:r>
              <a:rPr lang="en-US" dirty="0">
                <a:solidFill>
                  <a:schemeClr val="accent5">
                    <a:lumMod val="40000" />
                    <a:lumOff val="60000" />
                  </a:schemeClr>
                </a:solidFill>
                <a:hlinkClick r:id="rId2">
                  <a:extLst>
                    <a:ext uri="{A12FA001-AC4F-418D-AE19-62706E023703}">
                      <ahyp:hlinkClr xmlns:ahyp="http://schemas.microsoft.com/office/drawing/2018/hyperlinkcolor" val="tx" />
                    </a:ext>
                  </a:extLst>
                </a:hlinkClick>
              </a:rPr>
              <a:t>hyperlink</a:t>
            </a:r>

Certainly confectable, using python-pptx as a base. One could do this for all hyperlinks, I think.

Personally, though, I have no need for this. But it might inspire somebody else to write some Python.

By contrast, here's another hyperlink - that I didn't override the colour for:

            <a:r>
              <a:rPr lang="en-US" dirty="0">
                <a:hlinkClick r:id="rId3" />
              </a:rPr>
              <a:t>hyperlink</a:t>
            </a:r>

I looked at the theme. And this XML in ppt/theme/theme1.xml looks significant:

      <a:hlink>
        <a:srgbClr val="467886" />
      </a:hlink>
      <a:folHlink>
        <a:srgbClr val="96607D" />
      </a:folHlink>

The first looks like an unfollowed link and the seconf the followed link (both as RGB colours).

But if, as @scanny said, there's no way within python-pptx to modify this file the theme-wide approach won't work. A pity as it looks simpler.

IIRC there is a theme part, so it would be in the package, probably something like ppt/theme.xml. You could unzip -l a PPTX file to see if you see something like that in there. I don't believe we have a proxy part in the code for that though.

It's been a while, but I vaguely remember that being a pretty simple part, like not that many different element types and not very long.

@Mike3285 If that's where this setting (visited/not-visited link color) is stored then you could accomplish this by using a customized "template" presentation that you gave the color setting you want by hand using the PowerPoint UI. So like: prs = Presentation("my-customized-template.pptx") instead of prs = Presentation() in your code.

Thanks for your reply. At this point, I was referencing the Stackoverflow answer at the following link: Stackoverflow Answer where a kind user directed us to a guide explaining how to adjust the color template in PowerPoint directly.

Setting a theme and using it as a "template" for my presentations is working well, and I have successfully configured the hyperlinks in the desired color.
However, this approach is not particularly reliable or elegant, and I am eager to see this functionality incorporated into python-pptx. If we can't override the theme colors for hyperlinks, allowing us to set or modify the PPTX "theme" from within Python may be sufficient.