Auto Detect Last Paragraph and Pass to Macro

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












4














The MWE below produces the desired results:




enter image description here




via the ProcessLastPara which applies a desired parshape to the given (last) paragraph.



Questions:



The MWE below required me to manually identify both the start and end of the last paragraph so it could be passed on to the ProcessLastPara macro.




  1. Is it possible to achieve the effect of ProcessLastPara<text> by simply identifying the beginning of the last paragraph. That is, can I change the call to SetMyText to be of the form:



    SetMyText%
    Other Text...

    LastParaBeginsHere
    Last Para Text%
    %


    so that LastParaBeginsHere invokesProcessLastParaLast Para Text.



    This would need some error checking to make sure that LastParaBeginsHere really was indeed the last paragraph defined by SetMyText.



  2. Is it possible to auto detect where the last paragraph begins and ends so that I do not need to manually invoke ProcessLastPara and identify the text of the last paragraph?


Notes:



  • This needs to work for the case where the text is defined in a macro before it is typeset.

  • The solution of defLastParaBeginsHereLastParShape won't work as I need to process the last paragraph text to determine the appropriate parshape to apply. That is, this is a 2 step process, the details of which are not included here to simplify the test case.

Code:



documentclassarticle

usepackage[paperwidth=15cm]geometry

makeatletter
newcommand@MyText
newcommandSetMyText[1]def@MyText#1%
newcommand*OutputMyText@MyText%
makeatother

newcommand*LastParShape%
parshape 5
0.10hsize 0.80hsize
0.15hsize 0.70hsize
0.20hsize 0.60hsize
0.25hsize 0.50hsize
0.30hsize 0.40hsize
%


newcommand*ProcessLastPara[1]%
LastParShape
#1%

begindocument
SetMyText%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.

ProcessLastPara%
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.%
%
%% ----------------
OutputMyText%
enddocument









share|improve this question





















  • do you want the para indent on the first line of your triangle, I cancelled it out (not quite correctly) in my answer but I could remove it to get the same shape that you and egreg show...
    – David Carlisle
    Dec 12 at 9:15










  • @DavidCarlisle: Removing indentation of the last para is preferrable.
    – Peter Grill
    Dec 12 at 17:59















4














The MWE below produces the desired results:




enter image description here




via the ProcessLastPara which applies a desired parshape to the given (last) paragraph.



Questions:



The MWE below required me to manually identify both the start and end of the last paragraph so it could be passed on to the ProcessLastPara macro.




  1. Is it possible to achieve the effect of ProcessLastPara<text> by simply identifying the beginning of the last paragraph. That is, can I change the call to SetMyText to be of the form:



    SetMyText%
    Other Text...

    LastParaBeginsHere
    Last Para Text%
    %


    so that LastParaBeginsHere invokesProcessLastParaLast Para Text.



    This would need some error checking to make sure that LastParaBeginsHere really was indeed the last paragraph defined by SetMyText.



  2. Is it possible to auto detect where the last paragraph begins and ends so that I do not need to manually invoke ProcessLastPara and identify the text of the last paragraph?


Notes:



  • This needs to work for the case where the text is defined in a macro before it is typeset.

  • The solution of defLastParaBeginsHereLastParShape won't work as I need to process the last paragraph text to determine the appropriate parshape to apply. That is, this is a 2 step process, the details of which are not included here to simplify the test case.

Code:



documentclassarticle

usepackage[paperwidth=15cm]geometry

makeatletter
newcommand@MyText
newcommandSetMyText[1]def@MyText#1%
newcommand*OutputMyText@MyText%
makeatother

newcommand*LastParShape%
parshape 5
0.10hsize 0.80hsize
0.15hsize 0.70hsize
0.20hsize 0.60hsize
0.25hsize 0.50hsize
0.30hsize 0.40hsize
%


newcommand*ProcessLastPara[1]%
LastParShape
#1%

begindocument
SetMyText%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.

ProcessLastPara%
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.%
%
%% ----------------
OutputMyText%
enddocument









share|improve this question





















  • do you want the para indent on the first line of your triangle, I cancelled it out (not quite correctly) in my answer but I could remove it to get the same shape that you and egreg show...
    – David Carlisle
    Dec 12 at 9:15










  • @DavidCarlisle: Removing indentation of the last para is preferrable.
    – Peter Grill
    Dec 12 at 17:59













4












4








4


1





The MWE below produces the desired results:




enter image description here




via the ProcessLastPara which applies a desired parshape to the given (last) paragraph.



Questions:



The MWE below required me to manually identify both the start and end of the last paragraph so it could be passed on to the ProcessLastPara macro.




  1. Is it possible to achieve the effect of ProcessLastPara<text> by simply identifying the beginning of the last paragraph. That is, can I change the call to SetMyText to be of the form:



    SetMyText%
    Other Text...

    LastParaBeginsHere
    Last Para Text%
    %


    so that LastParaBeginsHere invokesProcessLastParaLast Para Text.



    This would need some error checking to make sure that LastParaBeginsHere really was indeed the last paragraph defined by SetMyText.



  2. Is it possible to auto detect where the last paragraph begins and ends so that I do not need to manually invoke ProcessLastPara and identify the text of the last paragraph?


Notes:



  • This needs to work for the case where the text is defined in a macro before it is typeset.

  • The solution of defLastParaBeginsHereLastParShape won't work as I need to process the last paragraph text to determine the appropriate parshape to apply. That is, this is a 2 step process, the details of which are not included here to simplify the test case.

Code:



documentclassarticle

usepackage[paperwidth=15cm]geometry

makeatletter
newcommand@MyText
newcommandSetMyText[1]def@MyText#1%
newcommand*OutputMyText@MyText%
makeatother

newcommand*LastParShape%
parshape 5
0.10hsize 0.80hsize
0.15hsize 0.70hsize
0.20hsize 0.60hsize
0.25hsize 0.50hsize
0.30hsize 0.40hsize
%


newcommand*ProcessLastPara[1]%
LastParShape
#1%

begindocument
SetMyText%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.

ProcessLastPara%
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.%
%
%% ----------------
OutputMyText%
enddocument









share|improve this question













The MWE below produces the desired results:




enter image description here




via the ProcessLastPara which applies a desired parshape to the given (last) paragraph.



Questions:



The MWE below required me to manually identify both the start and end of the last paragraph so it could be passed on to the ProcessLastPara macro.




  1. Is it possible to achieve the effect of ProcessLastPara<text> by simply identifying the beginning of the last paragraph. That is, can I change the call to SetMyText to be of the form:



    SetMyText%
    Other Text...

    LastParaBeginsHere
    Last Para Text%
    %


    so that LastParaBeginsHere invokesProcessLastParaLast Para Text.



    This would need some error checking to make sure that LastParaBeginsHere really was indeed the last paragraph defined by SetMyText.



  2. Is it possible to auto detect where the last paragraph begins and ends so that I do not need to manually invoke ProcessLastPara and identify the text of the last paragraph?


Notes:



  • This needs to work for the case where the text is defined in a macro before it is typeset.

  • The solution of defLastParaBeginsHereLastParShape won't work as I need to process the last paragraph text to determine the appropriate parshape to apply. That is, this is a 2 step process, the details of which are not included here to simplify the test case.

Code:



documentclassarticle

usepackage[paperwidth=15cm]geometry

makeatletter
newcommand@MyText
newcommandSetMyText[1]def@MyText#1%
newcommand*OutputMyText@MyText%
makeatother

newcommand*LastParShape%
parshape 5
0.10hsize 0.80hsize
0.15hsize 0.70hsize
0.20hsize 0.60hsize
0.25hsize 0.50hsize
0.30hsize 0.40hsize
%


newcommand*ProcessLastPara[1]%
LastParShape
#1%

begindocument
SetMyText%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.

ProcessLastPara%
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.%
%
%% ----------------
OutputMyText%
enddocument






macros line-breaking paragraphs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Dec 12 at 7:43









Peter Grill

163k25434745




163k25434745











  • do you want the para indent on the first line of your triangle, I cancelled it out (not quite correctly) in my answer but I could remove it to get the same shape that you and egreg show...
    – David Carlisle
    Dec 12 at 9:15










  • @DavidCarlisle: Removing indentation of the last para is preferrable.
    – Peter Grill
    Dec 12 at 17:59
















  • do you want the para indent on the first line of your triangle, I cancelled it out (not quite correctly) in my answer but I could remove it to get the same shape that you and egreg show...
    – David Carlisle
    Dec 12 at 9:15










  • @DavidCarlisle: Removing indentation of the last para is preferrable.
    – Peter Grill
    Dec 12 at 17:59















do you want the para indent on the first line of your triangle, I cancelled it out (not quite correctly) in my answer but I could remove it to get the same shape that you and egreg show...
– David Carlisle
Dec 12 at 9:15




do you want the para indent on the first line of your triangle, I cancelled it out (not quite correctly) in my answer but I could remove it to get the same shape that you and egreg show...
– David Carlisle
Dec 12 at 9:15












@DavidCarlisle: Removing indentation of the last para is preferrable.
– Peter Grill
Dec 12 at 17:59




@DavidCarlisle: Removing indentation of the last para is preferrable.
– Peter Grill
Dec 12 at 17:59










2 Answers
2






active

oldest

votes


















5














documentclassarticle

usepackage[paperwidth=15cm]geometry

makeatletter
newcommand@MyText
newcommandSetMyText[1]def@MyText#1LastParShapepar%
newcommand*OutputMyText@MyText%
makeatother

newcommand*LastParShape%
parshape 5
dimexpr0.10hsize-parindentrelax dimexpr0.80hsize+parindentrelax
0.15hsize 0.70hsize
0.20hsize 0.60hsize
0.25hsize 0.50hsize
0.30hsize 0.40hsize
%



begindocument
SetMyText%
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.%
%
%% ----------------
OutputMyText%
enddocument


enter image description here






share|improve this answer


















  • 1




    I didn't even need egreg's hat.
    – David Carlisle
    Dec 12 at 9:10










  • What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
    – Peter Grill
    Dec 12 at 17:58











  • @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
    – David Carlisle
    Dec 12 at 18:45







  • 1




    @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
    – javadr
    Dec 12 at 19:12






  • 2




    @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
    – David Carlisle
    Dec 12 at 19:44


















3














It's quite easy with expl3: collect the text, split it at par, then detach the last paragraph and typeset it separately.



documentclassarticle
usepackage[paperwidth=15cm]geometry
usepackagexparse

ExplSyntaxOn
NewDocumentCommandSetMyTexts+m

IfBooleanTF#1

seq_set_split:NnV l_peter_mytext_seq par #2


seq_set_split:Nnn l_peter_mytext_seq par #2


cs_generate_variant:Nn seq_set_split:Nnn NnV
seq_new:N l_peter_mytext_seq
tl_new:N l_peter_mytext_tl

NewDocumentCommandOutputMyText

seq_pop_right:NN l_peter_mytext_seq l_peter_mytext_tl
seq_use:Nn l_peter_mytext_seq par par
LastParShape l_peter_mytext_tl

ExplSyntaxOff

newcommand*LastParShape%
parshape 5
0.10hsize 0.80hsize
0.15hsize 0.70hsize
0.20hsize 0.60hsize
0.25hsize 0.50hsize
0.30hsize 0.40hsize


begindocument

SetMyText
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.


OutputMyText

enddocument


enter image description here






share|improve this answer




















    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "85"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f464468%2fauto-detect-last-paragraph-and-pass-to-macro%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5














    documentclassarticle

    usepackage[paperwidth=15cm]geometry

    makeatletter
    newcommand@MyText
    newcommandSetMyText[1]def@MyText#1LastParShapepar%
    newcommand*OutputMyText@MyText%
    makeatother

    newcommand*LastParShape%
    parshape 5
    dimexpr0.10hsize-parindentrelax dimexpr0.80hsize+parindentrelax
    0.15hsize 0.70hsize
    0.20hsize 0.60hsize
    0.25hsize 0.50hsize
    0.30hsize 0.40hsize
    %



    begindocument
    SetMyText%
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua.

    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.

    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.%
    %
    %% ----------------
    OutputMyText%
    enddocument


    enter image description here






    share|improve this answer


















    • 1




      I didn't even need egreg's hat.
      – David Carlisle
      Dec 12 at 9:10










    • What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
      – Peter Grill
      Dec 12 at 17:58











    • @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
      – David Carlisle
      Dec 12 at 18:45







    • 1




      @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
      – javadr
      Dec 12 at 19:12






    • 2




      @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
      – David Carlisle
      Dec 12 at 19:44















    5














    documentclassarticle

    usepackage[paperwidth=15cm]geometry

    makeatletter
    newcommand@MyText
    newcommandSetMyText[1]def@MyText#1LastParShapepar%
    newcommand*OutputMyText@MyText%
    makeatother

    newcommand*LastParShape%
    parshape 5
    dimexpr0.10hsize-parindentrelax dimexpr0.80hsize+parindentrelax
    0.15hsize 0.70hsize
    0.20hsize 0.60hsize
    0.25hsize 0.50hsize
    0.30hsize 0.40hsize
    %



    begindocument
    SetMyText%
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua.

    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.

    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.%
    %
    %% ----------------
    OutputMyText%
    enddocument


    enter image description here






    share|improve this answer


















    • 1




      I didn't even need egreg's hat.
      – David Carlisle
      Dec 12 at 9:10










    • What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
      – Peter Grill
      Dec 12 at 17:58











    • @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
      – David Carlisle
      Dec 12 at 18:45







    • 1




      @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
      – javadr
      Dec 12 at 19:12






    • 2




      @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
      – David Carlisle
      Dec 12 at 19:44













    5












    5








    5






    documentclassarticle

    usepackage[paperwidth=15cm]geometry

    makeatletter
    newcommand@MyText
    newcommandSetMyText[1]def@MyText#1LastParShapepar%
    newcommand*OutputMyText@MyText%
    makeatother

    newcommand*LastParShape%
    parshape 5
    dimexpr0.10hsize-parindentrelax dimexpr0.80hsize+parindentrelax
    0.15hsize 0.70hsize
    0.20hsize 0.60hsize
    0.25hsize 0.50hsize
    0.30hsize 0.40hsize
    %



    begindocument
    SetMyText%
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua.

    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.

    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.%
    %
    %% ----------------
    OutputMyText%
    enddocument


    enter image description here






    share|improve this answer














    documentclassarticle

    usepackage[paperwidth=15cm]geometry

    makeatletter
    newcommand@MyText
    newcommandSetMyText[1]def@MyText#1LastParShapepar%
    newcommand*OutputMyText@MyText%
    makeatother

    newcommand*LastParShape%
    parshape 5
    dimexpr0.10hsize-parindentrelax dimexpr0.80hsize+parindentrelax
    0.15hsize 0.70hsize
    0.20hsize 0.60hsize
    0.25hsize 0.50hsize
    0.30hsize 0.40hsize
    %



    begindocument
    SetMyText%
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua.

    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.

    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.%
    %
    %% ----------------
    OutputMyText%
    enddocument


    enter image description here







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 12 at 18:49

























    answered Dec 12 at 9:10









    David Carlisle

    481k3811121848




    481k3811121848







    • 1




      I didn't even need egreg's hat.
      – David Carlisle
      Dec 12 at 9:10










    • What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
      – Peter Grill
      Dec 12 at 17:58











    • @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
      – David Carlisle
      Dec 12 at 18:45







    • 1




      @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
      – javadr
      Dec 12 at 19:12






    • 2




      @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
      – David Carlisle
      Dec 12 at 19:44












    • 1




      I didn't even need egreg's hat.
      – David Carlisle
      Dec 12 at 9:10










    • What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
      – Peter Grill
      Dec 12 at 17:58











    • @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
      – David Carlisle
      Dec 12 at 18:45







    • 1




      @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
      – javadr
      Dec 12 at 19:12






    • 2




      @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
      – David Carlisle
      Dec 12 at 19:44







    1




    1




    I didn't even need egreg's hat.
    – David Carlisle
    Dec 12 at 9:10




    I didn't even need egreg's hat.
    – David Carlisle
    Dec 12 at 9:10












    What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
    – Peter Grill
    Dec 12 at 17:58





    What kind of sorcery is this? You can specify the parhsape after the paragraph (ie, after the #1 in SetMyText)? However, this won't work as per second point in the Notes. I need the content of the last paragraph to be passed to ProcessLastPara as a parameter so that I can determine the correct parshape to apply.
    – Peter Grill
    Dec 12 at 17:58













    @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
    – David Carlisle
    Dec 12 at 18:45





    @PeterGrill I saw that note but decided just to answer the question as asked, as I wanted to demonstrate this (which uses a few orders of magnitude fewer macro expansions than egreg's:-) (you could of course add a noindent to the code in your question and egreg's answer to get the full length top row.
    – David Carlisle
    Dec 12 at 18:45





    1




    1




    @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
    – javadr
    Dec 12 at 19:12




    @DavidCarlisle Very nice and concise answer, but I'm really confused by putting the LastParShape after #1. I wish you would have time to explain more about it.
    – javadr
    Dec 12 at 19:12




    2




    2




    @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
    – David Carlisle
    Dec 12 at 19:44




    @javadr paragraph settings, whether parshape or centering etc use the settings in force at the end of the paragraph, which is why you often see on this site warnings that centering hello does not center as the settings are discarded but centering hellopar does center, as does noindent hellocenteringpar setting the parshape is the same, it sets the linebreaking but is not consulted until tex starts linebreaking which is at the end of the paragraph.
    – David Carlisle
    Dec 12 at 19:44











    3














    It's quite easy with expl3: collect the text, split it at par, then detach the last paragraph and typeset it separately.



    documentclassarticle
    usepackage[paperwidth=15cm]geometry
    usepackagexparse

    ExplSyntaxOn
    NewDocumentCommandSetMyTexts+m

    IfBooleanTF#1

    seq_set_split:NnV l_peter_mytext_seq par #2


    seq_set_split:Nnn l_peter_mytext_seq par #2


    cs_generate_variant:Nn seq_set_split:Nnn NnV
    seq_new:N l_peter_mytext_seq
    tl_new:N l_peter_mytext_tl

    NewDocumentCommandOutputMyText

    seq_pop_right:NN l_peter_mytext_seq l_peter_mytext_tl
    seq_use:Nn l_peter_mytext_seq par par
    LastParShape l_peter_mytext_tl

    ExplSyntaxOff

    newcommand*LastParShape%
    parshape 5
    0.10hsize 0.80hsize
    0.15hsize 0.70hsize
    0.20hsize 0.60hsize
    0.25hsize 0.50hsize
    0.30hsize 0.40hsize


    begindocument

    SetMyText
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua.

    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat.

    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
    eu fugiat nulla pariatur.
    Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
    deserunt mollit anim id est laborum.


    OutputMyText

    enddocument


    enter image description here






    share|improve this answer

























      3














      It's quite easy with expl3: collect the text, split it at par, then detach the last paragraph and typeset it separately.



      documentclassarticle
      usepackage[paperwidth=15cm]geometry
      usepackagexparse

      ExplSyntaxOn
      NewDocumentCommandSetMyTexts+m

      IfBooleanTF#1

      seq_set_split:NnV l_peter_mytext_seq par #2


      seq_set_split:Nnn l_peter_mytext_seq par #2


      cs_generate_variant:Nn seq_set_split:Nnn NnV
      seq_new:N l_peter_mytext_seq
      tl_new:N l_peter_mytext_tl

      NewDocumentCommandOutputMyText

      seq_pop_right:NN l_peter_mytext_seq l_peter_mytext_tl
      seq_use:Nn l_peter_mytext_seq par par
      LastParShape l_peter_mytext_tl

      ExplSyntaxOff

      newcommand*LastParShape%
      parshape 5
      0.10hsize 0.80hsize
      0.15hsize 0.70hsize
      0.20hsize 0.60hsize
      0.25hsize 0.50hsize
      0.30hsize 0.40hsize


      begindocument

      SetMyText
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
      incididunt ut labore et dolore magna aliqua.

      Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
      aliquip ex ea commodo consequat.

      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
      eu fugiat nulla pariatur.
      Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
      deserunt mollit anim id est laborum.


      OutputMyText

      enddocument


      enter image description here






      share|improve this answer























        3












        3








        3






        It's quite easy with expl3: collect the text, split it at par, then detach the last paragraph and typeset it separately.



        documentclassarticle
        usepackage[paperwidth=15cm]geometry
        usepackagexparse

        ExplSyntaxOn
        NewDocumentCommandSetMyTexts+m

        IfBooleanTF#1

        seq_set_split:NnV l_peter_mytext_seq par #2


        seq_set_split:Nnn l_peter_mytext_seq par #2


        cs_generate_variant:Nn seq_set_split:Nnn NnV
        seq_new:N l_peter_mytext_seq
        tl_new:N l_peter_mytext_tl

        NewDocumentCommandOutputMyText

        seq_pop_right:NN l_peter_mytext_seq l_peter_mytext_tl
        seq_use:Nn l_peter_mytext_seq par par
        LastParShape l_peter_mytext_tl

        ExplSyntaxOff

        newcommand*LastParShape%
        parshape 5
        0.10hsize 0.80hsize
        0.15hsize 0.70hsize
        0.20hsize 0.60hsize
        0.25hsize 0.50hsize
        0.30hsize 0.40hsize


        begindocument

        SetMyText
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
        incididunt ut labore et dolore magna aliqua.

        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
        aliquip ex ea commodo consequat.

        Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
        eu fugiat nulla pariatur.
        Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
        deserunt mollit anim id est laborum.


        OutputMyText

        enddocument


        enter image description here






        share|improve this answer












        It's quite easy with expl3: collect the text, split it at par, then detach the last paragraph and typeset it separately.



        documentclassarticle
        usepackage[paperwidth=15cm]geometry
        usepackagexparse

        ExplSyntaxOn
        NewDocumentCommandSetMyTexts+m

        IfBooleanTF#1

        seq_set_split:NnV l_peter_mytext_seq par #2


        seq_set_split:Nnn l_peter_mytext_seq par #2


        cs_generate_variant:Nn seq_set_split:Nnn NnV
        seq_new:N l_peter_mytext_seq
        tl_new:N l_peter_mytext_tl

        NewDocumentCommandOutputMyText

        seq_pop_right:NN l_peter_mytext_seq l_peter_mytext_tl
        seq_use:Nn l_peter_mytext_seq par par
        LastParShape l_peter_mytext_tl

        ExplSyntaxOff

        newcommand*LastParShape%
        parshape 5
        0.10hsize 0.80hsize
        0.15hsize 0.70hsize
        0.20hsize 0.60hsize
        0.25hsize 0.50hsize
        0.30hsize 0.40hsize


        begindocument

        SetMyText
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
        incididunt ut labore et dolore magna aliqua.

        Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
        aliquip ex ea commodo consequat.

        Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
        eu fugiat nulla pariatur.
        Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
        deserunt mollit anim id est laborum.


        OutputMyText

        enddocument


        enter image description here







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 12 at 8:49









        egreg

        706k8618783160




        706k8618783160



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f464468%2fauto-detect-last-paragraph-and-pass-to-macro%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay