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