2

I'm working on something that really benefits from division into multiple files, and so am trying to figure out the Project/Product/Component structure. I do think I've got most of it working, except for some details in (ab)using the \environment feature: I'd like some components to use a particular environment, without affecting the rest of the document.

If I just put it at the beginning of the component, it doesn't unload and winds up affecting every component after this one in the product:

\startcomponent c_acronyms
\project proj_ref
\product prd_data
\environment env_list


\startchapter[title=Acronym definitions]

...

\stopchapter
\stopcomponent

I can hack together a solution using \start and \stop, but that feels rather ugly as far as hacks go, and any successive invocations of that environment are ignored:

\startcomponent c_acronyms
\project proj_ref
\product prd_data


\startchapter[title=Acronym definitions]
\start
\environment env_list

...

\stop
\stopchapter

\startchapter[title=Keeps default formatting]
\start
\environment env_list

...

\stop
\stopchapter
\stopcomponent

I get the feeling that I'm trying to use \environment for something it's not actually designed for, but what would the best replacement be for it? I imagine I could do something with modules, but that seems a lot heavier-weight than necessary for such a small collection of commands (especially in my Windows TeXLive installation, which doesn't seem to recognize modules in the project directory). Should I be putting together a specific \definestartstop?

For reference, here's the minimal contents of the rest of my hiearchy:

\startproduct prd_data
\project proj_ref


\startfrontmatter

\completecontent

\component c_acronyms

\stopfrontmatter
\stopproduct

 

\startproject proj_ref
\environment env_ref


\product prd_data

\stopproject

 

\startenvironment env_ref

\usepath[{data}]


\setupcolors[state=start]
\setupinteraction[state=start]


% Add thin spaces before tall punctuation
\definecharacterspacing[thin]
\setupcharacterspacing[thin][\number`:][left=.16667,alternative=1]
\setupcharacterspacing[thin][\number`;][left=.16667,alternative=1]
\setupcharacterspacing[thin][\number`?][left=.16667,alternative=1]
\setupcharacterspacing[thin][\number`!][left=.16667,alternative=1]
\setcharacterspacing[thin]


% Define look-and-feel for the document
\setupalign[hanging]
\setupindenting[yes,small]
\setupwhitespace[medium]

\definefontfeature[default][default][protrusion=quality]


\stopenvironment

 

\startenvironment env_list


% Override look-and-feel for tabbed lists
\setupindenting[no]
\setupwhitespace[big] % Makes the issue more obvious


\stopenvironment

And while I'm here, does anyone know why compiling the project file doesn't compile each of the products? I'd guess it was originally due to a restriction on one-output-per-invocation, but surely the switch to LuaTeX allows spawning child processes?

9
  • 1
    Possible duplicate of Do ConTeXt products have isolated layouts? Jun 5, 2017 at 4:04
  • This is similar to TeX's \input. You cannot "deinput" the file afterwards. You can only limit the effects by using grouping. Unfortunately, ConTeXt keeps track of environment input globally (one the Lua level) which is why all successive attempts to use the environment are ignored. So the closest you can get to your idea is removing the environment markers from the file and do \start\input env_list ... \stop. Jun 5, 2017 at 4:12
  • Thanks! I do get why they aren't "deinput" (fun term) after the file, but it's a bit unfortunate that the environment loading is forced to be globally-unique; even if I had to make sure that the primary environment files overwrote everything in the specialized ones, I'd think it would be a lot more flexible if it were per-file. And I did run a few searches, but apparently not with the right terms. Thanks for linking me to that as well! It's definitely similar, but I think I'm asking about an alternative (like \input) while that's wondering about use cases.
    – WovenTales
    Jun 5, 2017 at 5:32
  • Actually, there is a difference between \environment and \input that makes the latter sub-optimal: since it doesn't know of the project directory structure, I need to use the full path relative to the component (../env_list). It definitely works for now, but hardcoding the path like that in an easy macro -- and, admittedly, not doing so is an easy fix -- seems like it's begging to break if I make enough environments to move them to a subfolder or if I nest a component even one level deeper than expected.
    – WovenTales
    Jun 5, 2017 at 5:56
  • 1
    I've found it! \setcharacterspacing[frenchpunctuation] -- not actually documented anywhere on the wiki except the changelogs, but it is talked about on the mailing list (though I found it through the t-french module). The question is updated with what I'm using now, which isn't actually the builtin since I found those spaces a bit thicker than I wanted.
    – WovenTales
    Jun 10, 2017 at 7:50

2 Answers 2

3

One option is to use \setups.

\startenvironment env_list

% Override look-and-feel for tabbed lists
\startsetups[tabbled-list]
  \setupindenting[no]
  \setupwhitespace[big] % Makes the issue more obvious
\stopsetups

\stopenvironment

Then, input the environment in your project file and use

\start
\setups[tabbed-list]
....
\stop

to limit the region where you want to apply setup. Some environments accept a setup key, so depending on how you are implementing the tabbed list, you could even pass setups=tabbed-list to an appropriate \setup... command.

1
  • That's probably the safest way of doing so, thanks! The "tabbed list" is just a literal sequence of macros from a \definedescription deriving from tab, so unfortunately it's not quite as simple as the best case you've given, but I can put it in a \definestartstop easily enough.
    – WovenTales
    Jun 5, 2017 at 6:03
3

You could write your own \environment wrapper which opens a group, inputs the environment file and ignores the \start ... \stopenvironment inside.

So if you have a file env_test.tex

\startenvironment *

  \def\envtest{Test}

\stopenvironment

you can do

\unexpanded\def\startlocalenvironment{%
  \dosingleempty\dostartlocalenvironment}
\def\dostartlocalenvironment[#1]{%
  \start
  \let\startenvironment\gobbleoptorarg
  \let\stopenvironment\relax
  \input{#1}}

\def\stoplocalenvironment{\stop}

\unexpanded\def\gobbleoptorarg{%
  \doifelsenextoptionalcs\gobbleopt\gobblearg}

\def\gobbleopt[#1]{}
\def\gobblearg #1 {}

\starttext

\startlocalenvironment[env_test]

  \show\envtest

\stoplocalenvironment

\show\envtest

\stoptext

On the command line I then get

> \envtest=macro:
->Test

...

> \envtest=undefined
5
  • There used to be a macro named \startlocalenvironment ... \stoplocalenvironment, but it did something different. A commented out definition is still in file-job.mkvi
    – Aditya
    Jun 5, 2017 at 6:12
  • Since this particular situation is so simple, I think I'll stick with @Aditya's \setups method for now. I'll definitely keep this in mind if I need a particularly complex environment, though! And just to point it out, there's a builtin version of \gobblearg mentioned on the wiki (on "System Macros/Handling Arguments"): \gobbleoneargument. Not sure how well it works for optional arguments, or even the standard ones, but it's there.
    – WovenTales
    Jun 5, 2017 at 6:13
  • @WovenTales This version of \gobblearg is different from \gobbleoneargument (note the space after #1). Jun 5, 2017 at 6:20
  • @Aditya You are right. Looks more like some leftover from MKII, though. Jun 5, 2017 at 6:21
  • Right. I was forgetting spacing has meaning in TeX. I'm too used to languages that only care about the tokens.
    – WovenTales
    Jun 5, 2017 at 6:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .