Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support \operatorname #145

Closed
sophiebits opened this issue Oct 1, 2014 · 23 comments
Closed

Support \operatorname #145

sophiebits opened this issue Oct 1, 2014 · 23 comments
Labels

Comments

@sophiebits
Copy link
Contributor

We should support this so you can do, e.g., \operatorname{span} (see #144). Its implementation is subtler than it may appear:

http://tex.stackexchange.com/a/84308/9

@xymostech
Copy link
Contributor

Interesting. That post has a lot of other useful information too.

For example, it pointed me to the fact that \stackrel is just defined as \def\stackrel#1#2\mathrel{\mathop {#2}\limits ^{#1}} which is something we could simulate pretty easily. Food for thought.

@gagern
Copy link
Collaborator

gagern commented Jan 16, 2017

amsopn is the relevant package here, so texdoc amsopn will provide relevant implementation details. \operatorname builds on the more elementary \qopname.

\DeclareRobustCommand{\operatorname}{%
    \@ifstar{\qopname\newmcodes@ m}%
            {\qopname\newmcodes@ o}}%

In the interior of the \mathop we need a null object (we choose a zero kern for minimum waste of main mem) in order to guard against the case where #3 is a single letter; TEX will seize it and center it on the math axis if there is nothing else inside the \mathop atom.

\DeclareRobustCommand{\qopname}[3]{%
    \mathop{#1\kern\z@\operator@font#3}%
    \csname n#2limits@\endcsname}

This command \qopname is in turn used by many definitions, including the \limsup from #111. They tend to have \relax in place of #1. #2 would either be o for \nolimits@ which is \nolimits but eats any \limits that might follow, or it would be m for \nmlimits@ which is \displaylimits, i.e. limits above and below in display mode, but to the right in inline mode.

If we can get our macro expansion to support this kind of command, we'd have access to a lot of built-in definitions with almost no additional work.

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

I think the following code would work for \operatorname:

//////////////////////////////////////////////////////////////////////
// amsopn.dtx

//   \operatorname
// \mathop{#1\kern\z@\operator@font#3}\csname n#2limits@\endcsname}
defineMacro("\\operatorname", "\\mathop{\\text{#1}}\\nolimits");

//////////////////////////////////////////////////////////////////////

That macro gets the spacing correct; it avoids centering a single character; it deals with hyphens correctly.
operatorname

I'm not really up to creating any Screenshotter tests, but I think the code is ready if someone wants to take it on.

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

@kevinbarabash, Do you think that this \operatorname macro needs Screenshotter tests? If not, then I could just submit the PR.

@edemaine
Copy link
Member

I think a screenshot test would be useful in particular so it's easy to run texcmp to compare. I'm particularly curious about the use of \text -- does \operator@font really switch to text mode, or just a roman font? E.g., what happens to spaces or math-only operators inside \operatorname? (Maybe \text should just be \mathrm.)

\def\operator@font{\mathgroup\symoperators}

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

The purpose of the \text is to prevent a hyphen from turning into a minus. In other words, I'm using \text as a hack to replace \newmcodes@. If \mathrm were to replace \text the screenshot above would render as:
badhyphen

@edemaine
Copy link
Member

Ah, I see, that makes sense. What about spaces (do/should they appear in output?) and math-only commands (not sure KaTeX enforces those)?

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

Well, there are math operators, such as lim sup, that do contain a space, so I suppose we want \operatorname to enable a space. I really hadn't thought much about math-only commands.

@sophiebits
Copy link
Contributor Author

lim sup should be lim,sup if I remember correctly.

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

Image from quicklatex.com for \limsup x

@edemaine
Copy link
Member

edemaine commented Jul 25, 2017

What I meant was, "what does LaTeX do with spaces in \operatorname?" Unfortunately, the answer is that \operatorname eats spaces, as if in math mode. So it's not exactly \text mode, but partially...

It still might be worth defining \operatorname in the way you suggest, as a temporary solution, given that it works in most cases...

(\limsup isn't the point here, as it's going to be defined with explicit spaces in it.)

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

I very much agree. This macro is meant to be a quick hack, done in time to be included in the next release. It can improved in several ways.

@ronkok
Copy link
Collaborator

ronkok commented Jul 25, 2017

Okay, new option. This code eats spaces, and it has better MathML output than the macro version. Here's the output:
newop
from: \( \operatorname{g}(z) + 5\operatorname{g}z + \operatorname{gam-ma}(z) + \operatorname{gam ma}(z) \)

The code in functions.js is augmented by:

// \operatorname. No limits, not symbols.
defineFunction("\\operatorname", {
    numArgs: 1,
}, function (context, args) {
    const argArray = args[0].value;
    let opName = "\\";
    for (let i = 0; i < argArray.length; i++) {
        opName += argArray[i].value;
    }
    opName = opName.replace(/\\s/g, "");
    return {
        type: "op",
        limits: false,
        symbol: false,
        body: opName,
    };
});

In buildHtml.groupTypes.op, the line:

output.push(buildCommon.mathsym(group.value.body[i], group.mode));

is replaced by:

output.push(buildCommon.mathsym(group.value.body[i], "text"));

I don't do Screenshotter, but anyone is welcome to make this PR.

@kevinbarabash
Copy link
Member

I don't do Screenshotter, but anyone is welcome to make this PR.

This makes me sad. I wish that Screenshotter wasn't a barrier to entry for contributors. There appears to be a way to run multiple builds on travis with different environment variables. travis-ci has a way to upload contents of a folder to S3 that I'm investigating.

https://docs.travis-ci.com/user/deployment/s3/

@ronkok
Copy link
Collaborator

ronkok commented Jul 26, 2017

This makes me sad.

Don’t be. This sort of thing shouldn’t be a problem, just one step on the way to a solution.

Perhaps some background. I’ve been a structural engineer for 35 years. I’ve led work at scales that range from a two sheet job to a $500 million project. During all that time, it’s been rare that I could assign a project to just one person. Anything substantial requires a team of people with complementary abilities.

That’s really all this is. Just a task that requires a team with complementary abilities. I’m seeing open-source development for the first time and it seems as though the whole process may be held back because it doesn’t have a really good way to put those teams together.

If you find a way to make Screenshotter easier, that’s great, but if you want to do something really brilliant, figure out a way to identify and build a team on demand.

@kevinbarabash
Copy link
Member

I’m seeing open-source development for the first time and it seems as though the whole process may be held back because it doesn’t have a really good way to put those teams together.

It can definitely be slower than having a dedicated team of people who are being paid to work on a project.

If you find a way to make Screenshotter easier, that’s great, but if you want to do something really brilliant, figure out a way to identify and build a team on demand.

My goals are definitely less lofty than figuring building an on demand team. I'd like to make KaTeX easier to contribute to and hopefully I can generalize things I learn to other open source projects.

@ronkok
Copy link
Collaborator

ronkok commented Sep 10, 2017

@kevinbarabash I have prepared a PR to support \operatorname, but I am once again having trouble making a commit. I get the error message:

Commit failed - exit code 1 received, with output: 'error: cannot spawn .git/hooks/pre-commit: No such file or directory'

I have tried:

  • npm install
  • npm update
  • deleting the file pre-commit from the hooks folder.
  • deleting all the files in the hooks folder.

Frustration waxes. Patience wanes. Any suggestions would be welcome.

@kevinbarabash
Copy link
Member

@ronkok you can skip commit hooks by doing git commit -n. If we can't figure out why this isn't working on windows we may just disable the hooks. The various checks get run on travis-ci anyways. The intent was to save when creating or updating a PR by running the checks locally first. People can do this manually anyways.

I'm surprised that deleting pre-commit from the hooks folder didn't fix this though.

@edemaine
Copy link
Member

git commit -n will fix short term. Be sure to delete pre-commit from .git/hooks not hooks.

@ronkok
Copy link
Collaborator

ronkok commented Sep 10, 2017

Success. Thank you once more.

@janosh
Copy link

janosh commented Mar 22, 2019

Having operatorname is great! Are there any plans to add support for operatorname* to enable proper limits in display mode?

@ronkok
Copy link
Collaborator

ronkok commented Mar 22, 2019

Yep. I'll turn in a PR sometime in the next few days.

@janosh
Copy link

janosh commented Mar 22, 2019

Thank you very much! Looking forward to that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants