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

Turning content into string: str(content) #2196

Closed
zouharvi opened this issue Sep 20, 2023 · 9 comments
Closed

Turning content into string: str(content) #2196

zouharvi opened this issue Sep 20, 2023 · 9 comments
Labels
feature request New feature or request scripting About Typst's coding capabilities

Comments

@zouharvi
Copy link
Sponsor

Description

The str() function could accept content out of which it would extract the textual parts. For example: str([Hello _there_]) would be "Hello there".

Use Case

In a few projects I want to set the document (PDF) title but also display the title in the doc itself. However, the title might be content and not a string. That means that it needs to be duplicated:

set document(title: "This cool project")

align(center)[
  #set text(size: 1.5em)
  This _*cool*_ project
]

This is not a big deal but leads to these kinds of templates which feel weird because of the duplicity:

#show: project.with(
  codename: "This cool project",
  title: [This _*cool*_ project],
)

Ideally, one would be able to write the following, with conversion from content to string inside of the template.

#show: project.with(
  title: [This _*cool*_ project],
)

I acknowledge that there are many vague cases and lots of complexity -- I'm just putting this out. Maybe there's also an existing solution to this which I overlooked, such as iterating the children of the content and only collecting the textual yield.

@zouharvi zouharvi added the feature request New feature or request label Sep 20, 2023
@zouharvi zouharvi changed the title Turning content into string with str(content) Turning content into string: str(content) Sep 20, 2023
@EpicEricEE
Copy link
Contributor

EpicEricEE commented Sep 20, 2023

You can indeed iterate over the children and collect the text recursively. It's definitely not perfect, but it works for your case:

#let to-string(content) = {
  if content.has("text") {
    content.text
  } else if content.has("children") {
    content.children.map(to-string).join("")
  } else if content.has("body") {
    to-string(content.body)
  } else if content == [ ] {
    " "
  }
}

#to-string[This _*cool*_ project] // => "This cool project"

@zouharvi
Copy link
Sponsor Author

Thanks @EpicEricEE. That feels like should be the implementation of str(content) so I'll leave the issue open to keep this under consideration but anyone else feel free to close it.

@laurmaedje
Copy link
Member

Internally, there is already a plain text functionality (via the PlainText trait), which is used for instance for the PDF outline.

Since the issue mostly comes up with set document(title: _), I'm considering to just allow content there and do the plain-text conversion internally.

Long-term, with get rules, this would also mean that more "standard" metadata like title, author, etc. could be specified with document set rules instead of on the template and templates could read that. For that, the title would also need to be content.

@laurmaedje laurmaedje added the scripting About Typst's coding capabilities label Sep 21, 2023
@laurmaedje
Copy link
Member

I have pushed a commit that allows arbitrary content as the document title. It will then be turned into a string internally. This should cover your use case. I will also update the web app templates to default to a content block instead of a string with the next release.

I'm not comfortable with exposing the internal plain-text functionality at the moment because it's very lossy for more complex content.

@laurmaedje laurmaedje closed this as not planned Won't fix, can't repro, duplicate, stale Nov 20, 2023
@zouharvi
Copy link
Sponsor Author

Thank you for resolving this!

@emilyyyylime
Copy link
Contributor

@laurmaedje would it be possible to apply the same change for document author?

@laurmaedje
Copy link
Member

Does it really make sense for an author name to have markup?

@emilyyyylime
Copy link
Contributor

in Hebrew for example, I might write ' and use a show rule to turn it into a Geresh ׳, or someone might want smart quotes when entering their Name "nickname" Surname. It's mostly about simple conversions like that and about being able to reuse the same variable later in like the title page.

@laurmaedje
Copy link
Member

Unfortunately the plain text conversion employed to convert the title to a string is very naive, so it wouldn't be able to handle show rules. I think it also doesn't properly handle smartquotes, but that would be fixable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature or request scripting About Typst's coding capabilities
Projects
None yet
Development

No branches or pull requests

4 participants