What is the difference between somecmd and csname somecmdendcsname?












3















This is a demo



documentclass{article}
usepackage{soul}
makeatletter
newcommand{mydef}[2]{%
expandafterdefcsname my#1endcsname {#2}
}
newcommand{mygetdef}[1]{%
ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
}
makeatother

deftest{some text to complete}
mydef{xxx}{some text to complete}

begin{document}
ultest % it works
%%%% if uncomment, the below one does not work, an error is reported
% ulmygetdef{xxx}
end{document}


As the comment says, if ulmygetdef{xxx} takes place, there comes a error:



! Argument of SOUL@@ has an extra }.



UPDATE:



I switch to package ulem where uline can underline fbox.
Everything works (see MWE below).
Then I try to make colorful box.
However, I find that once I include package xcolor or tcolorbox (as the comment in MWE), some weird error comes up immediately even before I actually use them in the document.



documentclass{article}
%%% uncomment either of the packages below, it reports errors.
%usepackage{xcolor}
%usepackage{tcolorbox}

usepackage[normalem]{ulem}
makeatletter
newcommand{mydef}[2]{%
expandafterdefcsname my#1endcsname {#2}
}
newcommand{mygetdef}[1]{%
ifcsname my#1endcsname csname my#1endcsname else protectfbox{#1} fi%
}

deftest{some text to complete}
mydef{xxx}{some text to complete}

begin{document}
uline{test}

edefmytmp{mygetdef{xxx}}
uline{mytmp}

edefmytmp{mygetdef{yyy}}
uline{mytmp}

end{document}


After all my efforts, I can not figure out why and solve it.
So I updated my original problem.










share|improve this question





























    3















    This is a demo



    documentclass{article}
    usepackage{soul}
    makeatletter
    newcommand{mydef}[2]{%
    expandafterdefcsname my#1endcsname {#2}
    }
    newcommand{mygetdef}[1]{%
    ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
    }
    makeatother

    deftest{some text to complete}
    mydef{xxx}{some text to complete}

    begin{document}
    ultest % it works
    %%%% if uncomment, the below one does not work, an error is reported
    % ulmygetdef{xxx}
    end{document}


    As the comment says, if ulmygetdef{xxx} takes place, there comes a error:



    ! Argument of SOUL@@ has an extra }.



    UPDATE:



    I switch to package ulem where uline can underline fbox.
    Everything works (see MWE below).
    Then I try to make colorful box.
    However, I find that once I include package xcolor or tcolorbox (as the comment in MWE), some weird error comes up immediately even before I actually use them in the document.



    documentclass{article}
    %%% uncomment either of the packages below, it reports errors.
    %usepackage{xcolor}
    %usepackage{tcolorbox}

    usepackage[normalem]{ulem}
    makeatletter
    newcommand{mydef}[2]{%
    expandafterdefcsname my#1endcsname {#2}
    }
    newcommand{mygetdef}[1]{%
    ifcsname my#1endcsname csname my#1endcsname else protectfbox{#1} fi%
    }

    deftest{some text to complete}
    mydef{xxx}{some text to complete}

    begin{document}
    uline{test}

    edefmytmp{mygetdef{xxx}}
    uline{mytmp}

    edefmytmp{mygetdef{yyy}}
    uline{mytmp}

    end{document}


    After all my efforts, I can not figure out why and solve it.
    So I updated my original problem.










    share|improve this question



























      3












      3








      3








      This is a demo



      documentclass{article}
      usepackage{soul}
      makeatletter
      newcommand{mydef}[2]{%
      expandafterdefcsname my#1endcsname {#2}
      }
      newcommand{mygetdef}[1]{%
      ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
      }
      makeatother

      deftest{some text to complete}
      mydef{xxx}{some text to complete}

      begin{document}
      ultest % it works
      %%%% if uncomment, the below one does not work, an error is reported
      % ulmygetdef{xxx}
      end{document}


      As the comment says, if ulmygetdef{xxx} takes place, there comes a error:



      ! Argument of SOUL@@ has an extra }.



      UPDATE:



      I switch to package ulem where uline can underline fbox.
      Everything works (see MWE below).
      Then I try to make colorful box.
      However, I find that once I include package xcolor or tcolorbox (as the comment in MWE), some weird error comes up immediately even before I actually use them in the document.



      documentclass{article}
      %%% uncomment either of the packages below, it reports errors.
      %usepackage{xcolor}
      %usepackage{tcolorbox}

      usepackage[normalem]{ulem}
      makeatletter
      newcommand{mydef}[2]{%
      expandafterdefcsname my#1endcsname {#2}
      }
      newcommand{mygetdef}[1]{%
      ifcsname my#1endcsname csname my#1endcsname else protectfbox{#1} fi%
      }

      deftest{some text to complete}
      mydef{xxx}{some text to complete}

      begin{document}
      uline{test}

      edefmytmp{mygetdef{xxx}}
      uline{mytmp}

      edefmytmp{mygetdef{yyy}}
      uline{mytmp}

      end{document}


      After all my efforts, I can not figure out why and solve it.
      So I updated my original problem.










      share|improve this question
















      This is a demo



      documentclass{article}
      usepackage{soul}
      makeatletter
      newcommand{mydef}[2]{%
      expandafterdefcsname my#1endcsname {#2}
      }
      newcommand{mygetdef}[1]{%
      ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
      }
      makeatother

      deftest{some text to complete}
      mydef{xxx}{some text to complete}

      begin{document}
      ultest % it works
      %%%% if uncomment, the below one does not work, an error is reported
      % ulmygetdef{xxx}
      end{document}


      As the comment says, if ulmygetdef{xxx} takes place, there comes a error:



      ! Argument of SOUL@@ has an extra }.



      UPDATE:



      I switch to package ulem where uline can underline fbox.
      Everything works (see MWE below).
      Then I try to make colorful box.
      However, I find that once I include package xcolor or tcolorbox (as the comment in MWE), some weird error comes up immediately even before I actually use them in the document.



      documentclass{article}
      %%% uncomment either of the packages below, it reports errors.
      %usepackage{xcolor}
      %usepackage{tcolorbox}

      usepackage[normalem]{ulem}
      makeatletter
      newcommand{mydef}[2]{%
      expandafterdefcsname my#1endcsname {#2}
      }
      newcommand{mygetdef}[1]{%
      ifcsname my#1endcsname csname my#1endcsname else protectfbox{#1} fi%
      }

      deftest{some text to complete}
      mydef{xxx}{some text to complete}

      begin{document}
      uline{test}

      edefmytmp{mygetdef{xxx}}
      uline{mytmp}

      edefmytmp{mygetdef{yyy}}
      uline{mytmp}

      end{document}


      After all my efforts, I can not figure out why and solve it.
      So I updated my original problem.







      soul csname






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 23 at 14:01







      jiewuza

















      asked Mar 23 at 1:31









      jiewuzajiewuza

      916




      916






















          2 Answers
          2






          active

          oldest

          votes


















          2














          Try



          edeftmp{mygetdef{xxx}}
          ultmp


          The mygetdef needs to be expanded before being passed to ul.



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
          }
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works
          %%%% if uncomment, the below one does not work, an error is reported
          % ulmygetdef{xxx}

          edeftmp{mygetdef{xxx}}
          ultmp
          end{document}


          enter image description here





          SUPPLEMENTAL NOTE TO OP



          Not really to answer OP question, but in reply to some of his comments to this answer:



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else
          #1 not defined fi%
          }
          newcommand{myulgetdef}[1]{%
          ifcsname my#1endcsname expandafterul{csname my#1endcsname}%
          elsefbox{#1 not defined} fi%
          }
          newcommand{myxgetdef}[1]{%
          ifcsname my#1endcsname expandaftercsname my#1endcsname%
          elseprotectprotectprotectfbox{#1 not defined} fi%
          }
          newcommandexul[1]{edeftmp{#1}ultmp}
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works

          exul{mygetdef{xxx}}

          1. mygetdef{yyy}

          2. myulgetdef{yyy}

          3. myxgetdef{yyy}

          4. exul{mygetdef{yyy}}

          5. exul{myxgetdef{yyy}}% HOWEVER, fbox IS NOT UNDERLINED

          %6. exul{myulgetdef{yyy}}% FAILS; CANNOT ul{fbox{...}}

          end{document}


          enter image description here






          share|improve this answer


























          • Is there any way putting edef part in mygetdef to make it work?

            – jiewuza
            Mar 23 at 3:01











          • @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

            – Steven B. Segletes
            Mar 23 at 3:07











          • Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

            – jiewuza
            Mar 23 at 4:00











          • I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

            – jiewuza
            Mar 23 at 4:26











          • @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

            – Steven B. Segletes
            Mar 23 at 4:58



















          3














          The command ul is defined as SOUL@ulsetupSOUL@. The first command sets up some commands that will be later delivered after a group has started and is of no concern here.



          The macro SOUL@ is defined as



          % soul.sty, line 99:
          defSOUL@{%
          futureletSOUL@@SOUL@expand
          }


          which means that the following token is looked up and stored in SOUL@@; then SOUL@expand is executed



          % soul.sty, line 102:
          defSOUL@expand{%
          ifcatbgroupnoexpandSOUL@@
          letSOUL@nSOUL@start
          else
          bgroup
          def\##1##2{def##2{noexpand##2}}%
          theSOUL@cmds
          SOUL@buffer={%
          \TeX\LaTeX\soulomit\mbox\hbox\textregistered
          \slash\textcircled\copyright\S\,\<\>\~%
          \\%
          }%
          def\##1{def##1{noexpand##1}}%
          theSOUL@buffer
          letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%
          egroup
          fi
          SOUL@n
          }


          Quite a mouthful! The behavior depends on whether the token stored in SOUL@@ is a left brace or not. In your case it isn't.



          The part of the code above which is of primary interest is



                      letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%


          Note that SOUL@@ is the token found at the first step, in your case mygetdef. At the end, SOUL@n is executed, which discards the next token (your mygetdef) and does



          SOUL@start{<full expansion of mygetdef`>}


          The place where the error happens is at the xdef, because mygetdef does not find its argument, but just the closing brace. What you want is that



          ulmygetdef{xxx}


          becomes



          ulmyxxx


          You need to do some clever expansion for this, but it becomes very awkward, mainly because of the conditionals. If you do



          expandafterulmyxxx


          you get



          ulifcsname myxxxendcsnamecsname myxxxendcsnameelse xxx not defined fi


          With three expandafters



          ulcsname myxxxendcsnameelse xxx not defined fi


          With seven expandafters



          ulmyxxxelse xxx not defined fi


          That's it! Let's see what happens with mygetdef{noway} (assuming it's undefined). You'd get



          ul noway not defined fi


          which is not really what you want, but can be easily fixed.



          documentclass{article}
          usepackage{soul}

          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname{#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname
          csname my#1endcsname
          else
          {}#1 not defined%
          fi
          }

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}

          ultest

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{xxx}

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{noway}

          end{document}


          enter image description here



          My proposal is to define differently mygetdef, if you plan to use it after soul macros, but not only.



          documentclass{article}
          usepackage{soul}

          makeatletter
          newcommand{mydef}[2]{%
          @namedef{my#1}{#2}
          }
          newcommand{mygetdef}[2][relax]{%
          @ifundefined{my#2}%
          {{}#2 not defined}%
          {expandafter#1csname my#2endcsname}%
          }
          makeatother

          mydef{xxx}{some text to complete}

          begin{document}

          mygetdef{xxx}

          mygetdef[ul]{xxx}

          mygetdef[textit]{xxx}

          mygetdef[ul]{noway}

          end{document}


          enter image description here






          share|improve this answer
























          • Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

            – jiewuza
            Mar 23 at 14:27












          Your Answer








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

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

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


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f481003%2fwhat-is-the-difference-between-somecmd-and-csname-somecmd-endcsname%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          Try



          edeftmp{mygetdef{xxx}}
          ultmp


          The mygetdef needs to be expanded before being passed to ul.



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
          }
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works
          %%%% if uncomment, the below one does not work, an error is reported
          % ulmygetdef{xxx}

          edeftmp{mygetdef{xxx}}
          ultmp
          end{document}


          enter image description here





          SUPPLEMENTAL NOTE TO OP



          Not really to answer OP question, but in reply to some of his comments to this answer:



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else
          #1 not defined fi%
          }
          newcommand{myulgetdef}[1]{%
          ifcsname my#1endcsname expandafterul{csname my#1endcsname}%
          elsefbox{#1 not defined} fi%
          }
          newcommand{myxgetdef}[1]{%
          ifcsname my#1endcsname expandaftercsname my#1endcsname%
          elseprotectprotectprotectfbox{#1 not defined} fi%
          }
          newcommandexul[1]{edeftmp{#1}ultmp}
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works

          exul{mygetdef{xxx}}

          1. mygetdef{yyy}

          2. myulgetdef{yyy}

          3. myxgetdef{yyy}

          4. exul{mygetdef{yyy}}

          5. exul{myxgetdef{yyy}}% HOWEVER, fbox IS NOT UNDERLINED

          %6. exul{myulgetdef{yyy}}% FAILS; CANNOT ul{fbox{...}}

          end{document}


          enter image description here






          share|improve this answer


























          • Is there any way putting edef part in mygetdef to make it work?

            – jiewuza
            Mar 23 at 3:01











          • @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

            – Steven B. Segletes
            Mar 23 at 3:07











          • Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

            – jiewuza
            Mar 23 at 4:00











          • I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

            – jiewuza
            Mar 23 at 4:26











          • @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

            – Steven B. Segletes
            Mar 23 at 4:58
















          2














          Try



          edeftmp{mygetdef{xxx}}
          ultmp


          The mygetdef needs to be expanded before being passed to ul.



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
          }
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works
          %%%% if uncomment, the below one does not work, an error is reported
          % ulmygetdef{xxx}

          edeftmp{mygetdef{xxx}}
          ultmp
          end{document}


          enter image description here





          SUPPLEMENTAL NOTE TO OP



          Not really to answer OP question, but in reply to some of his comments to this answer:



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else
          #1 not defined fi%
          }
          newcommand{myulgetdef}[1]{%
          ifcsname my#1endcsname expandafterul{csname my#1endcsname}%
          elsefbox{#1 not defined} fi%
          }
          newcommand{myxgetdef}[1]{%
          ifcsname my#1endcsname expandaftercsname my#1endcsname%
          elseprotectprotectprotectfbox{#1 not defined} fi%
          }
          newcommandexul[1]{edeftmp{#1}ultmp}
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works

          exul{mygetdef{xxx}}

          1. mygetdef{yyy}

          2. myulgetdef{yyy}

          3. myxgetdef{yyy}

          4. exul{mygetdef{yyy}}

          5. exul{myxgetdef{yyy}}% HOWEVER, fbox IS NOT UNDERLINED

          %6. exul{myulgetdef{yyy}}% FAILS; CANNOT ul{fbox{...}}

          end{document}


          enter image description here






          share|improve this answer


























          • Is there any way putting edef part in mygetdef to make it work?

            – jiewuza
            Mar 23 at 3:01











          • @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

            – Steven B. Segletes
            Mar 23 at 3:07











          • Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

            – jiewuza
            Mar 23 at 4:00











          • I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

            – jiewuza
            Mar 23 at 4:26











          • @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

            – Steven B. Segletes
            Mar 23 at 4:58














          2












          2








          2







          Try



          edeftmp{mygetdef{xxx}}
          ultmp


          The mygetdef needs to be expanded before being passed to ul.



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
          }
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works
          %%%% if uncomment, the below one does not work, an error is reported
          % ulmygetdef{xxx}

          edeftmp{mygetdef{xxx}}
          ultmp
          end{document}


          enter image description here





          SUPPLEMENTAL NOTE TO OP



          Not really to answer OP question, but in reply to some of his comments to this answer:



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else
          #1 not defined fi%
          }
          newcommand{myulgetdef}[1]{%
          ifcsname my#1endcsname expandafterul{csname my#1endcsname}%
          elsefbox{#1 not defined} fi%
          }
          newcommand{myxgetdef}[1]{%
          ifcsname my#1endcsname expandaftercsname my#1endcsname%
          elseprotectprotectprotectfbox{#1 not defined} fi%
          }
          newcommandexul[1]{edeftmp{#1}ultmp}
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works

          exul{mygetdef{xxx}}

          1. mygetdef{yyy}

          2. myulgetdef{yyy}

          3. myxgetdef{yyy}

          4. exul{mygetdef{yyy}}

          5. exul{myxgetdef{yyy}}% HOWEVER, fbox IS NOT UNDERLINED

          %6. exul{myulgetdef{yyy}}% FAILS; CANNOT ul{fbox{...}}

          end{document}


          enter image description here






          share|improve this answer















          Try



          edeftmp{mygetdef{xxx}}
          ultmp


          The mygetdef needs to be expanded before being passed to ul.



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else #1 not defined fi%
          }
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works
          %%%% if uncomment, the below one does not work, an error is reported
          % ulmygetdef{xxx}

          edeftmp{mygetdef{xxx}}
          ultmp
          end{document}


          enter image description here





          SUPPLEMENTAL NOTE TO OP



          Not really to answer OP question, but in reply to some of his comments to this answer:



          documentclass{article}
          usepackage{soul}
          makeatletter
          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname {#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname csname my#1endcsname else
          #1 not defined fi%
          }
          newcommand{myulgetdef}[1]{%
          ifcsname my#1endcsname expandafterul{csname my#1endcsname}%
          elsefbox{#1 not defined} fi%
          }
          newcommand{myxgetdef}[1]{%
          ifcsname my#1endcsname expandaftercsname my#1endcsname%
          elseprotectprotectprotectfbox{#1 not defined} fi%
          }
          newcommandexul[1]{edeftmp{#1}ultmp}
          makeatother

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}
          ultest % it works

          exul{mygetdef{xxx}}

          1. mygetdef{yyy}

          2. myulgetdef{yyy}

          3. myxgetdef{yyy}

          4. exul{mygetdef{yyy}}

          5. exul{myxgetdef{yyy}}% HOWEVER, fbox IS NOT UNDERLINED

          %6. exul{myulgetdef{yyy}}% FAILS; CANNOT ul{fbox{...}}

          end{document}


          enter image description here







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 23 at 5:15

























          answered Mar 23 at 1:41









          Steven B. SegletesSteven B. Segletes

          160k9205413




          160k9205413













          • Is there any way putting edef part in mygetdef to make it work?

            – jiewuza
            Mar 23 at 3:01











          • @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

            – Steven B. Segletes
            Mar 23 at 3:07











          • Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

            – jiewuza
            Mar 23 at 4:00











          • I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

            – jiewuza
            Mar 23 at 4:26











          • @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

            – Steven B. Segletes
            Mar 23 at 4:58



















          • Is there any way putting edef part in mygetdef to make it work?

            – jiewuza
            Mar 23 at 3:01











          • @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

            – Steven B. Segletes
            Mar 23 at 3:07











          • Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

            – jiewuza
            Mar 23 at 4:00











          • I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

            – jiewuza
            Mar 23 at 4:26











          • @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

            – Steven B. Segletes
            Mar 23 at 4:58

















          Is there any way putting edef part in mygetdef to make it work?

          – jiewuza
          Mar 23 at 3:01





          Is there any way putting edef part in mygetdef to make it work?

          – jiewuza
          Mar 23 at 3:01













          @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

          – Steven B. Segletes
          Mar 23 at 3:07





          @jiewuza It would be easier to define newcommandexul[1]{edeftmp{#1}ultmp} and then invoke it as exul{mygetdef{xxx}}.

          – Steven B. Segletes
          Mar 23 at 3:07













          Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

          – jiewuza
          Mar 23 at 4:00





          Well, then I have to define more newcommand for others besides ul. But it works anyway. Thanks.

          – jiewuza
          Mar 23 at 4:00













          I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

          – jiewuza
          Mar 23 at 4:26





          I just got another problem. I added fbox in mygetdef, that is, ifcsname my#1endcsname csname my#1endcsname else fbox{#1 not defined} fi. And when I try mygetdef{yyy} (which is not defined), it brokes with some Undefined control sequence error.

          – jiewuza
          Mar 23 at 4:26













          @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

          – Steven B. Segletes
          Mar 23 at 4:58





          @jiewuza The command newcommand{mygetdef}[1]{% ifcsname my#1endcsname csname my#1endcsname else fbox{ #1 not defined} fi% } works just fine if invoked directly as mygetdef{yyy}. However, exul{mygetdef{yyy}} does not work in that case because you can't ul an fbox.

          – Steven B. Segletes
          Mar 23 at 4:58











          3














          The command ul is defined as SOUL@ulsetupSOUL@. The first command sets up some commands that will be later delivered after a group has started and is of no concern here.



          The macro SOUL@ is defined as



          % soul.sty, line 99:
          defSOUL@{%
          futureletSOUL@@SOUL@expand
          }


          which means that the following token is looked up and stored in SOUL@@; then SOUL@expand is executed



          % soul.sty, line 102:
          defSOUL@expand{%
          ifcatbgroupnoexpandSOUL@@
          letSOUL@nSOUL@start
          else
          bgroup
          def\##1##2{def##2{noexpand##2}}%
          theSOUL@cmds
          SOUL@buffer={%
          \TeX\LaTeX\soulomit\mbox\hbox\textregistered
          \slash\textcircled\copyright\S\,\<\>\~%
          \\%
          }%
          def\##1{def##1{noexpand##1}}%
          theSOUL@buffer
          letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%
          egroup
          fi
          SOUL@n
          }


          Quite a mouthful! The behavior depends on whether the token stored in SOUL@@ is a left brace or not. In your case it isn't.



          The part of the code above which is of primary interest is



                      letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%


          Note that SOUL@@ is the token found at the first step, in your case mygetdef. At the end, SOUL@n is executed, which discards the next token (your mygetdef) and does



          SOUL@start{<full expansion of mygetdef`>}


          The place where the error happens is at the xdef, because mygetdef does not find its argument, but just the closing brace. What you want is that



          ulmygetdef{xxx}


          becomes



          ulmyxxx


          You need to do some clever expansion for this, but it becomes very awkward, mainly because of the conditionals. If you do



          expandafterulmyxxx


          you get



          ulifcsname myxxxendcsnamecsname myxxxendcsnameelse xxx not defined fi


          With three expandafters



          ulcsname myxxxendcsnameelse xxx not defined fi


          With seven expandafters



          ulmyxxxelse xxx not defined fi


          That's it! Let's see what happens with mygetdef{noway} (assuming it's undefined). You'd get



          ul noway not defined fi


          which is not really what you want, but can be easily fixed.



          documentclass{article}
          usepackage{soul}

          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname{#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname
          csname my#1endcsname
          else
          {}#1 not defined%
          fi
          }

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}

          ultest

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{xxx}

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{noway}

          end{document}


          enter image description here



          My proposal is to define differently mygetdef, if you plan to use it after soul macros, but not only.



          documentclass{article}
          usepackage{soul}

          makeatletter
          newcommand{mydef}[2]{%
          @namedef{my#1}{#2}
          }
          newcommand{mygetdef}[2][relax]{%
          @ifundefined{my#2}%
          {{}#2 not defined}%
          {expandafter#1csname my#2endcsname}%
          }
          makeatother

          mydef{xxx}{some text to complete}

          begin{document}

          mygetdef{xxx}

          mygetdef[ul]{xxx}

          mygetdef[textit]{xxx}

          mygetdef[ul]{noway}

          end{document}


          enter image description here






          share|improve this answer
























          • Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

            – jiewuza
            Mar 23 at 14:27
















          3














          The command ul is defined as SOUL@ulsetupSOUL@. The first command sets up some commands that will be later delivered after a group has started and is of no concern here.



          The macro SOUL@ is defined as



          % soul.sty, line 99:
          defSOUL@{%
          futureletSOUL@@SOUL@expand
          }


          which means that the following token is looked up and stored in SOUL@@; then SOUL@expand is executed



          % soul.sty, line 102:
          defSOUL@expand{%
          ifcatbgroupnoexpandSOUL@@
          letSOUL@nSOUL@start
          else
          bgroup
          def\##1##2{def##2{noexpand##2}}%
          theSOUL@cmds
          SOUL@buffer={%
          \TeX\LaTeX\soulomit\mbox\hbox\textregistered
          \slash\textcircled\copyright\S\,\<\>\~%
          \\%
          }%
          def\##1{def##1{noexpand##1}}%
          theSOUL@buffer
          letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%
          egroup
          fi
          SOUL@n
          }


          Quite a mouthful! The behavior depends on whether the token stored in SOUL@@ is a left brace or not. In your case it isn't.



          The part of the code above which is of primary interest is



                      letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%


          Note that SOUL@@ is the token found at the first step, in your case mygetdef. At the end, SOUL@n is executed, which discards the next token (your mygetdef) and does



          SOUL@start{<full expansion of mygetdef`>}


          The place where the error happens is at the xdef, because mygetdef does not find its argument, but just the closing brace. What you want is that



          ulmygetdef{xxx}


          becomes



          ulmyxxx


          You need to do some clever expansion for this, but it becomes very awkward, mainly because of the conditionals. If you do



          expandafterulmyxxx


          you get



          ulifcsname myxxxendcsnamecsname myxxxendcsnameelse xxx not defined fi


          With three expandafters



          ulcsname myxxxendcsnameelse xxx not defined fi


          With seven expandafters



          ulmyxxxelse xxx not defined fi


          That's it! Let's see what happens with mygetdef{noway} (assuming it's undefined). You'd get



          ul noway not defined fi


          which is not really what you want, but can be easily fixed.



          documentclass{article}
          usepackage{soul}

          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname{#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname
          csname my#1endcsname
          else
          {}#1 not defined%
          fi
          }

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}

          ultest

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{xxx}

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{noway}

          end{document}


          enter image description here



          My proposal is to define differently mygetdef, if you plan to use it after soul macros, but not only.



          documentclass{article}
          usepackage{soul}

          makeatletter
          newcommand{mydef}[2]{%
          @namedef{my#1}{#2}
          }
          newcommand{mygetdef}[2][relax]{%
          @ifundefined{my#2}%
          {{}#2 not defined}%
          {expandafter#1csname my#2endcsname}%
          }
          makeatother

          mydef{xxx}{some text to complete}

          begin{document}

          mygetdef{xxx}

          mygetdef[ul]{xxx}

          mygetdef[textit]{xxx}

          mygetdef[ul]{noway}

          end{document}


          enter image description here






          share|improve this answer
























          • Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

            – jiewuza
            Mar 23 at 14:27














          3












          3








          3







          The command ul is defined as SOUL@ulsetupSOUL@. The first command sets up some commands that will be later delivered after a group has started and is of no concern here.



          The macro SOUL@ is defined as



          % soul.sty, line 99:
          defSOUL@{%
          futureletSOUL@@SOUL@expand
          }


          which means that the following token is looked up and stored in SOUL@@; then SOUL@expand is executed



          % soul.sty, line 102:
          defSOUL@expand{%
          ifcatbgroupnoexpandSOUL@@
          letSOUL@nSOUL@start
          else
          bgroup
          def\##1##2{def##2{noexpand##2}}%
          theSOUL@cmds
          SOUL@buffer={%
          \TeX\LaTeX\soulomit\mbox\hbox\textregistered
          \slash\textcircled\copyright\S\,\<\>\~%
          \\%
          }%
          def\##1{def##1{noexpand##1}}%
          theSOUL@buffer
          letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%
          egroup
          fi
          SOUL@n
          }


          Quite a mouthful! The behavior depends on whether the token stored in SOUL@@ is a left brace or not. In your case it isn't.



          The part of the code above which is of primary interest is



                      letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%


          Note that SOUL@@ is the token found at the first step, in your case mygetdef. At the end, SOUL@n is executed, which discards the next token (your mygetdef) and does



          SOUL@start{<full expansion of mygetdef`>}


          The place where the error happens is at the xdef, because mygetdef does not find its argument, but just the closing brace. What you want is that



          ulmygetdef{xxx}


          becomes



          ulmyxxx


          You need to do some clever expansion for this, but it becomes very awkward, mainly because of the conditionals. If you do



          expandafterulmyxxx


          you get



          ulifcsname myxxxendcsnamecsname myxxxendcsnameelse xxx not defined fi


          With three expandafters



          ulcsname myxxxendcsnameelse xxx not defined fi


          With seven expandafters



          ulmyxxxelse xxx not defined fi


          That's it! Let's see what happens with mygetdef{noway} (assuming it's undefined). You'd get



          ul noway not defined fi


          which is not really what you want, but can be easily fixed.



          documentclass{article}
          usepackage{soul}

          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname{#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname
          csname my#1endcsname
          else
          {}#1 not defined%
          fi
          }

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}

          ultest

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{xxx}

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{noway}

          end{document}


          enter image description here



          My proposal is to define differently mygetdef, if you plan to use it after soul macros, but not only.



          documentclass{article}
          usepackage{soul}

          makeatletter
          newcommand{mydef}[2]{%
          @namedef{my#1}{#2}
          }
          newcommand{mygetdef}[2][relax]{%
          @ifundefined{my#2}%
          {{}#2 not defined}%
          {expandafter#1csname my#2endcsname}%
          }
          makeatother

          mydef{xxx}{some text to complete}

          begin{document}

          mygetdef{xxx}

          mygetdef[ul]{xxx}

          mygetdef[textit]{xxx}

          mygetdef[ul]{noway}

          end{document}


          enter image description here






          share|improve this answer













          The command ul is defined as SOUL@ulsetupSOUL@. The first command sets up some commands that will be later delivered after a group has started and is of no concern here.



          The macro SOUL@ is defined as



          % soul.sty, line 99:
          defSOUL@{%
          futureletSOUL@@SOUL@expand
          }


          which means that the following token is looked up and stored in SOUL@@; then SOUL@expand is executed



          % soul.sty, line 102:
          defSOUL@expand{%
          ifcatbgroupnoexpandSOUL@@
          letSOUL@nSOUL@start
          else
          bgroup
          def\##1##2{def##2{noexpand##2}}%
          theSOUL@cmds
          SOUL@buffer={%
          \TeX\LaTeX\soulomit\mbox\hbox\textregistered
          \slash\textcircled\copyright\S\,\<\>\~%
          \\%
          }%
          def\##1{def##1{noexpand##1}}%
          theSOUL@buffer
          letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%
          egroup
          fi
          SOUL@n
          }


          Quite a mouthful! The behavior depends on whether the token stored in SOUL@@ is a left brace or not. In your case it isn't.



          The part of the code above which is of primary interest is



                      letprotectnoexpand
          xdefSOUL@n##1{noexpandSOUL@start{SOUL@@}}%


          Note that SOUL@@ is the token found at the first step, in your case mygetdef. At the end, SOUL@n is executed, which discards the next token (your mygetdef) and does



          SOUL@start{<full expansion of mygetdef`>}


          The place where the error happens is at the xdef, because mygetdef does not find its argument, but just the closing brace. What you want is that



          ulmygetdef{xxx}


          becomes



          ulmyxxx


          You need to do some clever expansion for this, but it becomes very awkward, mainly because of the conditionals. If you do



          expandafterulmyxxx


          you get



          ulifcsname myxxxendcsnamecsname myxxxendcsnameelse xxx not defined fi


          With three expandafters



          ulcsname myxxxendcsnameelse xxx not defined fi


          With seven expandafters



          ulmyxxxelse xxx not defined fi


          That's it! Let's see what happens with mygetdef{noway} (assuming it's undefined). You'd get



          ul noway not defined fi


          which is not really what you want, but can be easily fixed.



          documentclass{article}
          usepackage{soul}

          newcommand{mydef}[2]{%
          expandafterdefcsname my#1endcsname{#2}
          }
          newcommand{mygetdef}[1]{%
          ifcsname my#1endcsname
          csname my#1endcsname
          else
          {}#1 not defined%
          fi
          }

          deftest{some text to complete}
          mydef{xxx}{some text to complete}

          begin{document}

          ultest

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{xxx}

          expandafterexpandafterexpandafter
          expandafterexpandafterexpandafter
          expandafterulmygetdef{noway}

          end{document}


          enter image description here



          My proposal is to define differently mygetdef, if you plan to use it after soul macros, but not only.



          documentclass{article}
          usepackage{soul}

          makeatletter
          newcommand{mydef}[2]{%
          @namedef{my#1}{#2}
          }
          newcommand{mygetdef}[2][relax]{%
          @ifundefined{my#2}%
          {{}#2 not defined}%
          {expandafter#1csname my#2endcsname}%
          }
          makeatother

          mydef{xxx}{some text to complete}

          begin{document}

          mygetdef{xxx}

          mygetdef[ul]{xxx}

          mygetdef[textit]{xxx}

          mygetdef[ul]{noway}

          end{document}


          enter image description here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 23 at 13:50









          egregegreg

          731k8819293246




          731k8819293246













          • Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

            – jiewuza
            Mar 23 at 14:27



















          • Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

            – jiewuza
            Mar 23 at 14:27

















          Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

          – jiewuza
          Mar 23 at 14:27





          Although it is now beyond my understanding, your explanation is really helpful. I am learning the expanding rules. And your redefination of mygetdef is quite interesting. I will dig more.

          – jiewuza
          Mar 23 at 14:27


















          draft saved

          draft discarded




















































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


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

          But avoid



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

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


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




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f481003%2fwhat-is-the-difference-between-somecmd-and-csname-somecmd-endcsname%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

          Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

          ComboBox Display Member on multiple fields

          Is it possible to collect Nectar points via Trainline?