1if not modules then modules = { } end modules ['back-exp-imp-tag'] = {
2 version = 1.001,
3 comment = "companion to back-exp.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11
12local tonumber = tonumber
13local todimen = number.todimen
14local sortedkeys, sortedhash, setmetatableindex, concat, insert = table.sortedkeys, table.sortedhash, table.setmetatableindex, table.concat, table.insert
15local settings_to_hash = utilities.parsers.settings_to_hash
16local lpegmatch = lpeg.match
17local formatters = string.formatters
18
19local references = structures.references
20local structurestags = structures.tags
21local taglist = structurestags.taglist
22local specifications = structurestags.specifications
23local properties = structurestags.properties
24local locatedtag = structurestags.locatedtag
25
26local backend = structurestags.backend
27
28local setattribute = backend.setattribute
29local extras = backend.extras
30local checks = backend.checks
31local fixes = backend.fixes
32local listdata = backend.listdata
33local finalizers = backend.finalizers
34local usedstyles = backend.usedstyles
35local usedimages = backend.usedimages
36local referencehash = backend.referencehash
37local destinationhash = backend.destinationhash
38
39local implement = interfaces.implement
40
41do
42
43 local itemgroups = { }
44
45 local function setitemgroup(packed,level,symbol)
46 itemgroups[locatedtag("itemgroup")] = {
47 packed = packed,
48 symbol = symbol,
49 level = level,
50 }
51 end
52
53 local function setitem(kind)
54 itemgroups[locatedtag("item")] = {
55 kind = kind,
56 }
57 end
58
59 function extras.itemgroup(di,element,n,fulltag)
60 local hash = itemgroups[fulltag]
61 if hash then
62 setattribute(di,"packed",hash.packed and "yes" or nil)
63 setattribute(di,"symbol",hash.symbol)
64 setattribute(di,"level",hash.level)
65 end
66 end
67
68 function extras.item(di,element,n,fulltag)
69 local hash = itemgroups[fulltag]
70 if hash then
71 local kind = hash.kind
72 if kind and kind ~= "" then
73 setattribute(di,"kind",kind)
74 end
75 end
76 end
77
78 implement {
79 name = "settagitemgroup",
80 actions = setitemgroup,
81 arguments = { "boolean", "integer", "string" }
82 }
83
84 implement {
85 name = "settagitem",
86 actions = setitem,
87 arguments = "string"
88 }
89
90 structurestags.setitemgroup = setitemgroup
91 structurestags.setitem = setitem
92
93end
94
95do
96
97 local registered = structures.sections.registered
98
99 local function resolve(di,element,n,fulltag)
100 local data = listdata[fulltag]
101 if data then
102 extras.addreference(di,data.references)
103 return true
104 else
105 local data = di.data
106 if data then
107 for i=1,#data do
108 local di = data[i]
109 if di then
110 local ft = di.fulltag
111 if ft and resolve(di,element,n,ft) then
112 return true
113 end
114 end
115 end
116 end
117 end
118 end
119
120 function extras.section(di,element,n,fulltag)
121 local r = registered[specifications[fulltag].detail]
122 if r then
123 setattribute(di,"level",r.level)
124 end
125 resolve(di,element,n,fulltag)
126 end
127
128 local floats = { }
129
130 local function setfloat(options,method)
131 floats[locatedtag("float")] = {
132 options = options,
133 method = method,
134 }
135 end
136
137 function extras.float(di,element,n,fulltag)
138 local hash = floats[fulltag]
139 if hash then
140 local method = hash.method
141 if not method or method == "" then
142 method = "here"
143 end
144 setattribute(di,"method",method)
145 local options = hash.options
146 if options and options ~= "" then
147 options = settings_to_hash(options)
148 options[method] = nil
149 options = concat(sortedkeys(options),",")
150 if #options > 0 then
151 setattribute(di,"options",options)
152 end
153 end
154 end
155 resolve(di,element,n,fulltag)
156 end
157
158 implement {
159 name = "settagfloat",
160 actions = setfloat,
161 arguments = "2 strings",
162 }
163
164 structurestags.setfloat = setfloat
165
166end
167
168do
169
170 local registered = { }
171
172 local function setformulacontent(n)
173 registered[locatedtag("formulacontent")] = {
174 n = n,
175 }
176 end
177
178 function extras.formulacontent(di,element,n,fulltag)
179 local r = registered[fulltag]
180 if r then
181 setattribute(di,"n",r.n)
182 end
183 end
184
185 implement {
186 name = "settagformulacontent",
187 actions = setformulacontent,
188 arguments = "integer",
189 }
190
191 structurestags.setformulacontent = setformulacontent
192
193end
194
195do
196
197 local symbols = { }
198
199 local function settagdelimitedsymbol(symbol)
200 symbols[locatedtag("delimitedsymbol")] = {
201 symbol = symbol,
202 }
203 end
204
205 function extras.delimitedsymbol(di,element,n,fulltag)
206 local hash = symbols[fulltag]
207 if hash then
208 setattribute(di,"symbol",hash.symbol or nil)
209 end
210 end
211
212 implement {
213 name = "settagdelimitedsymbol",
214 actions = settagdelimitedsymbol,
215 arguments = "string"
216 }
217
218 structurestags.settagdelimitedsymbol = settagdelimitedsymbol
219
220end
221
222
223do
224
225 local symbols = { }
226
227 local function settagsubsentencesymbol(symbol)
228 symbols[locatedtag("subsentencesymbol")] = {
229 symbol = symbol,
230 }
231 end
232
233 function extras.subsentencesymbol(di,element,n,fulltag)
234 local hash = symbols[fulltag]
235 if hash then
236 setattribute(di,"symbol",hash.symbol or nil)
237 end
238 end
239
240 implement {
241 name = "settagsubsentencesymbol",
242 actions = settagsubsentencesymbol,
243 arguments = "string"
244 }
245
246 structurestags.settagsubsentencesymbol = settagsubsentencesymbol
247
248end
249
250do
251
252 local synonyms = { }
253 local sortings = { }
254
255 local function setsynonym(tag)
256 synonyms[locatedtag("synonym")] = tag
257 end
258
259 function extras.synonym(di,element,n,fulltag)
260 local tag = synonyms[fulltag]
261 if tag then
262 setattribute(di,"tag",tag)
263 end
264 end
265
266 local function setsorting(tag)
267 sortings[locatedtag("sorting")] = tag
268 end
269
270 function extras.sorting(di,element,n,fulltag)
271 local tag = sortings[fulltag]
272 if tag then
273 setattribute(di,"tag",tag)
274 end
275 end
276
277 implement {
278 name = "settagsynonym",
279 actions = setsynonym,
280 arguments = "string"
281 }
282
283 implement {
284 name = "settagsorting",
285 actions = setsorting,
286 arguments = "string"
287 }
288
289 structurestags.setsynonym = setsynonym
290 structurestags.setsorting = setsorting
291
292end
293
294do
295
296 local descriptions = { }
297 local symbols = { }
298 local linked = { }
299
300
301
302 local function setnotation(tag,n)
303
304 local nd = structures.notes.get(tag,n)
305 if nd then
306 local references = nd.references
307 descriptions[references and references.internal] = locatedtag("description")
308 end
309 end
310
311 local function setnotationsymbol(tag,n)
312 local nd = structures.notes.get(tag,n)
313 if nd then
314 local references = nd.references
315 symbols[references and references.internal] = locatedtag("descriptionsymbol")
316 end
317 end
318
319 function finalizers.descriptions(tree)
320 local n = 0
321 for id, tag in sortedhash(descriptions) do
322 local sym = symbols[id]
323 if sym then
324 n = n + 1
325 linked[tag] = n
326 linked[sym] = n
327 end
328 end
329 end
330
331 function extras.description(di,element,n,fulltag)
332 local id = linked[fulltag]
333 if id then
334 setattribute(di,"insert",id)
335 end
336 end
337
338 function extras.descriptionsymbol(di,element,n,fulltag)
339 local id = linked[fulltag]
340 if id then
341 setattribute(di,"insert",id)
342 end
343 end
344
345 implement {
346 name = "settagnotation",
347 actions = setnotation,
348 arguments = { "string", "integer" }
349 }
350
351 implement {
352 name = "settagnotationsymbol",
353 actions = setnotationsymbol,
354 arguments = { "string", "integer" }
355 }
356
357 structurestags.setnotation = setnotation
358 structurestags.setnotationsymbol = setnotationsymbol
359
360end
361
362
363do
364
365 local strippedtag = structurestags.strip
366
367 local highlight = { }
368 local construct = { }
369
370 usedstyles.highlight = highlight
371 usedstyles.construct = construct
372
373 local function sethighlight(name,style,color,mode)
374 if not highlight[name] then
375 highlight[name] = {
376 style = style,
377 color = color,
378 mode = mode == 1 and "display" or nil,
379 }
380 end
381 end
382
383 local function setconstruct(name,style,color,mode)
384 if not construct[name] then
385 construct[name] = {
386 style = style,
387 color = color,
388 mode = mode == 1 and "display" or nil,
389 }
390 end
391 end
392
393 implement {
394 name = "settagconstruct",
395 actions = setconstruct,
396 arguments = { "string", "string", "integer", "integer" }
397 }
398
399 implement {
400 name = "settaghighlight",
401 actions = sethighlight,
402 arguments = { "string", "string", "integer", "integer" }
403 }
404
405 structurestags.sethighlight = sethighlight
406 structurestags.setconstruct = setconstruct
407
408end
409
410do
411
412 local f_id = formatters["%s-%s"]
413 local image = { }
414 usedimages.image = image
415
416 structurestags.usewithcare.images = image
417
418 local function setfigure(name,used,page,width,height,label)
419 local fulltag = locatedtag("image")
420 local spec = specifications[fulltag]
421 if spec then
422 local page = tonumber(page)
423 image[fulltag] = {
424 id = f_id(spec.tagname,spec.tagindex),
425 name = name,
426 used = used,
427 page = page and page > 1 and page or nil,
428 width = todimen(width, "cm","%0.3F%s"),
429 height = todimen(height,"cm","%0.3F%s"),
430 label = label,
431 }
432 else
433
434 end
435 end
436
437 function extras.image(di,element,n,fulltag)
438 local data = image[fulltag]
439 if data then
440 setattribute(di,"name",data.name)
441 setattribute(di,"page",data.page)
442 setattribute(di,"id",data.id)
443 setattribute(di,"width",data.width)
444 setattribute(di,"height",data.height)
445 setattribute(di,"label",data.height)
446 end
447 end
448
449 implement {
450 name = "settagfigure",
451 actions = setfigure,
452 arguments = { "string", "string", "string", "dimen", "dimen", "string" }
453 }
454
455 structurestags.setfigure = setfigure
456
457end
458
459do
460
461 local combinations = { }
462
463 local function setcombination(nx,ny)
464 combinations[locatedtag("combination")] = {
465 nx = nx,
466 ny = ny,
467 }
468 end
469
470 function extras.combination(di,element,n,fulltag)
471 local data = combinations[fulltag]
472 if data then
473 setattribute(di,"nx",data.nx)
474 setattribute(di,"ny",data.ny)
475 end
476 end
477
478 implement {
479 name = "settagcombination",
480 actions = setcombination,
481 arguments = { "integer", "integer" }
482 }
483
484 structurestags.setcombination = setcombination
485
486end
487
488do
489
490 local function hascontent(data)
491 for i=1,#data do
492 local di = data[i]
493 if not di or di.tg == "ignore" then
494
495 else
496 local content = di.content
497 if content == " " then
498
499 elseif content then
500 return true
501 else
502 local d = di.data
503 if d and #d > 0 and hascontent(d) then
504 return true
505 end
506 end
507 end
508 end
509 end
510
511 local tabledata = { }
512
513 local function settablecell(rows,columns,align)
514 if align > 0 or rows > 1 or columns > 1 then
515 tabledata[locatedtag("tablecell")] = {
516 rows = rows,
517 columns = columns,
518 align = align,
519 }
520 end
521 end
522
523 local function gettablecell(fulltag)
524 return tabledata[fulltag]
525 end
526
527 function extras.tablecell(di,element,n,fulltag)
528 local hash = tabledata[fulltag]
529 if hash then
530 local columns = hash.columns
531 if columns and columns > 1 then
532 setattribute(di,"columns",columns)
533 end
534 local rows = hash.rows
535 if rows and rows > 1 then
536 setattribute(di,"rows",rows)
537 end
538 local align = hash.align
539 if not align or align == 0 then
540
541 elseif align == 1 then
542 setattribute(di,"align","flushright")
543 elseif align == 2 then
544 setattribute(di,"align","middle")
545 elseif align == 3 then
546 setattribute(di,"align","flushleft")
547 end
548 end
549 end
550
551 local tabulatedata = { }
552
553 local function settabulatecell(align,kind)
554 if align > 0 or kind > 0 then
555 tabulatedata[locatedtag("tabulatecell")] = {
556 align = align,
557 kind = kind,
558 }
559 end
560 end
561
562 local function gettabulatecell(fulltag)
563 return tabulatedata[fulltag]
564 end
565
566 function extras.tabulate(di,element,n,fulltag)
567 local data = di.data
568 for i=1,#data do
569 local di = data[i]
570 if di.tg == "tabulaterow" and not hascontent(di.data) then
571 di.element = ""
572 end
573 end
574 end
575
576 function extras.tabulatecell(di,element,n,fulltag)
577 local hash = tabulatedata[fulltag]
578 if hash then
579 local align = hash.align
580 if not align or align == 0 then
581
582 elseif align == 1 then
583 setattribute(di,"align","flushleft")
584 elseif align == 2 then
585 setattribute(di,"align","flushright")
586 elseif align == 3 then
587 setattribute(di,"align","middle")
588 end
589 local kind = hash.kind
590 if kind == 1 then
591 setattribute(di,"kind","strong")
592 elseif kind == 2 then
593 setattribute(di,"kind","equals")
594 end
595 end
596 end
597
598 implement {
599 name = "settagtablecell",
600 actions = settablecell,
601 arguments = { "integer", "integer", "integer" }
602 }
603
604 implement {
605 name = "settagtabulatecell",
606 actions = settabulatecell,
607 arguments = { "integer", "integer" },
608 }
609
610 structurestags.settablecell = settablecell
611 structurestags.gettablecell = gettablecell
612 structurestags.settabulatecell = settabulatecell
613 structurestags.gettabulatecell = gettabulatecell
614
615end
616
617do
618
619
620
621 local p_stripper = lpeg.patterns.stripper
622
623 local function setregister(tag,n)
624 local data = structures.registers.get(tag,n)
625 if data then
626 referencehash[locatedtag("registerlocation")] = data
627 end
628 end
629
630 function extras.registerlocation(di,element,n,fulltag)
631 local data = referencehash[fulltag]
632 if type(data) == "table" then
633 extras.addinternal(di,data.references)
634 return true
635 else
636
637 end
638 end
639
640 function extras.registerpages(di,element,n,fulltag)
641 local data = di.data
642 for i=1,#data do
643 local d = data[i]
644 if d.content == " " then
645 d.content = ""
646 end
647 end
648 end
649
650 function extras.registerseparator(di,element,n,fulltag)
651 local data = di.data
652 for i=1,#data do
653 local d = data[i]
654 local c = d.content
655 if type(c) == "string" then
656 d.content = lpegmatch(p_stripper,c)
657 end
658 end
659 end
660
661 implement {
662 name = "settagregister",
663 actions = setregister,
664 arguments = { "string", "integer" }
665 }
666
667 structurestags.setregister = setregister
668
669end
670
671do
672
673
674
675 local function setlist(n)
676 local data = structures.lists.getresult(n)
677 if data then
678 referencehash[locatedtag("listitem")] = data
679 end
680 end
681
682 function extras.listitem(di,element,n,fulltag)
683 local data = referencehash[fulltag]
684 if data then
685 extras.addinternal(di,data.references)
686 return true
687 end
688 end
689
690 implement {
691 name = "settaglist",
692 actions = setlist,
693 arguments = "integer"
694 }
695
696 structurestags.setlist = setlist
697
698end
699
700do
701
702 local usedpublications = { }
703 local tagsindatasets = setmetatableindex("table")
704 local serialize = false
705
706 local function setpublication(dataset,tag,rendering)
707 usedpublications[locatedtag("publication")] = {
708 dataset = dataset,
709 tag = tag,
710 rendering = rendering
711 }
712 tagsindatasets[dataset][tag] = true
713 if not serialize then
714 structures.tags.registerextradata("btx",function()
715 local t = { "<btxdata>"}
716 for dataset, used in sortedhash(tagsindatasets) do
717 t[#t+1] = publications.converttoxml(dataset,true,false,true,false,true,true)
718 end
719 t[#t+1] = "</btxdata>"
720 return concat(t,"\n")
721 end)
722 end
723 end
724
725 function extras.publication(di,element,n,fulltag)
726 local hash = usedpublications[fulltag]
727 if hash then
728 setattribute(di,"dataset",hash.dataset)
729 setattribute(di,"tag",hash.tag)
730 end
731 end
732
733 implement {
734 name = "settagpublication",
735 actions = setpublication,
736 arguments = "2 strings"
737 }
738
739 structurestags.setpublication = setpublication
740
741end
742
743do
744
745 local usedparagraphs = { }
746
747 local function setparagraph(align)
748 if align ~= "" then
749 usedparagraphs[locatedtag("paragraph")] = {
750 align = align,
751 }
752 end
753 end
754
755 function extras.paragraph(di,element,n,fulltag)
756 local hash = usedparagraphs[fulltag]
757 if hash then
758 setattribute(di,"align",hash.align)
759 end
760 end
761
762 implement {
763 name = "settagparagraph",
764 actions = setparagraph,
765 arguments = "string"
766 }
767
768 structurestags.setparagraph = setparagraph
769
770end
771
772do
773
774 local marginanchors = { }
775 local margincontent = { }
776
777 function checks.margintext(di)
778 local i = marginanchors[di.fulltag]
779 margincontent[i] = di
780 end
781
782 function checks.marginanchor(di)
783 local i = marginanchors[di.fulltag]
784 local d = margincontent[i]
785
786 di.attribute = d.attribute
787 di.data = d.data
788 di.detail = d.detail
789 di.element = d.element
790 di.fulltag = d.fulltag
791 di.nature = d.nature
792 di.samepar = true
793 di.tg = d.tg
794
795 d.skip = "ignore"
796 end
797
798 implement {
799 name = "settagmargintext",
800 arguments = "integer",
801 actions = function(n)
802 marginanchors[locatedtag("margintext")] = n
803 end
804 }
805
806 implement {
807 name = "settagmarginanchor",
808 arguments = "integer",
809 actions = function(n)
810 marginanchors[locatedtag("marginanchor")] = n
811 end
812 }
813
814end
815
816do
817
818 function fixes.linenumber(di,data,i)
819 local ni = data[i+1]
820 if ni then
821 if ni.data then
822 while true do
823 local d = ni.data[1]
824 if d then
825 local e = d.element
826 if e then
827 if e == "line" or e == "verbatimline" then
828 insert(d.data,1,di)
829 data[i] = false
830 return
831 else
832 ni = d
833 end
834 else
835 return
836 end
837 else
838 return
839 end
840 end
841 end
842 end
843 end
844
845end
846
847
848do
849
850 local usedcodepoints = { }
851
852 local function checkcodepoint(di,element,n,fulltag)
853 local unicode = usedcodepoints[fulltag]
854 if unicode then
855 setattribute(di,"codepoint",unicode)
856 end
857 end
858
859 local function setcodepoint(tag,unicode)
860 usedcodepoints[locatedtag(tag)] = unicode
861 if not extras[tag] then
862 extras[tag] = checkcodepoint
863 end
864 end
865
866 implement {
867 name = "settagcodepoint",
868 actions = setcodepoint,
869 arguments = { "argument", "integer" },
870 }
871
872 structurestags.setcodepoint = setcodepoint
873
874end
875 |