Pptxgenjs: [Feature request] Multiple text objects in one line without bullets or with align

Created on 29 Jun 2018  路  16Comments  路  Source: gitbrent/PptxGenJS

The current system will not allow for multiple text objects without break if there is no bullet or some kind of align specified. This turns into a Problem if you consider, that text formatting (italic, bold, underlinde, strike, ...) are global to one text object. This means, that even code like this

<html>
  <head>
    <script lang="javascript" src="PptxGenJS/libs/jquery.min.js"></script>
    <script lang="javascript" src="PptxGenJS/libs/jszip.min.js"></script>
    <script lang="javascript" src="PptxGenJS/dist/pptxgen.js"></script>
  </head>
  <body>
    <script>
        pptx = new PptxGenJS();
        var slide = pptx.addNewSlide();

        slide.addText([
            { text: 'abc', options: {}},
            { text: 'def', options: {italic:true}}
        ], {x:'0', y:'0', w:'100%', h:'100%', align:'center', valign:'middle'});

//          Save PPTX
        pptx.save('Titel');
    </script>
  </body>
</html>

is not able to achieve this: abc_def_, but will output two seperate lines for abc and _def_.
This could be easily mended by adding an additional attribute to the text objects, let鈥檚 say, break, and change line 3668 from

else if ( idx > 0 && (typeof textObj.options.bullet !== 'undefined' || typeof textObj.options.align !== 'undefined') ) {
                strSlideXml += '</a:p><a:p>' + paragraphPropXml;
            }

to

else if ( idx > 0 && (typeof textObj.options.break === 'undefined' || textObj.options.break) && (typeof textObj.options.bullet !== 'undefined' || typeof textObj.options.align !== 'undefined') ) {
                strSlideXml += '</a:p><a:p>' + paragraphPropXml;
            }

and using the code

<html>
  <head>
    <script lang="javascript" src="PptxGenJS/libs/jquery.min.js"></script>
    <script lang="javascript" src="PptxGenJS/libs/jszip.min.js"></script>
    <script lang="javascript" src="PptxGenJS/dist/pptxgen.js"></script>
  </head>
  <body>
    <script>
        pptx = new PptxGenJS();
        var slide = pptx.addNewSlide();

        slide.addText([
            { text: 'abc', options: {}},
            { text: 'def', options: {italic:true, break:false}}
        ], {x:'0', y:'0', w:'100%', h:'100%', align:'center', valign:'middle'});

//          Save PPTX
        pptx.save('Titel');
    </script>
  </body>
</html>

which will achieve the desired effect.
See this patch:
pptxgen.js.patch.txt

enhancement-text text

Most helpful comment

When using the code

slide.addText(
    [
        { text:'1st word ', options:{ color:'99ABCC', italic:true } },
        { text:'2nd word ', options:{ color:'FFFF00', bold:true } },
        { text:'3rd word ', options:{ color:'0088CC' } }
    ],
    { x:1.5, y:1.5, w:6, h:2, margin:0.1, fill:'232323', align:'center' }
    );

I get

Note that the three text objects are not in the same line, so if I want to have it like this

there's no way to do it.

All 16 comments

abc_def_ is supposed to be abc and def in italic, but GitHub鈥檚 italic specified doesn鈥檛 seem to like prepending non-whitespace chars.

+1 ... I've just come across this limitation.
There is already a breakline option. Maybe if that is explicitly set to false then the linebreak could be squashed.

@bigianb If you really need this feature now, you can try using my patch above, it鈥檚 literally inserting the check

(typeof textObj.options.break === 'undefined' || textObj.options.break)

into

else if ( idx > 0 && (typeof textObj.options.bullet !== 'undefined' || typeof textObj.options.align !== 'undefined') ) {...}

From my experience it works, but I didn鈥檛 try anything too special. Hm, maybe one should change this to

NO ONE SHOULDN鈥橳, I JUST DID NOT THINK WHEN WRITING THIS BIT!

(typeof textObj.options.break !== 'undefined' && textObj.options.break)

thus using this option only if it鈥檚 explicitely set to false ...

I don't see where the library lacks the ability to format on a word-level basis.

This adds italics and bold without forcing a line-break or requiring bullets:

slide.addText(
  [
    { text:'1st word ', options:{ color:'99ABCC', italic:true } },
    { text:'2nd word ', options:{ color:'FFFF00', bold:true } },
    { text:'3rd word ', options:{ color:'0088CC' } }
  ],
  { x:1.5, y:1.5, w:6, h:2, margin:0.1, fill:'232323' }
);

screen shot 2018-08-08 at 23 28 58

@gitbrent Your code does not use any kind of align, add align:'center' to the options and you end up with

grafik

Using the code

slide.addText(
    [
        { text:'1st word ', options:{ color:'99ABCC', italic:true } },
        { text:'2nd word ', options:{ color:'FFFF00', bold:true, break:false } },
        { text:'3rd word ', options:{ color:'0088CC', break: false } }
    ],
    { x:1.5, y:1.5, w:6, h:2, margin:0.1, fill:'232323', align:'center' }
    );

with the patch you get what you want
grafik

But alignment necessitates a paragraph as you cant align words...

But you still have a paragraph, you just don鈥檛 add one for each text object. The problem is, that, as soon as an align is specified, you add one
'</a:p><a:p>' + paragraphPropXml
between the different text objects in the array.

Okay, so what problem are we trying to solve?

Do you have a screencap of the PptxGenJS output versus the result you're looking for.

When using the code

slide.addText(
    [
        { text:'1st word ', options:{ color:'99ABCC', italic:true } },
        { text:'2nd word ', options:{ color:'FFFF00', bold:true } },
        { text:'3rd word ', options:{ color:'0088CC' } }
    ],
    { x:1.5, y:1.5, w:6, h:2, margin:0.1, fill:'232323', align:'center' }
    );

I get

Note that the three text objects are not in the same line, so if I want to have it like this

there's no way to do it.

@vpetzel, great job on writing this up and providing a fix in the mean time. I'm running into the same issue with this library when I want to style individual words in the PPT.

I couldn't figure this out for the longest time but as you mentioned, it only occurs if you're using the 'align' options, which is a pretty common use case. Adding your patch works great. It should be included in the base library, or if the regular functionality doesn't want to be changed, then add a new config property for the "don't break" scenario.

Any news on this ? I am facing the same issue.

I'll get this patched in an upcoming release.

var pptx = new PptxGenJS();
pptx.layout = "LAYOUT_WIDE";
var slide = pptx.addSlide();

// Works
slide.addText(
  [
    { text: "1st line", options: { fontSize: 24, color: "99ABCC" } },
    { text: "2nd line", options: { fontSize: 36, color: "FFFF00" } },
    { text: "3rd line", options: { fontSize: 48, color: "0088CC" } }
  ],
  { x: 1.5, y: 1.5, w: 6, h: 2, margin: 0.1, fill: "232323" }
);

// Creates one word per line (bug: `align` is inherited/applied to each text object)
slide.addText(
  [
    { text: "1st word ", options: { color: "99ABCC", italic: true } },
    { text: "2nd word ", options: { color: "FFFF00", bold: true } },
    { text: "3rd word ", options: { color: "0088CC" } }
  ],
  { x: 1.5, y: 1.5, w: 6, h: 2, margin: 0.1, fill: "232323", align: "center" }
);

pptx.save("PptxGenJS-Issue#369");

Screen Shot 2019-08-14 at 22 22 36

hey @gitbrent, I just tried this in the 3.0.0-beta.4 and the problem is unfortunately still there.

Related: Issue #258

Fixed via #751

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shyam2794 picture shyam2794  路  6Comments

Skiizoo picture Skiizoo  路  6Comments

bestis picture bestis  路  6Comments

Kirill71 picture Kirill71  路  4Comments

jobnte picture jobnte  路  5Comments