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

MANUAL: clarify truthiness in template variables #4631

Merged
merged 1 commit into from
May 8, 2018
Merged

Conversation

mb21
Copy link
Collaborator

@mb21 mb21 commented May 6, 2018

closes #2281

I couldn't find the relevant code in https://www.stackage.org/haddock/lts-11.7/doctemplates-0.2.2.1/src/Text.DocTemplates.html

  • Is this list of truthy values exhaustive or should it be defined in terms of which things are not truthy?
  • Does the YAML standard define types? Or are they just falling back on the JSON type definitions? Should we mention this here?
  • How come --metadata x=no is parsed as a YAML boolean false? Is that specific to pandoc or a YAML thing?

@latk
Copy link

latk commented May 6, 2018

There are multiple YAML standards that are slightly inconsistent, but they all do ascribe some type to all values (defaulting to the !!str tag).

YAML 1.2 has the concept of schemas. In the Core Schema that extends JSON, a regex for booleans is given as:

true | True | TRUE | false | False | FALSE

YAML 1.1 is more common, and has a tag library in which the bool type is defined as y/n, yes/no, true/false, on/off. Each keyword can be lowercase, uppercase, and capitalized.

Neither YAML standard seems to ascribe truthiness to non-booleans such as zero, null, or lists. Those would be application-dependent.

So the question is, which YAML standard and schema does Pandoc use by default? And how does Pandoc coerce non-boolean values to booleans?

If I read the linked doctemplates source correctly, any JSON value should be truthy that is coerced by resolveVar to a non-empty string: a number, the true boolean, an object, or a non-empty list where the 1st element is truthy?

@jgm
Copy link
Owner

jgm commented May 6, 2018

We currently use this library to parse YAML:
https://hackage.haskell.org/package/yaml
it wraps
http://pyyaml.org/wiki/LibYAML
Neither README says anything about the YAML version supported. But, a little experimenting shows that y is recognized as a true boolean value, so it sounds like 1.1.

@jgm
Copy link
Owner

jgm commented May 6, 2018

So, the proposed documentation change is incomplete. Truthy values include not just true, but y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF.

@mb21
Copy link
Collaborator Author

mb21 commented May 7, 2018

Thanks @latk for the pointer to resolveVar, which is called by cond – so if resolveVar returns an empty string, the $else$ clause is evaluated, otherwise the $if clause.

And thanks to @jgm for pointing out how the YAML parses booleans.

I've thusly changed the pull request. But it's now a very long and complicated text. Maybe that should better go in the README for the doctemplates library and we just add a link to it from the MANUAL?

@jgm
Copy link
Owner

jgm commented May 7, 2018 via email

MANUAL.txt Outdated
any valid template text, and may include interpolated variables or other
conditionals. The `$else$` section may be omitted.
This will include `X` in the template if `variable` has a truthy
value; otherwise it will include `Y`. (Here a truthy value is:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get rid of the extra layer of parens: (Here -> Here.

@jgm
Copy link
Owner

jgm commented May 7, 2018

How about something like this:

This will include `X` in the template if `variable` has a truthy
value; otherwise it will include `Y`. Here a truthy value is any
of the following:

- a string that is not entirely white space,
- a non-empty array where the first value is truthy,
- any number (including zero)
- any object
- the boolean `true` (to specify the boolean `true`
  value using YAML metadata or the `--metadata` flag,
  use `y`, `Y`, `yes`, `Yes`, `YES`, `true`, `True`,
  `TRUE`, `on`, `On`, or `ON`; with the `--variable`
  flag, simply omit a value for the variable, as in
  `--variable draft`).
 
`X` and `Y` are placeholders for any valid template text,
and may include interpolated variables or other conditionals.
The `$else$` section may be omitted.

Now that this is documented, I see some things we may want
to change. In particular, I didn't even realize that an array whose
first value was false would be treated as a false value, and that
seems a bit odd. But we should certainly document the current
behavior before thinking about that.

@mb21
Copy link
Collaborator Author

mb21 commented May 7, 2018

Okay, we're getting there! Changed the commit again...

Not sure it's clear to the reader that an object here refers to some YAML that gets parsed to the Aeson-in-memory-representation that's analogous to a JSON object but whatever...

@mb21
Copy link
Collaborator Author

mb21 commented May 7, 2018

an array whose first value was false would be treated as a false value, and that seems a bit odd.

It's certainly surprising... but there must have been a special reason to implement it in this (more complicated) way. Maybe it was desirable to have an array containing only one element behave in the same way as that element by itself?

@jgm jgm merged commit eb3521e into master May 8, 2018
@jgm
Copy link
Owner

jgm commented May 8, 2018

Thanks!

@mb21 mb21 deleted the mb21-patch-1 branch May 8, 2018 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Undocumented behaviour on template variable
3 participants