Respectable-abbreviations macro









up vote
7
down vote

favorite
1












How might one write a macro that makes slovenly abbreviations respectable?



documentclassarticle
% newcommandabr...
begindocument
I've seen it in the abrOED.
enddocument


What I mean is that OED should be rendered as O.,E.,D..



As Mico points out, there should never be two contiguous points. I
suppose one might use @ifnextchar. to prevent that.










share|improve this question























  • Are you sure that you want two . punctuation marks after the (non-slovenly) version of OED?
    – Mico
    Nov 8 at 16:41







  • 1




    @Mico, I'm sure I don't; edited.
    – Toothrot
    Nov 8 at 19:42






  • 1




    Note however that the norm is that abbreviations should be typeset without any dots. I don't have the reference to the norm right now, but I'll post it later on.
    – Massimo Ortolano
    Nov 9 at 7:44














up vote
7
down vote

favorite
1












How might one write a macro that makes slovenly abbreviations respectable?



documentclassarticle
% newcommandabr...
begindocument
I've seen it in the abrOED.
enddocument


What I mean is that OED should be rendered as O.,E.,D..



As Mico points out, there should never be two contiguous points. I
suppose one might use @ifnextchar. to prevent that.










share|improve this question























  • Are you sure that you want two . punctuation marks after the (non-slovenly) version of OED?
    – Mico
    Nov 8 at 16:41







  • 1




    @Mico, I'm sure I don't; edited.
    – Toothrot
    Nov 8 at 19:42






  • 1




    Note however that the norm is that abbreviations should be typeset without any dots. I don't have the reference to the norm right now, but I'll post it later on.
    – Massimo Ortolano
    Nov 9 at 7:44












up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





How might one write a macro that makes slovenly abbreviations respectable?



documentclassarticle
% newcommandabr...
begindocument
I've seen it in the abrOED.
enddocument


What I mean is that OED should be rendered as O.,E.,D..



As Mico points out, there should never be two contiguous points. I
suppose one might use @ifnextchar. to prevent that.










share|improve this question















How might one write a macro that makes slovenly abbreviations respectable?



documentclassarticle
% newcommandabr...
begindocument
I've seen it in the abrOED.
enddocument


What I mean is that OED should be rendered as O.,E.,D..



As Mico points out, there should never be two contiguous points. I
suppose one might use @ifnextchar. to prevent that.







macros






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 19:48

























asked Nov 8 at 12:36









Toothrot

1,359417




1,359417











  • Are you sure that you want two . punctuation marks after the (non-slovenly) version of OED?
    – Mico
    Nov 8 at 16:41







  • 1




    @Mico, I'm sure I don't; edited.
    – Toothrot
    Nov 8 at 19:42






  • 1




    Note however that the norm is that abbreviations should be typeset without any dots. I don't have the reference to the norm right now, but I'll post it later on.
    – Massimo Ortolano
    Nov 9 at 7:44
















  • Are you sure that you want two . punctuation marks after the (non-slovenly) version of OED?
    – Mico
    Nov 8 at 16:41







  • 1




    @Mico, I'm sure I don't; edited.
    – Toothrot
    Nov 8 at 19:42






  • 1




    Note however that the norm is that abbreviations should be typeset without any dots. I don't have the reference to the norm right now, but I'll post it later on.
    – Massimo Ortolano
    Nov 9 at 7:44















Are you sure that you want two . punctuation marks after the (non-slovenly) version of OED?
– Mico
Nov 8 at 16:41





Are you sure that you want two . punctuation marks after the (non-slovenly) version of OED?
– Mico
Nov 8 at 16:41





1




1




@Mico, I'm sure I don't; edited.
– Toothrot
Nov 8 at 19:42




@Mico, I'm sure I don't; edited.
– Toothrot
Nov 8 at 19:42




1




1




Note however that the norm is that abbreviations should be typeset without any dots. I don't have the reference to the norm right now, but I'll post it later on.
– Massimo Ortolano
Nov 9 at 7:44




Note however that the norm is that abbreviations should be typeset without any dots. I don't have the reference to the norm right now, but I'll post it later on.
– Massimo Ortolano
Nov 9 at 7:44










6 Answers
6






active

oldest

votes

















up vote
7
down vote













All in all the same as the answer by Steven B. Segletes, but expandable. Also almost everything as contents should be fine (except the really unlikely endabr@).



documentclassarticle

makeatletter
newcommandabr[1]
%
abr@#1endabr@

defabr@#1#2endabr@
%
#1.%
ifrelaxdetokenize#2relax
@%
expandafter@gobble
else
,%
expandafter@firstofone
fi
abr@#2endabr@%

makeatother

begindocument
Single letter:
abreg

Multi letter:
abrthe
enddocument





share|improve this answer
















  • 1




    I believe mine is fully expandable, as well.
    – Steven B. Segletes
    Nov 8 at 12:59










  • @StevenB.Segletes def is not expandable.
    – Skillmon
    Nov 8 at 13:00










  • Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
    – Steven B. Segletes
    Nov 8 at 13:01










  • @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
    – Skillmon
    Nov 8 at 13:02






  • 1




    @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
    – Skillmon
    Nov 8 at 13:05

















up vote
6
down vote













Here is the simplest form of my original approach. It can be placed in an edef. Its only drawback is that it can blow the stack if the argument is too long (maybe 256 characters??)



documentclassarticle
newcommandabr[1]abraux#1relaxrelax
defabraux#1#2relax#1.ifxrelax#2relax@else,abraux#2relaxfi
begindocument
Here is abrOED abbreviation.

Here is abrXO abbreviation.
enddocument


enter image description here



If that really were an issue, here is an alternative that doesn't have that problem.



There seems to be a misunderstanding that this definition of abr cannot be placed into an edef. It can. Naturally, the expansion is not necessarily pretty, but it will yield the proper typesetting. The only proviso is that @MyOwnMacro is not used elsewhere in your document.



documentclassarticle
usepackage[T1]fontenc
makeatletter
let@MyOwnMacrorelax
newcommandabr[1]abraux#1relaxrelax
defabraux#1#2relax%
#1.ifxrelax#2relaxdef@MyOwnMacro@elsedef@MyOwnMacro,abraux#2relaxfi%
@MyOwnMacro%

makeatother
begindocument
Here is abrOED abbreviation.

Here is abrXO abbreviation.

Can be edef'ed:

edeftmpabrOED detokenizeexpandaftertmp

expands to tmp
enddocument


enter image description here






share|improve this answer


















  • 1




    Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
    – Sebastiano
    Nov 8 at 12:51







  • 1




    @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
    – Steven B. Segletes
    Nov 8 at 12:58










  • It can't be edefed if it is used for the first time! It'll throw an error.
    – Skillmon
    Nov 8 at 13:55










  • @Skillmon OK, letnextrelax fixes that.
    – Steven B. Segletes
    Nov 8 at 14:16






  • 2




    @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
    – Skillmon
    Nov 8 at 14:21

















up vote
6
down vote













Here's a LuaLaTeX-based solution.



  • Cases such as abrOED or abrIMF work just as expected. If the acronym contains both uppercase and lowercase letters, dots are inserted only before the uppercase letters in the interior of the acronym. E.g., abrMSc generates M.,Sc., and abrPhD generates Ph.,D..


  • It can handle mixed-case acronyms such as "PhD" directly -- no need to write abrPhD.


  • If a "slovenly abbreviation" ends a sentence, one should place the "." punctuation mark inside the argument of abr. The code takes care to insert a @ "space factor* directive before the final . character. This, in turn, informs LaTeX that that . character should be treated as ending a sentence.


  • The code returns nothing if the argument of abr is either empty or expands to return nothing. E.g., defttt /abrttt/ returns //. If the code encounters non-letter characters -- say, ( and ) -- no periods are inserted before or after them.


  • The code is expandable in the sense that abr can be included in the argument of an edef directive.


enter image description here



documentclassarticle
usepackageluacode % for 'luacode' environment

%% Lua-side code:
beginluacode


function abr ( s )
n = string.len ( s )
-- Do nothing unless "s" is non-empty.
if n>0 then
s_mod = "" -- initialize the string

-- Process the first n-1 characters in "s"
for i=1, n-1 do
s12 = string.sub ( s , i, i+1 )
s1 = string.sub ( s12, 1, 1 )
if string.match ( s12 , "%a%u" ) then
s_mod = s_mod .. s1 .. ".\,"
else
s_mod = s_mod .. s1
end
end

-- Process the final character in "s"
s_n = string.sub ( s , n)
if string.match (s_n, "%.") then -- "." char.
s_mod = s_mod .. "\@."
elseif string.match (s_n, "%l") then -- lowercase letter
s_mod = s_mod .. s_n .. ".\hbox"
elseif string.match (s_n, "%u") then -- uppercase letter
s_mod = s_mod .. s_n .. "."
else -- Any other character:
s_mod = s_mod .. s_n -- don't add anything after 's_n'
end


 -- Print the modified string
tex.sprint ( s_mod )
end
end

endluacode

%% LaTeX-side code: macro that calls the Lua function
newcommandabr[2]directluaabr("#1")

begindocument
abrOED, abrPhD, abrDPhil, abrMSc, abr()

smallskip
% Two calls to "abr" with an empty argument (upon expansion):
.abr. quad
defttt .abrttt.

bigskip
edeftmpabrMA detokenizeexpandaftertmp

edeftmpabrMA. detokenizeexpandaftertmp

expands to: tmp

smallskip
edeftmpabrMSc detokenizeexpandaftertmp

edeftmpabrMSc. detokenizeexpandaftertmp

expands to: tmp

bigskip
Some tests of spacing after punctuation marks:

smallskip
a abrPhD candidate --- good

a Ph.,D. candidate --- just to verify

smallskip
an abrMSc candidate --- good

an M.,Sc. candidate --- just to verify

smallskip
She has a abrPhD. So do I. --- good

She has a Ph.,D@. So do I. --- just to verify

smallskip
He has an abrMSc. So do I. --- good

He has an M.,Sc. So do I. --- just to verify

smallskip
Does he have an abrMSc.? Really?! --- good

Does he have an M.,Sc.? Really?! --- just to verify
enddocument





share|improve this answer






















  • I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
    – Toothrot
    Nov 8 at 22:16










  • @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
    – Mico
    Nov 8 at 22:49










  • How about @ifnextchar.spacefactor3000@gobble or something like that?
    – Toothrot
    Nov 8 at 22:55










  • @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
    – Mico
    Nov 9 at 6:11

















up vote
5
down vote













Let TeX do the recursion:



documentclassarticle
usepackagexparse
usepackageetoolbox

robustify, % just in order it doesn't expand in edef

ExplSyntaxOn
NewExpandableDocumentCommandabrm

tl_map_function:fN tl_range:nnn #1 1 -2 __toothrot_abr:n
tl_range:nnn #1 -1 -1 .

cs_generate_variant:Nn tl_map_function:nN f
cs_new:Nn __toothrot_abr:n #1.,
ExplSyntaxOff

begindocument

abrOED

abrPhD

edeftestabrOED
textttmeaningtest

edeftestabr
textttmeaningtest

enddocument


If a part of the argument is braced, it is considered as a single item.



One might check whether the argument is empty in order to print nothing at all, but it doesn't seem so important a feature.



enter image description here



With tl_range:nnn #1 1 -2 we extract all items but the last; tl_range:nnn #1 -1 -1 extracts the last item.






share|improve this answer



























    up vote
    5
    down vote













    documentclassarticle
    usepackagexinttools
    newcommandabr[1]xintListWithSep.,#1.
    begindocument
    I've seen it in the abrOED.

    I got my abrPhD.
    enddocument


    enter image description here



    Updated (à la Mico, but without LuaLaTeX)



    The syntax here is to use abrPhD. for example at end of a sentence, and abrPhD if not at end of a sentence.



    documentclassarticle
    usepackagexinttools
    makeatletter
    newcommandabr[1]
    expandafter@gobbletworomannumeral0xintapplyunbracedabr@aux#1.@
    defabr@sep.,
    defabr@aux#1if.#1expandafterabr@end
    else
    if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
    expandafterexpandafterexpandafterabr@sep
    fi
    fi#1%
    defabr@end. abr@@end
    defabr@@end.@@.
    makeatother

    begindocument%ttfamily
    I've seen it in the abrOED, and if located at end of a sentence
    just insert a dot in the verb|abr| argument: abrOED. It ended a
    sentence and in non-French spacing mode, TeX inserted the extra
    space.

    textttWe can see it better with monospace font: abrOED. See?

    I got my abrPhD and even my abrPhilD, leniency ruled
    in those days.

    textttThe dots are added in a smart way: abrAaaaBbbbCccc. But it is
    assumed that the first letter is abrUppercased. That's it.

    textttNotice that neitger abrAaaa nor abrAaA trigger an end of
    sentence spacing after the dot, which is abrGood. Isn't it?
    enddocument


    enter image description here



    Again updated, for automatic end of sentence dot detection after abbreviation



    Here an end of sentence dot will be detected automatically.



    Of course we can't use @ifnextchar for that, as it swallows spaces.



    I added some comments about expandability, which seems to have drawn great attention in other answers :).



    documentclassarticle
    usepackageshortvrbMakeShortVerb
    usepackagexinttools

    makeatletter
    protecteddefabrsep.,% maybe redefined even after edeffooabrDPhil...
    protecteddefabrendfuturelet@let@tokenabr@end
    defabr@endifx.@let@token@else.@fi
    newcommandabr[1]
    expandafter@gobbleromannumeral0xintapplyunbracedabr@aux#1abrend
    defabr@aux#1if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
    expandafterabr@sep
    fi#1%
    defabr@sep abrsep
    makeatother

    begindocument%ttfamily
    I've seen it in the abrOED, and if located at end of a sentence
    it will detect it automatically: abrOED. There was no double dot.
    Besides, TeX applied its end of sentence extra space.

    textttWe can see it better with monospace font: abrOED. See?

    textttWe can see it better with monospace font: abrOED, See?

    I got a abrMSc, a abrPhD and even a abrDPhil. Leniency ruled
    in those days.

    The abbreviation dots are added in a smart way, after the last
    lowercase letter following an uppercase letter:
    abrAaaaBbbbCccc. But it is emphassumed that the first letter is
    abrUppercased. That's it.

    textttNotice that neither abrDPhil nor abrPhilD get TeX to
    consider the inserted final dot as signaling an end of
    sentence spacing after the dot, which is abrGood. Isn't it?

    About expandability, the correct way for LaTeX2e's users would be to use
    |protected@edef|, not a naked |edef|; although nowadays some
    LaTeX2e users have heard about |edef|, they might not know
    about |protected@edef|, which requires a cumbersome extra
    |makeatletter| for its usage. Anyway, none of that is described in
    textscLamport book, so I wonder if LaTeX2e users are really
    emphallowed into using |edef| to start with.

    But as it seems they know about |edef|, we as macro programmers need
    better to use the e-TeX's |protected| prefix and not the LaTeX2e
    |DeclareRobustCommand|, because users will not do |protected@edef|.

    This is what I have done here for a macro |abrsep| (why haven't we all
    used |abbr| by the way?) which is deliberately |protected|,
    allowing it to be redefined at location of use, long after some macro
    will have been defined via |edeffooabrABCDEFGH|.

    edeffooabrABCDEFGHtextttstringfoo is meaningfoo

    edeffooabrAaaBccCcctextttstringfoo is meaningfoo

    The |abrend| is also |protected|, anyway as its expansion will be
    context dependent (it detects if a dot follows), it had to not expand
    in the |edef|.
    enddocument


    enter image description here



    Notice that my proposals v2 and v3 will work only with ascii uppercase letters, no diacritics.






    share|improve this answer






















    • @Mico I plagiarized your input syntax for end of sentence...
      – jfbu
      Nov 8 at 17:07






    • 1




      @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
      – jfbu
      Nov 9 at 8:21










    • Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
      – Mico
      Nov 9 at 8:39










    • (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
      – jfbu
      Nov 9 at 9:47


















    up vote
    4
    down vote













    documentclassarticle
    newcommandabr[1]abraux#1..
    defabraux#1#2#3%
    #1%
    ifnum`#2>91relax% we have a lowercase letter following
    defnextabraux#2#3%
    else
    .ifx.#2defnext@else,defnextabraux#2#3fi
    fi
    next

    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.

    Here is abrXOOED abbreviation.

    abrMSc

    abrDPhil
    enddocument


    enter image description here






    share|improve this answer






















    • Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
      – Mico
      Nov 9 at 6:20






    • 1




      Sure, if it is not an uppercase letter then go the next char.
      – Herbert
      Nov 9 at 19:02










    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',
    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%2f458975%2frespectable-abbreviations-macro%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    7
    down vote













    All in all the same as the answer by Steven B. Segletes, but expandable. Also almost everything as contents should be fine (except the really unlikely endabr@).



    documentclassarticle

    makeatletter
    newcommandabr[1]
    %
    abr@#1endabr@

    defabr@#1#2endabr@
    %
    #1.%
    ifrelaxdetokenize#2relax
    @%
    expandafter@gobble
    else
    ,%
    expandafter@firstofone
    fi
    abr@#2endabr@%

    makeatother

    begindocument
    Single letter:
    abreg

    Multi letter:
    abrthe
    enddocument





    share|improve this answer
















    • 1




      I believe mine is fully expandable, as well.
      – Steven B. Segletes
      Nov 8 at 12:59










    • @StevenB.Segletes def is not expandable.
      – Skillmon
      Nov 8 at 13:00










    • Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
      – Steven B. Segletes
      Nov 8 at 13:01










    • @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
      – Skillmon
      Nov 8 at 13:02






    • 1




      @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
      – Skillmon
      Nov 8 at 13:05














    up vote
    7
    down vote













    All in all the same as the answer by Steven B. Segletes, but expandable. Also almost everything as contents should be fine (except the really unlikely endabr@).



    documentclassarticle

    makeatletter
    newcommandabr[1]
    %
    abr@#1endabr@

    defabr@#1#2endabr@
    %
    #1.%
    ifrelaxdetokenize#2relax
    @%
    expandafter@gobble
    else
    ,%
    expandafter@firstofone
    fi
    abr@#2endabr@%

    makeatother

    begindocument
    Single letter:
    abreg

    Multi letter:
    abrthe
    enddocument





    share|improve this answer
















    • 1




      I believe mine is fully expandable, as well.
      – Steven B. Segletes
      Nov 8 at 12:59










    • @StevenB.Segletes def is not expandable.
      – Skillmon
      Nov 8 at 13:00










    • Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
      – Steven B. Segletes
      Nov 8 at 13:01










    • @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
      – Skillmon
      Nov 8 at 13:02






    • 1




      @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
      – Skillmon
      Nov 8 at 13:05












    up vote
    7
    down vote










    up vote
    7
    down vote









    All in all the same as the answer by Steven B. Segletes, but expandable. Also almost everything as contents should be fine (except the really unlikely endabr@).



    documentclassarticle

    makeatletter
    newcommandabr[1]
    %
    abr@#1endabr@

    defabr@#1#2endabr@
    %
    #1.%
    ifrelaxdetokenize#2relax
    @%
    expandafter@gobble
    else
    ,%
    expandafter@firstofone
    fi
    abr@#2endabr@%

    makeatother

    begindocument
    Single letter:
    abreg

    Multi letter:
    abrthe
    enddocument





    share|improve this answer












    All in all the same as the answer by Steven B. Segletes, but expandable. Also almost everything as contents should be fine (except the really unlikely endabr@).



    documentclassarticle

    makeatletter
    newcommandabr[1]
    %
    abr@#1endabr@

    defabr@#1#2endabr@
    %
    #1.%
    ifrelaxdetokenize#2relax
    @%
    expandafter@gobble
    else
    ,%
    expandafter@firstofone
    fi
    abr@#2endabr@%

    makeatother

    begindocument
    Single letter:
    abreg

    Multi letter:
    abrthe
    enddocument






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 8 at 12:57









    Skillmon

    19.9k11739




    19.9k11739







    • 1




      I believe mine is fully expandable, as well.
      – Steven B. Segletes
      Nov 8 at 12:59










    • @StevenB.Segletes def is not expandable.
      – Skillmon
      Nov 8 at 13:00










    • Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
      – Steven B. Segletes
      Nov 8 at 13:01










    • @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
      – Skillmon
      Nov 8 at 13:02






    • 1




      @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
      – Skillmon
      Nov 8 at 13:05












    • 1




      I believe mine is fully expandable, as well.
      – Steven B. Segletes
      Nov 8 at 12:59










    • @StevenB.Segletes def is not expandable.
      – Skillmon
      Nov 8 at 13:00










    • Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
      – Steven B. Segletes
      Nov 8 at 13:01










    • @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
      – Skillmon
      Nov 8 at 13:02






    • 1




      @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
      – Skillmon
      Nov 8 at 13:05







    1




    1




    I believe mine is fully expandable, as well.
    – Steven B. Segletes
    Nov 8 at 12:59




    I believe mine is fully expandable, as well.
    – Steven B. Segletes
    Nov 8 at 12:59












    @StevenB.Segletes def is not expandable.
    – Skillmon
    Nov 8 at 13:00




    @StevenB.Segletes def is not expandable.
    – Skillmon
    Nov 8 at 13:00












    Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
    – Steven B. Segletes
    Nov 8 at 13:01




    Got it. I meant to say, mine can be placed in an edef. But you are right, the contents of the edef are not the final expansion.
    – Steven B. Segletes
    Nov 8 at 13:01












    @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
    – Skillmon
    Nov 8 at 13:02




    @StevenB.Segletes It can't be placed inside an edef as the edef would try to expand next before it gets defined.
    – Skillmon
    Nov 8 at 13:02




    1




    1




    @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
    – Skillmon
    Nov 8 at 13:05




    @StevenB.Segletes no. Just try edeftmpabrOED right after the definition of abr and abraux in your MWE. It'll throw an error.
    – Skillmon
    Nov 8 at 13:05










    up vote
    6
    down vote













    Here is the simplest form of my original approach. It can be placed in an edef. Its only drawback is that it can blow the stack if the argument is too long (maybe 256 characters??)



    documentclassarticle
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax#1.ifxrelax#2relax@else,abraux#2relaxfi
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.
    enddocument


    enter image description here



    If that really were an issue, here is an alternative that doesn't have that problem.



    There seems to be a misunderstanding that this definition of abr cannot be placed into an edef. It can. Naturally, the expansion is not necessarily pretty, but it will yield the proper typesetting. The only proviso is that @MyOwnMacro is not used elsewhere in your document.



    documentclassarticle
    usepackage[T1]fontenc
    makeatletter
    let@MyOwnMacrorelax
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax%
    #1.ifxrelax#2relaxdef@MyOwnMacro@elsedef@MyOwnMacro,abraux#2relaxfi%
    @MyOwnMacro%

    makeatother
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.

    Can be edef'ed:

    edeftmpabrOED detokenizeexpandaftertmp

    expands to tmp
    enddocument


    enter image description here






    share|improve this answer


















    • 1




      Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
      – Sebastiano
      Nov 8 at 12:51







    • 1




      @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
      – Steven B. Segletes
      Nov 8 at 12:58










    • It can't be edefed if it is used for the first time! It'll throw an error.
      – Skillmon
      Nov 8 at 13:55










    • @Skillmon OK, letnextrelax fixes that.
      – Steven B. Segletes
      Nov 8 at 14:16






    • 2




      @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
      – Skillmon
      Nov 8 at 14:21














    up vote
    6
    down vote













    Here is the simplest form of my original approach. It can be placed in an edef. Its only drawback is that it can blow the stack if the argument is too long (maybe 256 characters??)



    documentclassarticle
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax#1.ifxrelax#2relax@else,abraux#2relaxfi
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.
    enddocument


    enter image description here



    If that really were an issue, here is an alternative that doesn't have that problem.



    There seems to be a misunderstanding that this definition of abr cannot be placed into an edef. It can. Naturally, the expansion is not necessarily pretty, but it will yield the proper typesetting. The only proviso is that @MyOwnMacro is not used elsewhere in your document.



    documentclassarticle
    usepackage[T1]fontenc
    makeatletter
    let@MyOwnMacrorelax
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax%
    #1.ifxrelax#2relaxdef@MyOwnMacro@elsedef@MyOwnMacro,abraux#2relaxfi%
    @MyOwnMacro%

    makeatother
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.

    Can be edef'ed:

    edeftmpabrOED detokenizeexpandaftertmp

    expands to tmp
    enddocument


    enter image description here






    share|improve this answer


















    • 1




      Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
      – Sebastiano
      Nov 8 at 12:51







    • 1




      @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
      – Steven B. Segletes
      Nov 8 at 12:58










    • It can't be edefed if it is used for the first time! It'll throw an error.
      – Skillmon
      Nov 8 at 13:55










    • @Skillmon OK, letnextrelax fixes that.
      – Steven B. Segletes
      Nov 8 at 14:16






    • 2




      @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
      – Skillmon
      Nov 8 at 14:21












    up vote
    6
    down vote










    up vote
    6
    down vote









    Here is the simplest form of my original approach. It can be placed in an edef. Its only drawback is that it can blow the stack if the argument is too long (maybe 256 characters??)



    documentclassarticle
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax#1.ifxrelax#2relax@else,abraux#2relaxfi
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.
    enddocument


    enter image description here



    If that really were an issue, here is an alternative that doesn't have that problem.



    There seems to be a misunderstanding that this definition of abr cannot be placed into an edef. It can. Naturally, the expansion is not necessarily pretty, but it will yield the proper typesetting. The only proviso is that @MyOwnMacro is not used elsewhere in your document.



    documentclassarticle
    usepackage[T1]fontenc
    makeatletter
    let@MyOwnMacrorelax
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax%
    #1.ifxrelax#2relaxdef@MyOwnMacro@elsedef@MyOwnMacro,abraux#2relaxfi%
    @MyOwnMacro%

    makeatother
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.

    Can be edef'ed:

    edeftmpabrOED detokenizeexpandaftertmp

    expands to tmp
    enddocument


    enter image description here






    share|improve this answer














    Here is the simplest form of my original approach. It can be placed in an edef. Its only drawback is that it can blow the stack if the argument is too long (maybe 256 characters??)



    documentclassarticle
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax#1.ifxrelax#2relax@else,abraux#2relaxfi
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.
    enddocument


    enter image description here



    If that really were an issue, here is an alternative that doesn't have that problem.



    There seems to be a misunderstanding that this definition of abr cannot be placed into an edef. It can. Naturally, the expansion is not necessarily pretty, but it will yield the proper typesetting. The only proviso is that @MyOwnMacro is not used elsewhere in your document.



    documentclassarticle
    usepackage[T1]fontenc
    makeatletter
    let@MyOwnMacrorelax
    newcommandabr[1]abraux#1relaxrelax
    defabraux#1#2relax%
    #1.ifxrelax#2relaxdef@MyOwnMacro@elsedef@MyOwnMacro,abraux#2relaxfi%
    @MyOwnMacro%

    makeatother
    begindocument
    Here is abrOED abbreviation.

    Here is abrXO abbreviation.

    Can be edef'ed:

    edeftmpabrOED detokenizeexpandaftertmp

    expands to tmp
    enddocument


    enter image description here







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 8 at 15:31

























    answered Nov 8 at 12:50









    Steven B. Segletes

    151k9189397




    151k9189397







    • 1




      Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
      – Sebastiano
      Nov 8 at 12:51







    • 1




      @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
      – Steven B. Segletes
      Nov 8 at 12:58










    • It can't be edefed if it is used for the first time! It'll throw an error.
      – Skillmon
      Nov 8 at 13:55










    • @Skillmon OK, letnextrelax fixes that.
      – Steven B. Segletes
      Nov 8 at 14:16






    • 2




      @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
      – Skillmon
      Nov 8 at 14:21












    • 1




      Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
      – Sebastiano
      Nov 8 at 12:51







    • 1




      @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
      – Steven B. Segletes
      Nov 8 at 12:58










    • It can't be edefed if it is used for the first time! It'll throw an error.
      – Skillmon
      Nov 8 at 13:55










    • @Skillmon OK, letnextrelax fixes that.
      – Steven B. Segletes
      Nov 8 at 14:16






    • 2




      @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
      – Skillmon
      Nov 8 at 14:21







    1




    1




    Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
    – Sebastiano
    Nov 8 at 12:51





    Cheers to you :-) for your good solution. I have removed my comment. Is it correct in English language?
    – Sebastiano
    Nov 8 at 12:51





    1




    1




    @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
    – Steven B. Segletes
    Nov 8 at 12:58




    @Sebastiano 5:5 (loud and clear). Excellent English. Saluti!
    – Steven B. Segletes
    Nov 8 at 12:58












    It can't be edefed if it is used for the first time! It'll throw an error.
    – Skillmon
    Nov 8 at 13:55




    It can't be edefed if it is used for the first time! It'll throw an error.
    – Skillmon
    Nov 8 at 13:55












    @Skillmon OK, letnextrelax fixes that.
    – Steven B. Segletes
    Nov 8 at 14:16




    @Skillmon OK, letnextrelax fixes that.
    – Steven B. Segletes
    Nov 8 at 14:16




    2




    2




    @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
    – Skillmon
    Nov 8 at 14:21




    @StevenB.Segletes as soon as anything else uses next you'll get problems. In general your macro can't be fully expandable as long as it contains anything changing the definition of anything.
    – Skillmon
    Nov 8 at 14:21










    up vote
    6
    down vote













    Here's a LuaLaTeX-based solution.



    • Cases such as abrOED or abrIMF work just as expected. If the acronym contains both uppercase and lowercase letters, dots are inserted only before the uppercase letters in the interior of the acronym. E.g., abrMSc generates M.,Sc., and abrPhD generates Ph.,D..


    • It can handle mixed-case acronyms such as "PhD" directly -- no need to write abrPhD.


    • If a "slovenly abbreviation" ends a sentence, one should place the "." punctuation mark inside the argument of abr. The code takes care to insert a @ "space factor* directive before the final . character. This, in turn, informs LaTeX that that . character should be treated as ending a sentence.


    • The code returns nothing if the argument of abr is either empty or expands to return nothing. E.g., defttt /abrttt/ returns //. If the code encounters non-letter characters -- say, ( and ) -- no periods are inserted before or after them.


    • The code is expandable in the sense that abr can be included in the argument of an edef directive.


    enter image description here



    documentclassarticle
    usepackageluacode % for 'luacode' environment

    %% Lua-side code:
    beginluacode


    function abr ( s )
    n = string.len ( s )
    -- Do nothing unless "s" is non-empty.
    if n>0 then
    s_mod = "" -- initialize the string

    -- Process the first n-1 characters in "s"
    for i=1, n-1 do
    s12 = string.sub ( s , i, i+1 )
    s1 = string.sub ( s12, 1, 1 )
    if string.match ( s12 , "%a%u" ) then
    s_mod = s_mod .. s1 .. ".\,"
    else
    s_mod = s_mod .. s1
    end
    end

    -- Process the final character in "s"
    s_n = string.sub ( s , n)
    if string.match (s_n, "%.") then -- "." char.
    s_mod = s_mod .. "\@."
    elseif string.match (s_n, "%l") then -- lowercase letter
    s_mod = s_mod .. s_n .. ".\hbox"
    elseif string.match (s_n, "%u") then -- uppercase letter
    s_mod = s_mod .. s_n .. "."
    else -- Any other character:
    s_mod = s_mod .. s_n -- don't add anything after 's_n'
    end


     -- Print the modified string
    tex.sprint ( s_mod )
    end
    end

    endluacode

    %% LaTeX-side code: macro that calls the Lua function
    newcommandabr[2]directluaabr("#1")

    begindocument
    abrOED, abrPhD, abrDPhil, abrMSc, abr()

    smallskip
    % Two calls to "abr" with an empty argument (upon expansion):
    .abr. quad
    defttt .abrttt.

    bigskip
    edeftmpabrMA detokenizeexpandaftertmp

    edeftmpabrMA. detokenizeexpandaftertmp

    expands to: tmp

    smallskip
    edeftmpabrMSc detokenizeexpandaftertmp

    edeftmpabrMSc. detokenizeexpandaftertmp

    expands to: tmp

    bigskip
    Some tests of spacing after punctuation marks:

    smallskip
    a abrPhD candidate --- good

    a Ph.,D. candidate --- just to verify

    smallskip
    an abrMSc candidate --- good

    an M.,Sc. candidate --- just to verify

    smallskip
    She has a abrPhD. So do I. --- good

    She has a Ph.,D@. So do I. --- just to verify

    smallskip
    He has an abrMSc. So do I. --- good

    He has an M.,Sc. So do I. --- just to verify

    smallskip
    Does he have an abrMSc.? Really?! --- good

    Does he have an M.,Sc.? Really?! --- just to verify
    enddocument





    share|improve this answer






















    • I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
      – Toothrot
      Nov 8 at 22:16










    • @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
      – Mico
      Nov 8 at 22:49










    • How about @ifnextchar.spacefactor3000@gobble or something like that?
      – Toothrot
      Nov 8 at 22:55










    • @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
      – Mico
      Nov 9 at 6:11














    up vote
    6
    down vote













    Here's a LuaLaTeX-based solution.



    • Cases such as abrOED or abrIMF work just as expected. If the acronym contains both uppercase and lowercase letters, dots are inserted only before the uppercase letters in the interior of the acronym. E.g., abrMSc generates M.,Sc., and abrPhD generates Ph.,D..


    • It can handle mixed-case acronyms such as "PhD" directly -- no need to write abrPhD.


    • If a "slovenly abbreviation" ends a sentence, one should place the "." punctuation mark inside the argument of abr. The code takes care to insert a @ "space factor* directive before the final . character. This, in turn, informs LaTeX that that . character should be treated as ending a sentence.


    • The code returns nothing if the argument of abr is either empty or expands to return nothing. E.g., defttt /abrttt/ returns //. If the code encounters non-letter characters -- say, ( and ) -- no periods are inserted before or after them.


    • The code is expandable in the sense that abr can be included in the argument of an edef directive.


    enter image description here



    documentclassarticle
    usepackageluacode % for 'luacode' environment

    %% Lua-side code:
    beginluacode


    function abr ( s )
    n = string.len ( s )
    -- Do nothing unless "s" is non-empty.
    if n>0 then
    s_mod = "" -- initialize the string

    -- Process the first n-1 characters in "s"
    for i=1, n-1 do
    s12 = string.sub ( s , i, i+1 )
    s1 = string.sub ( s12, 1, 1 )
    if string.match ( s12 , "%a%u" ) then
    s_mod = s_mod .. s1 .. ".\,"
    else
    s_mod = s_mod .. s1
    end
    end

    -- Process the final character in "s"
    s_n = string.sub ( s , n)
    if string.match (s_n, "%.") then -- "." char.
    s_mod = s_mod .. "\@."
    elseif string.match (s_n, "%l") then -- lowercase letter
    s_mod = s_mod .. s_n .. ".\hbox"
    elseif string.match (s_n, "%u") then -- uppercase letter
    s_mod = s_mod .. s_n .. "."
    else -- Any other character:
    s_mod = s_mod .. s_n -- don't add anything after 's_n'
    end


     -- Print the modified string
    tex.sprint ( s_mod )
    end
    end

    endluacode

    %% LaTeX-side code: macro that calls the Lua function
    newcommandabr[2]directluaabr("#1")

    begindocument
    abrOED, abrPhD, abrDPhil, abrMSc, abr()

    smallskip
    % Two calls to "abr" with an empty argument (upon expansion):
    .abr. quad
    defttt .abrttt.

    bigskip
    edeftmpabrMA detokenizeexpandaftertmp

    edeftmpabrMA. detokenizeexpandaftertmp

    expands to: tmp

    smallskip
    edeftmpabrMSc detokenizeexpandaftertmp

    edeftmpabrMSc. detokenizeexpandaftertmp

    expands to: tmp

    bigskip
    Some tests of spacing after punctuation marks:

    smallskip
    a abrPhD candidate --- good

    a Ph.,D. candidate --- just to verify

    smallskip
    an abrMSc candidate --- good

    an M.,Sc. candidate --- just to verify

    smallskip
    She has a abrPhD. So do I. --- good

    She has a Ph.,D@. So do I. --- just to verify

    smallskip
    He has an abrMSc. So do I. --- good

    He has an M.,Sc. So do I. --- just to verify

    smallskip
    Does he have an abrMSc.? Really?! --- good

    Does he have an M.,Sc.? Really?! --- just to verify
    enddocument





    share|improve this answer






















    • I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
      – Toothrot
      Nov 8 at 22:16










    • @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
      – Mico
      Nov 8 at 22:49










    • How about @ifnextchar.spacefactor3000@gobble or something like that?
      – Toothrot
      Nov 8 at 22:55










    • @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
      – Mico
      Nov 9 at 6:11












    up vote
    6
    down vote










    up vote
    6
    down vote









    Here's a LuaLaTeX-based solution.



    • Cases such as abrOED or abrIMF work just as expected. If the acronym contains both uppercase and lowercase letters, dots are inserted only before the uppercase letters in the interior of the acronym. E.g., abrMSc generates M.,Sc., and abrPhD generates Ph.,D..


    • It can handle mixed-case acronyms such as "PhD" directly -- no need to write abrPhD.


    • If a "slovenly abbreviation" ends a sentence, one should place the "." punctuation mark inside the argument of abr. The code takes care to insert a @ "space factor* directive before the final . character. This, in turn, informs LaTeX that that . character should be treated as ending a sentence.


    • The code returns nothing if the argument of abr is either empty or expands to return nothing. E.g., defttt /abrttt/ returns //. If the code encounters non-letter characters -- say, ( and ) -- no periods are inserted before or after them.


    • The code is expandable in the sense that abr can be included in the argument of an edef directive.


    enter image description here



    documentclassarticle
    usepackageluacode % for 'luacode' environment

    %% Lua-side code:
    beginluacode


    function abr ( s )
    n = string.len ( s )
    -- Do nothing unless "s" is non-empty.
    if n>0 then
    s_mod = "" -- initialize the string

    -- Process the first n-1 characters in "s"
    for i=1, n-1 do
    s12 = string.sub ( s , i, i+1 )
    s1 = string.sub ( s12, 1, 1 )
    if string.match ( s12 , "%a%u" ) then
    s_mod = s_mod .. s1 .. ".\,"
    else
    s_mod = s_mod .. s1
    end
    end

    -- Process the final character in "s"
    s_n = string.sub ( s , n)
    if string.match (s_n, "%.") then -- "." char.
    s_mod = s_mod .. "\@."
    elseif string.match (s_n, "%l") then -- lowercase letter
    s_mod = s_mod .. s_n .. ".\hbox"
    elseif string.match (s_n, "%u") then -- uppercase letter
    s_mod = s_mod .. s_n .. "."
    else -- Any other character:
    s_mod = s_mod .. s_n -- don't add anything after 's_n'
    end


     -- Print the modified string
    tex.sprint ( s_mod )
    end
    end

    endluacode

    %% LaTeX-side code: macro that calls the Lua function
    newcommandabr[2]directluaabr("#1")

    begindocument
    abrOED, abrPhD, abrDPhil, abrMSc, abr()

    smallskip
    % Two calls to "abr" with an empty argument (upon expansion):
    .abr. quad
    defttt .abrttt.

    bigskip
    edeftmpabrMA detokenizeexpandaftertmp

    edeftmpabrMA. detokenizeexpandaftertmp

    expands to: tmp

    smallskip
    edeftmpabrMSc detokenizeexpandaftertmp

    edeftmpabrMSc. detokenizeexpandaftertmp

    expands to: tmp

    bigskip
    Some tests of spacing after punctuation marks:

    smallskip
    a abrPhD candidate --- good

    a Ph.,D. candidate --- just to verify

    smallskip
    an abrMSc candidate --- good

    an M.,Sc. candidate --- just to verify

    smallskip
    She has a abrPhD. So do I. --- good

    She has a Ph.,D@. So do I. --- just to verify

    smallskip
    He has an abrMSc. So do I. --- good

    He has an M.,Sc. So do I. --- just to verify

    smallskip
    Does he have an abrMSc.? Really?! --- good

    Does he have an M.,Sc.? Really?! --- just to verify
    enddocument





    share|improve this answer














    Here's a LuaLaTeX-based solution.



    • Cases such as abrOED or abrIMF work just as expected. If the acronym contains both uppercase and lowercase letters, dots are inserted only before the uppercase letters in the interior of the acronym. E.g., abrMSc generates M.,Sc., and abrPhD generates Ph.,D..


    • It can handle mixed-case acronyms such as "PhD" directly -- no need to write abrPhD.


    • If a "slovenly abbreviation" ends a sentence, one should place the "." punctuation mark inside the argument of abr. The code takes care to insert a @ "space factor* directive before the final . character. This, in turn, informs LaTeX that that . character should be treated as ending a sentence.


    • The code returns nothing if the argument of abr is either empty or expands to return nothing. E.g., defttt /abrttt/ returns //. If the code encounters non-letter characters -- say, ( and ) -- no periods are inserted before or after them.


    • The code is expandable in the sense that abr can be included in the argument of an edef directive.


    enter image description here



    documentclassarticle
    usepackageluacode % for 'luacode' environment

    %% Lua-side code:
    beginluacode


    function abr ( s )
    n = string.len ( s )
    -- Do nothing unless "s" is non-empty.
    if n>0 then
    s_mod = "" -- initialize the string

    -- Process the first n-1 characters in "s"
    for i=1, n-1 do
    s12 = string.sub ( s , i, i+1 )
    s1 = string.sub ( s12, 1, 1 )
    if string.match ( s12 , "%a%u" ) then
    s_mod = s_mod .. s1 .. ".\,"
    else
    s_mod = s_mod .. s1
    end
    end

    -- Process the final character in "s"
    s_n = string.sub ( s , n)
    if string.match (s_n, "%.") then -- "." char.
    s_mod = s_mod .. "\@."
    elseif string.match (s_n, "%l") then -- lowercase letter
    s_mod = s_mod .. s_n .. ".\hbox"
    elseif string.match (s_n, "%u") then -- uppercase letter
    s_mod = s_mod .. s_n .. "."
    else -- Any other character:
    s_mod = s_mod .. s_n -- don't add anything after 's_n'
    end


     -- Print the modified string
    tex.sprint ( s_mod )
    end
    end

    endluacode

    %% LaTeX-side code: macro that calls the Lua function
    newcommandabr[2]directluaabr("#1")

    begindocument
    abrOED, abrPhD, abrDPhil, abrMSc, abr()

    smallskip
    % Two calls to "abr" with an empty argument (upon expansion):
    .abr. quad
    defttt .abrttt.

    bigskip
    edeftmpabrMA detokenizeexpandaftertmp

    edeftmpabrMA. detokenizeexpandaftertmp

    expands to: tmp

    smallskip
    edeftmpabrMSc detokenizeexpandaftertmp

    edeftmpabrMSc. detokenizeexpandaftertmp

    expands to: tmp

    bigskip
    Some tests of spacing after punctuation marks:

    smallskip
    a abrPhD candidate --- good

    a Ph.,D. candidate --- just to verify

    smallskip
    an abrMSc candidate --- good

    an M.,Sc. candidate --- just to verify

    smallskip
    She has a abrPhD. So do I. --- good

    She has a Ph.,D@. So do I. --- just to verify

    smallskip
    He has an abrMSc. So do I. --- good

    He has an M.,Sc. So do I. --- just to verify

    smallskip
    Does he have an abrMSc.? Really?! --- good

    Does he have an M.,Sc.? Really?! --- just to verify
    enddocument






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 9 at 6:12

























    answered Nov 8 at 15:05









    Mico

    269k30364748




    269k30364748











    • I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
      – Toothrot
      Nov 8 at 22:16










    • @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
      – Mico
      Nov 8 at 22:49










    • How about @ifnextchar.spacefactor3000@gobble or something like that?
      – Toothrot
      Nov 8 at 22:55










    • @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
      – Mico
      Nov 9 at 6:11
















    • I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
      – Toothrot
      Nov 8 at 22:16










    • @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
      – Mico
      Nov 8 at 22:49










    • How about @ifnextchar.spacefactor3000@gobble or something like that?
      – Toothrot
      Nov 8 at 22:55










    • @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
      – Mico
      Nov 9 at 6:11















    I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
    – Toothrot
    Nov 8 at 22:16




    I wonder if it weren't more correct to put a sentence-ending point after the macro rather than into the argument, seeing as the full-stop is not part of the abbreviation.
    – Toothrot
    Nov 8 at 22:16












    @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
    – Mico
    Nov 8 at 22:49




    @Toothrot - A major issue is: How does one inform LaTeX whether a sentence ends with a slovenly abbreviation? If one writes I like the abrOED., one ends up with two "dots" -- not good. The only way I can think of indicating reliably to LaTeX that a sentence ends right after some abr... directive is to include the period in the argument of abr. I've come up with an update to the code that allows abbrMSc and abrMSc. to be typeset differently. I'll post the updated code shortly.
    – Mico
    Nov 8 at 22:49












    How about @ifnextchar.spacefactor3000@gobble or something like that?
    – Toothrot
    Nov 8 at 22:55




    How about @ifnextchar.spacefactor3000@gobble or something like that?
    – Toothrot
    Nov 8 at 22:55












    @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
    – Mico
    Nov 9 at 6:11




    @Toothrot - Using @ifnextchar is a potentially interesting idea. I'll have to think about some more; unfortunately, I won't be able to get to work on it until this evening at the earliest. Maybe somebody else will come up with a good solution in the meantime...
    – Mico
    Nov 9 at 6:11










    up vote
    5
    down vote













    Let TeX do the recursion:



    documentclassarticle
    usepackagexparse
    usepackageetoolbox

    robustify, % just in order it doesn't expand in edef

    ExplSyntaxOn
    NewExpandableDocumentCommandabrm

    tl_map_function:fN tl_range:nnn #1 1 -2 __toothrot_abr:n
    tl_range:nnn #1 -1 -1 .

    cs_generate_variant:Nn tl_map_function:nN f
    cs_new:Nn __toothrot_abr:n #1.,
    ExplSyntaxOff

    begindocument

    abrOED

    abrPhD

    edeftestabrOED
    textttmeaningtest

    edeftestabr
    textttmeaningtest

    enddocument


    If a part of the argument is braced, it is considered as a single item.



    One might check whether the argument is empty in order to print nothing at all, but it doesn't seem so important a feature.



    enter image description here



    With tl_range:nnn #1 1 -2 we extract all items but the last; tl_range:nnn #1 -1 -1 extracts the last item.






    share|improve this answer
























      up vote
      5
      down vote













      Let TeX do the recursion:



      documentclassarticle
      usepackagexparse
      usepackageetoolbox

      robustify, % just in order it doesn't expand in edef

      ExplSyntaxOn
      NewExpandableDocumentCommandabrm

      tl_map_function:fN tl_range:nnn #1 1 -2 __toothrot_abr:n
      tl_range:nnn #1 -1 -1 .

      cs_generate_variant:Nn tl_map_function:nN f
      cs_new:Nn __toothrot_abr:n #1.,
      ExplSyntaxOff

      begindocument

      abrOED

      abrPhD

      edeftestabrOED
      textttmeaningtest

      edeftestabr
      textttmeaningtest

      enddocument


      If a part of the argument is braced, it is considered as a single item.



      One might check whether the argument is empty in order to print nothing at all, but it doesn't seem so important a feature.



      enter image description here



      With tl_range:nnn #1 1 -2 we extract all items but the last; tl_range:nnn #1 -1 -1 extracts the last item.






      share|improve this answer






















        up vote
        5
        down vote










        up vote
        5
        down vote









        Let TeX do the recursion:



        documentclassarticle
        usepackagexparse
        usepackageetoolbox

        robustify, % just in order it doesn't expand in edef

        ExplSyntaxOn
        NewExpandableDocumentCommandabrm

        tl_map_function:fN tl_range:nnn #1 1 -2 __toothrot_abr:n
        tl_range:nnn #1 -1 -1 .

        cs_generate_variant:Nn tl_map_function:nN f
        cs_new:Nn __toothrot_abr:n #1.,
        ExplSyntaxOff

        begindocument

        abrOED

        abrPhD

        edeftestabrOED
        textttmeaningtest

        edeftestabr
        textttmeaningtest

        enddocument


        If a part of the argument is braced, it is considered as a single item.



        One might check whether the argument is empty in order to print nothing at all, but it doesn't seem so important a feature.



        enter image description here



        With tl_range:nnn #1 1 -2 we extract all items but the last; tl_range:nnn #1 -1 -1 extracts the last item.






        share|improve this answer












        Let TeX do the recursion:



        documentclassarticle
        usepackagexparse
        usepackageetoolbox

        robustify, % just in order it doesn't expand in edef

        ExplSyntaxOn
        NewExpandableDocumentCommandabrm

        tl_map_function:fN tl_range:nnn #1 1 -2 __toothrot_abr:n
        tl_range:nnn #1 -1 -1 .

        cs_generate_variant:Nn tl_map_function:nN f
        cs_new:Nn __toothrot_abr:n #1.,
        ExplSyntaxOff

        begindocument

        abrOED

        abrPhD

        edeftestabrOED
        textttmeaningtest

        edeftestabr
        textttmeaningtest

        enddocument


        If a part of the argument is braced, it is considered as a single item.



        One might check whether the argument is empty in order to print nothing at all, but it doesn't seem so important a feature.



        enter image description here



        With tl_range:nnn #1 1 -2 we extract all items but the last; tl_range:nnn #1 -1 -1 extracts the last item.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 8 at 13:25









        egreg

        697k8518513117




        697k8518513117




















            up vote
            5
            down vote













            documentclassarticle
            usepackagexinttools
            newcommandabr[1]xintListWithSep.,#1.
            begindocument
            I've seen it in the abrOED.

            I got my abrPhD.
            enddocument


            enter image description here



            Updated (à la Mico, but without LuaLaTeX)



            The syntax here is to use abrPhD. for example at end of a sentence, and abrPhD if not at end of a sentence.



            documentclassarticle
            usepackagexinttools
            makeatletter
            newcommandabr[1]
            expandafter@gobbletworomannumeral0xintapplyunbracedabr@aux#1.@
            defabr@sep.,
            defabr@aux#1if.#1expandafterabr@end
            else
            if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterexpandafterexpandafterabr@sep
            fi
            fi#1%
            defabr@end. abr@@end
            defabr@@end.@@.
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            just insert a dot in the verb|abr| argument: abrOED. It ended a
            sentence and in non-French spacing mode, TeX inserted the extra
            space.

            textttWe can see it better with monospace font: abrOED. See?

            I got my abrPhD and even my abrPhilD, leniency ruled
            in those days.

            textttThe dots are added in a smart way: abrAaaaBbbbCccc. But it is
            assumed that the first letter is abrUppercased. That's it.

            textttNotice that neitger abrAaaa nor abrAaA trigger an end of
            sentence spacing after the dot, which is abrGood. Isn't it?
            enddocument


            enter image description here



            Again updated, for automatic end of sentence dot detection after abbreviation



            Here an end of sentence dot will be detected automatically.



            Of course we can't use @ifnextchar for that, as it swallows spaces.



            I added some comments about expandability, which seems to have drawn great attention in other answers :).



            documentclassarticle
            usepackageshortvrbMakeShortVerb
            usepackagexinttools

            makeatletter
            protecteddefabrsep.,% maybe redefined even after edeffooabrDPhil...
            protecteddefabrendfuturelet@let@tokenabr@end
            defabr@endifx.@let@token@else.@fi
            newcommandabr[1]
            expandafter@gobbleromannumeral0xintapplyunbracedabr@aux#1abrend
            defabr@aux#1if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterabr@sep
            fi#1%
            defabr@sep abrsep
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            it will detect it automatically: abrOED. There was no double dot.
            Besides, TeX applied its end of sentence extra space.

            textttWe can see it better with monospace font: abrOED. See?

            textttWe can see it better with monospace font: abrOED, See?

            I got a abrMSc, a abrPhD and even a abrDPhil. Leniency ruled
            in those days.

            The abbreviation dots are added in a smart way, after the last
            lowercase letter following an uppercase letter:
            abrAaaaBbbbCccc. But it is emphassumed that the first letter is
            abrUppercased. That's it.

            textttNotice that neither abrDPhil nor abrPhilD get TeX to
            consider the inserted final dot as signaling an end of
            sentence spacing after the dot, which is abrGood. Isn't it?

            About expandability, the correct way for LaTeX2e's users would be to use
            |protected@edef|, not a naked |edef|; although nowadays some
            LaTeX2e users have heard about |edef|, they might not know
            about |protected@edef|, which requires a cumbersome extra
            |makeatletter| for its usage. Anyway, none of that is described in
            textscLamport book, so I wonder if LaTeX2e users are really
            emphallowed into using |edef| to start with.

            But as it seems they know about |edef|, we as macro programmers need
            better to use the e-TeX's |protected| prefix and not the LaTeX2e
            |DeclareRobustCommand|, because users will not do |protected@edef|.

            This is what I have done here for a macro |abrsep| (why haven't we all
            used |abbr| by the way?) which is deliberately |protected|,
            allowing it to be redefined at location of use, long after some macro
            will have been defined via |edeffooabrABCDEFGH|.

            edeffooabrABCDEFGHtextttstringfoo is meaningfoo

            edeffooabrAaaBccCcctextttstringfoo is meaningfoo

            The |abrend| is also |protected|, anyway as its expansion will be
            context dependent (it detects if a dot follows), it had to not expand
            in the |edef|.
            enddocument


            enter image description here



            Notice that my proposals v2 and v3 will work only with ascii uppercase letters, no diacritics.






            share|improve this answer






















            • @Mico I plagiarized your input syntax for end of sentence...
              – jfbu
              Nov 8 at 17:07






            • 1




              @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
              – jfbu
              Nov 9 at 8:21










            • Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
              – Mico
              Nov 9 at 8:39










            • (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
              – jfbu
              Nov 9 at 9:47















            up vote
            5
            down vote













            documentclassarticle
            usepackagexinttools
            newcommandabr[1]xintListWithSep.,#1.
            begindocument
            I've seen it in the abrOED.

            I got my abrPhD.
            enddocument


            enter image description here



            Updated (à la Mico, but without LuaLaTeX)



            The syntax here is to use abrPhD. for example at end of a sentence, and abrPhD if not at end of a sentence.



            documentclassarticle
            usepackagexinttools
            makeatletter
            newcommandabr[1]
            expandafter@gobbletworomannumeral0xintapplyunbracedabr@aux#1.@
            defabr@sep.,
            defabr@aux#1if.#1expandafterabr@end
            else
            if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterexpandafterexpandafterabr@sep
            fi
            fi#1%
            defabr@end. abr@@end
            defabr@@end.@@.
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            just insert a dot in the verb|abr| argument: abrOED. It ended a
            sentence and in non-French spacing mode, TeX inserted the extra
            space.

            textttWe can see it better with monospace font: abrOED. See?

            I got my abrPhD and even my abrPhilD, leniency ruled
            in those days.

            textttThe dots are added in a smart way: abrAaaaBbbbCccc. But it is
            assumed that the first letter is abrUppercased. That's it.

            textttNotice that neitger abrAaaa nor abrAaA trigger an end of
            sentence spacing after the dot, which is abrGood. Isn't it?
            enddocument


            enter image description here



            Again updated, for automatic end of sentence dot detection after abbreviation



            Here an end of sentence dot will be detected automatically.



            Of course we can't use @ifnextchar for that, as it swallows spaces.



            I added some comments about expandability, which seems to have drawn great attention in other answers :).



            documentclassarticle
            usepackageshortvrbMakeShortVerb
            usepackagexinttools

            makeatletter
            protecteddefabrsep.,% maybe redefined even after edeffooabrDPhil...
            protecteddefabrendfuturelet@let@tokenabr@end
            defabr@endifx.@let@token@else.@fi
            newcommandabr[1]
            expandafter@gobbleromannumeral0xintapplyunbracedabr@aux#1abrend
            defabr@aux#1if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterabr@sep
            fi#1%
            defabr@sep abrsep
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            it will detect it automatically: abrOED. There was no double dot.
            Besides, TeX applied its end of sentence extra space.

            textttWe can see it better with monospace font: abrOED. See?

            textttWe can see it better with monospace font: abrOED, See?

            I got a abrMSc, a abrPhD and even a abrDPhil. Leniency ruled
            in those days.

            The abbreviation dots are added in a smart way, after the last
            lowercase letter following an uppercase letter:
            abrAaaaBbbbCccc. But it is emphassumed that the first letter is
            abrUppercased. That's it.

            textttNotice that neither abrDPhil nor abrPhilD get TeX to
            consider the inserted final dot as signaling an end of
            sentence spacing after the dot, which is abrGood. Isn't it?

            About expandability, the correct way for LaTeX2e's users would be to use
            |protected@edef|, not a naked |edef|; although nowadays some
            LaTeX2e users have heard about |edef|, they might not know
            about |protected@edef|, which requires a cumbersome extra
            |makeatletter| for its usage. Anyway, none of that is described in
            textscLamport book, so I wonder if LaTeX2e users are really
            emphallowed into using |edef| to start with.

            But as it seems they know about |edef|, we as macro programmers need
            better to use the e-TeX's |protected| prefix and not the LaTeX2e
            |DeclareRobustCommand|, because users will not do |protected@edef|.

            This is what I have done here for a macro |abrsep| (why haven't we all
            used |abbr| by the way?) which is deliberately |protected|,
            allowing it to be redefined at location of use, long after some macro
            will have been defined via |edeffooabrABCDEFGH|.

            edeffooabrABCDEFGHtextttstringfoo is meaningfoo

            edeffooabrAaaBccCcctextttstringfoo is meaningfoo

            The |abrend| is also |protected|, anyway as its expansion will be
            context dependent (it detects if a dot follows), it had to not expand
            in the |edef|.
            enddocument


            enter image description here



            Notice that my proposals v2 and v3 will work only with ascii uppercase letters, no diacritics.






            share|improve this answer






















            • @Mico I plagiarized your input syntax for end of sentence...
              – jfbu
              Nov 8 at 17:07






            • 1




              @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
              – jfbu
              Nov 9 at 8:21










            • Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
              – Mico
              Nov 9 at 8:39










            • (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
              – jfbu
              Nov 9 at 9:47













            up vote
            5
            down vote










            up vote
            5
            down vote









            documentclassarticle
            usepackagexinttools
            newcommandabr[1]xintListWithSep.,#1.
            begindocument
            I've seen it in the abrOED.

            I got my abrPhD.
            enddocument


            enter image description here



            Updated (à la Mico, but without LuaLaTeX)



            The syntax here is to use abrPhD. for example at end of a sentence, and abrPhD if not at end of a sentence.



            documentclassarticle
            usepackagexinttools
            makeatletter
            newcommandabr[1]
            expandafter@gobbletworomannumeral0xintapplyunbracedabr@aux#1.@
            defabr@sep.,
            defabr@aux#1if.#1expandafterabr@end
            else
            if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterexpandafterexpandafterabr@sep
            fi
            fi#1%
            defabr@end. abr@@end
            defabr@@end.@@.
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            just insert a dot in the verb|abr| argument: abrOED. It ended a
            sentence and in non-French spacing mode, TeX inserted the extra
            space.

            textttWe can see it better with monospace font: abrOED. See?

            I got my abrPhD and even my abrPhilD, leniency ruled
            in those days.

            textttThe dots are added in a smart way: abrAaaaBbbbCccc. But it is
            assumed that the first letter is abrUppercased. That's it.

            textttNotice that neitger abrAaaa nor abrAaA trigger an end of
            sentence spacing after the dot, which is abrGood. Isn't it?
            enddocument


            enter image description here



            Again updated, for automatic end of sentence dot detection after abbreviation



            Here an end of sentence dot will be detected automatically.



            Of course we can't use @ifnextchar for that, as it swallows spaces.



            I added some comments about expandability, which seems to have drawn great attention in other answers :).



            documentclassarticle
            usepackageshortvrbMakeShortVerb
            usepackagexinttools

            makeatletter
            protecteddefabrsep.,% maybe redefined even after edeffooabrDPhil...
            protecteddefabrendfuturelet@let@tokenabr@end
            defabr@endifx.@let@token@else.@fi
            newcommandabr[1]
            expandafter@gobbleromannumeral0xintapplyunbracedabr@aux#1abrend
            defabr@aux#1if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterabr@sep
            fi#1%
            defabr@sep abrsep
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            it will detect it automatically: abrOED. There was no double dot.
            Besides, TeX applied its end of sentence extra space.

            textttWe can see it better with monospace font: abrOED. See?

            textttWe can see it better with monospace font: abrOED, See?

            I got a abrMSc, a abrPhD and even a abrDPhil. Leniency ruled
            in those days.

            The abbreviation dots are added in a smart way, after the last
            lowercase letter following an uppercase letter:
            abrAaaaBbbbCccc. But it is emphassumed that the first letter is
            abrUppercased. That's it.

            textttNotice that neither abrDPhil nor abrPhilD get TeX to
            consider the inserted final dot as signaling an end of
            sentence spacing after the dot, which is abrGood. Isn't it?

            About expandability, the correct way for LaTeX2e's users would be to use
            |protected@edef|, not a naked |edef|; although nowadays some
            LaTeX2e users have heard about |edef|, they might not know
            about |protected@edef|, which requires a cumbersome extra
            |makeatletter| for its usage. Anyway, none of that is described in
            textscLamport book, so I wonder if LaTeX2e users are really
            emphallowed into using |edef| to start with.

            But as it seems they know about |edef|, we as macro programmers need
            better to use the e-TeX's |protected| prefix and not the LaTeX2e
            |DeclareRobustCommand|, because users will not do |protected@edef|.

            This is what I have done here for a macro |abrsep| (why haven't we all
            used |abbr| by the way?) which is deliberately |protected|,
            allowing it to be redefined at location of use, long after some macro
            will have been defined via |edeffooabrABCDEFGH|.

            edeffooabrABCDEFGHtextttstringfoo is meaningfoo

            edeffooabrAaaBccCcctextttstringfoo is meaningfoo

            The |abrend| is also |protected|, anyway as its expansion will be
            context dependent (it detects if a dot follows), it had to not expand
            in the |edef|.
            enddocument


            enter image description here



            Notice that my proposals v2 and v3 will work only with ascii uppercase letters, no diacritics.






            share|improve this answer














            documentclassarticle
            usepackagexinttools
            newcommandabr[1]xintListWithSep.,#1.
            begindocument
            I've seen it in the abrOED.

            I got my abrPhD.
            enddocument


            enter image description here



            Updated (à la Mico, but without LuaLaTeX)



            The syntax here is to use abrPhD. for example at end of a sentence, and abrPhD if not at end of a sentence.



            documentclassarticle
            usepackagexinttools
            makeatletter
            newcommandabr[1]
            expandafter@gobbletworomannumeral0xintapplyunbracedabr@aux#1.@
            defabr@sep.,
            defabr@aux#1if.#1expandafterabr@end
            else
            if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterexpandafterexpandafterabr@sep
            fi
            fi#1%
            defabr@end. abr@@end
            defabr@@end.@@.
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            just insert a dot in the verb|abr| argument: abrOED. It ended a
            sentence and in non-French spacing mode, TeX inserted the extra
            space.

            textttWe can see it better with monospace font: abrOED. See?

            I got my abrPhD and even my abrPhilD, leniency ruled
            in those days.

            textttThe dots are added in a smart way: abrAaaaBbbbCccc. But it is
            assumed that the first letter is abrUppercased. That's it.

            textttNotice that neitger abrAaaa nor abrAaA trigger an end of
            sentence spacing after the dot, which is abrGood. Isn't it?
            enddocument


            enter image description here



            Again updated, for automatic end of sentence dot detection after abbreviation



            Here an end of sentence dot will be detected automatically.



            Of course we can't use @ifnextchar for that, as it swallows spaces.



            I added some comments about expandability, which seems to have drawn great attention in other answers :).



            documentclassarticle
            usepackageshortvrbMakeShortVerb
            usepackagexinttools

            makeatletter
            protecteddefabrsep.,% maybe redefined even after edeffooabrDPhil...
            protecteddefabrendfuturelet@let@tokenabr@end
            defabr@endifx.@let@token@else.@fi
            newcommandabr[1]
            expandafter@gobbleromannumeral0xintapplyunbracedabr@aux#1abrend
            defabr@aux#1if1ifnum`#1<`A 0fiifnum`#1>`Z 0fi1%
            expandafterabr@sep
            fi#1%
            defabr@sep abrsep
            makeatother

            begindocument%ttfamily
            I've seen it in the abrOED, and if located at end of a sentence
            it will detect it automatically: abrOED. There was no double dot.
            Besides, TeX applied its end of sentence extra space.

            textttWe can see it better with monospace font: abrOED. See?

            textttWe can see it better with monospace font: abrOED, See?

            I got a abrMSc, a abrPhD and even a abrDPhil. Leniency ruled
            in those days.

            The abbreviation dots are added in a smart way, after the last
            lowercase letter following an uppercase letter:
            abrAaaaBbbbCccc. But it is emphassumed that the first letter is
            abrUppercased. That's it.

            textttNotice that neither abrDPhil nor abrPhilD get TeX to
            consider the inserted final dot as signaling an end of
            sentence spacing after the dot, which is abrGood. Isn't it?

            About expandability, the correct way for LaTeX2e's users would be to use
            |protected@edef|, not a naked |edef|; although nowadays some
            LaTeX2e users have heard about |edef|, they might not know
            about |protected@edef|, which requires a cumbersome extra
            |makeatletter| for its usage. Anyway, none of that is described in
            textscLamport book, so I wonder if LaTeX2e users are really
            emphallowed into using |edef| to start with.

            But as it seems they know about |edef|, we as macro programmers need
            better to use the e-TeX's |protected| prefix and not the LaTeX2e
            |DeclareRobustCommand|, because users will not do |protected@edef|.

            This is what I have done here for a macro |abrsep| (why haven't we all
            used |abbr| by the way?) which is deliberately |protected|,
            allowing it to be redefined at location of use, long after some macro
            will have been defined via |edeffooabrABCDEFGH|.

            edeffooabrABCDEFGHtextttstringfoo is meaningfoo

            edeffooabrAaaBccCcctextttstringfoo is meaningfoo

            The |abrend| is also |protected|, anyway as its expansion will be
            context dependent (it detects if a dot follows), it had to not expand
            in the |edef|.
            enddocument


            enter image description here



            Notice that my proposals v2 and v3 will work only with ascii uppercase letters, no diacritics.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 9 at 8:16

























            answered Nov 8 at 13:35









            jfbu

            44.3k65143




            44.3k65143











            • @Mico I plagiarized your input syntax for end of sentence...
              – jfbu
              Nov 8 at 17:07






            • 1




              @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
              – jfbu
              Nov 9 at 8:21










            • Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
              – Mico
              Nov 9 at 8:39










            • (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
              – jfbu
              Nov 9 at 9:47

















            • @Mico I plagiarized your input syntax for end of sentence...
              – jfbu
              Nov 8 at 17:07






            • 1




              @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
              – jfbu
              Nov 9 at 8:21










            • Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
              – Mico
              Nov 9 at 8:39










            • (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
              – jfbu
              Nov 9 at 9:47
















            @Mico I plagiarized your input syntax for end of sentence...
            – jfbu
            Nov 8 at 17:07




            @Mico I plagiarized your input syntax for end of sentence...
            – jfbu
            Nov 8 at 17:07




            1




            1




            @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
            – jfbu
            Nov 9 at 8:21




            @Mico I have again updated as I read OP is pushing towards automatic dot detection. One can not use LaTeX @ifnextchar which swallows spaces.
            – jfbu
            Nov 9 at 8:21












            Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
            – Mico
            Nov 9 at 8:39




            Outstanding! :-) Incidentally, I've gone ahead and deleted my earlier comments are they're no longer relevant, or even understandable, for readers of the current version of your answer.
            – Mico
            Nov 9 at 8:39












            (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
            – jfbu
            Nov 9 at 9:47





            (not to be told publicly: of course I could remove all usage of xinttools but where is the fun without it?) well, in fact usage of a an xinttools macro facilitates a fixed number of expansion steps to get final result, here 3 steps, I could reduce to 2 steps. But doesn't matter for an edef and anyhow the tokens of the input are subjected to full-first expansion via ifnum test etc...
            – jfbu
            Nov 9 at 9:47











            up vote
            4
            down vote













            documentclassarticle
            newcommandabr[1]abraux#1..
            defabraux#1#2#3%
            #1%
            ifnum`#2>91relax% we have a lowercase letter following
            defnextabraux#2#3%
            else
            .ifx.#2defnext@else,defnextabraux#2#3fi
            fi
            next

            begindocument
            Here is abrOED abbreviation.

            Here is abrXO abbreviation.

            Here is abrXOOED abbreviation.

            abrMSc

            abrDPhil
            enddocument


            enter image description here






            share|improve this answer






















            • Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
              – Mico
              Nov 9 at 6:20






            • 1




              Sure, if it is not an uppercase letter then go the next char.
              – Herbert
              Nov 9 at 19:02














            up vote
            4
            down vote













            documentclassarticle
            newcommandabr[1]abraux#1..
            defabraux#1#2#3%
            #1%
            ifnum`#2>91relax% we have a lowercase letter following
            defnextabraux#2#3%
            else
            .ifx.#2defnext@else,defnextabraux#2#3fi
            fi
            next

            begindocument
            Here is abrOED abbreviation.

            Here is abrXO abbreviation.

            Here is abrXOOED abbreviation.

            abrMSc

            abrDPhil
            enddocument


            enter image description here






            share|improve this answer






















            • Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
              – Mico
              Nov 9 at 6:20






            • 1




              Sure, if it is not an uppercase letter then go the next char.
              – Herbert
              Nov 9 at 19:02












            up vote
            4
            down vote










            up vote
            4
            down vote









            documentclassarticle
            newcommandabr[1]abraux#1..
            defabraux#1#2#3%
            #1%
            ifnum`#2>91relax% we have a lowercase letter following
            defnextabraux#2#3%
            else
            .ifx.#2defnext@else,defnextabraux#2#3fi
            fi
            next

            begindocument
            Here is abrOED abbreviation.

            Here is abrXO abbreviation.

            Here is abrXOOED abbreviation.

            abrMSc

            abrDPhil
            enddocument


            enter image description here






            share|improve this answer














            documentclassarticle
            newcommandabr[1]abraux#1..
            defabraux#1#2#3%
            #1%
            ifnum`#2>91relax% we have a lowercase letter following
            defnextabraux#2#3%
            else
            .ifx.#2defnext@else,defnextabraux#2#3fi
            fi
            next

            begindocument
            Here is abrOED abbreviation.

            Here is abrXO abbreviation.

            Here is abrXOOED abbreviation.

            abrMSc

            abrDPhil
            enddocument


            enter image description here







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 10 at 8:32

























            answered Nov 8 at 12:58









            Herbert

            264k23400712




            264k23400712











            • Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
              – Mico
              Nov 9 at 6:20






            • 1




              Sure, if it is not an uppercase letter then go the next char.
              – Herbert
              Nov 9 at 19:02
















            • Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
              – Mico
              Nov 9 at 6:20






            • 1




              Sure, if it is not an uppercase letter then go the next char.
              – Herbert
              Nov 9 at 19:02















            Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
            – Mico
            Nov 9 at 6:20




            Can your code be extended to handle the lazy/slovenly punctuation of MSc (correct: M.,Sc.) and DPhil (correct: D.,Phil.)?
            – Mico
            Nov 9 at 6:20




            1




            1




            Sure, if it is not an uppercase letter then go the next char.
            – Herbert
            Nov 9 at 19:02




            Sure, if it is not an uppercase letter then go the next char.
            – Herbert
            Nov 9 at 19:02

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f458975%2frespectable-abbreviations-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 do I collapse sections of code in Visual Studio Code for Windows?

            ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ