wortsammler 1.0.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +46 -4
- data/.gitpod.Dockerfile +32 -0
- data/.gitpod.yml +1 -0
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/202_wortsammler-gem.iml +119 -0
- data/.idea/compiler.xml +22 -0
- data/.idea/encodings.xml +6 -0
- data/.idea/inspectionProfiles/profiles_settings.xml +7 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +9 -0
- data/.idea/vcs.xml +7 -0
- data/Gemfile +1 -0
- data/README.md +25 -28
- data/Rakefile +3 -3
- data/changelog.md +17 -1
- data/lib/wortsammler.rb +61 -54
- data/lib/wortsammler/class.Traceable.md.rb +9 -7
- data/lib/wortsammler/class.Traceable.rb +74 -60
- data/lib/wortsammler/class.proolib.rb +1102 -982
- data/lib/wortsammler/mdTraceParser.treetop +2 -2
- data/lib/wortsammler/version.rb +1 -1
- data/resources/default.wortsammler.latex +4 -3
- data/resources/main.md +1 -1
- data/resources/pandocdefault.docx +0 -0
- data/resources/pandocdefault.epub +70 -0
- data/resources/pandocdefault.html +73 -0
- data/resources/pandocdefault.latex +403 -0
- data/resources/sample_the-sample-document.yaml +27 -1
- data/spec/TC_EXP_001.md +2 -1
- data/spec/Zupfnoter.jpg +0 -0
- data/spec/tc_exp_003_reference.txt +14 -29
- data/spec/test_beautify.md +13 -1
- data/spec/test_beautify_reference.md +17 -3
- data/spec/test_mkindex_reference.txt +9 -38
- data/spec/test_slides.md +38 -0
- data/spec/wortsammler_spec.rb +186 -150
- data/testproject.xx/30_Sources/001_Main/main.md +273 -0
- data/testproject.xx/30_Sources/900_snippets/snippets.xlsx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.docx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.html +145 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.latex +416 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.beamer.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.docx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.html +145 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.latex +416 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.docx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.html +145 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.latex +416 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_review.latex +582 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_review.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/RS_Main.traces.md +56 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/ZGEN_Reqtrace.graphml +119 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/ZGEN_Reqtrace.md +50 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/ZGEN_ReqtraceCompare.txt +52 -0
- data/testproject.xx/30_Sources/ZSUPP_Manifests/sample_the-sample-document.yaml +79 -0
- data/testproject.xx/30_Sources/ZSUPP_Styles/default.wortsammler.latex +321 -0
- data/testproject.xx/30_Sources/ZSUPP_Styles/logo.jpg +0 -0
- data/testproject.xx/30_Sources/ZSUPP_Tools/rakefile.rb +5 -0
- data/testresults/wortsammler_testresults.html +49 -466
- data/uninstall-pandoc.pl +79 -0
- data/wortsammler.gemspec +7 -4
- metadata +84 -14
- data/testresults/wortsammler_testresults.log +0 -325
- data/wortsammler-gem.sublime-project +0 -8
@@ -1,982 +1,1102 @@
|
|
1
|
-
#
|
2
|
-
# This script converts the trace-References in a markdown file
|
3
|
-
# to hot references.
|
4
|
-
#
|
5
|
-
# usage prepareTracingInPandoc <infile> <format> <outfile>
|
6
|
-
#
|
7
|
-
# Traces are formatted according to [RS_DM_008].
|
8
|
-
#
|
9
|
-
# Trace itself becomes the target, uptraces are converted to references.
|
10
|
-
#
|
11
|
-
# Traces can also be referenced by
|
12
|
-
#
|
13
|
-
#
|
14
|
-
require 'rubygems'
|
15
|
-
require 'yaml'
|
16
|
-
require 'tmpdir'
|
17
|
-
require 'nokogiri'
|
18
|
-
require "rubyXL"
|
19
|
-
require 'logger'
|
20
|
-
require 'wortsammler/latex_helper'
|
21
|
-
|
22
|
-
|
23
|
-
Encoding.default_external = Encoding::UTF_8
|
24
|
-
Encoding.default_internal = Encoding::UTF_8
|
25
|
-
|
26
|
-
# TODO: make these patterns part of the configuration
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
#
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
end
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
class
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
#
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
#
|
450
|
-
|
451
|
-
#
|
452
|
-
#
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
@log
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
#
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
l.gsub!(
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
#
|
641
|
-
#
|
642
|
-
#
|
643
|
-
# @param [String]
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
#
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
#
|
693
|
-
#
|
694
|
-
#
|
695
|
-
#
|
696
|
-
#
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
}
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
#
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
1
|
+
#
|
2
|
+
# This script converts the trace-References in a markdown file
|
3
|
+
# to hot references.
|
4
|
+
#
|
5
|
+
# usage prepareTracingInPandoc <infile> <format> <outfile>
|
6
|
+
#
|
7
|
+
# Traces are formatted according to [RS_DM_008].
|
8
|
+
#
|
9
|
+
# Trace itself becomes the target, uptraces are converted to references.
|
10
|
+
#
|
11
|
+
# Traces can also be referenced by
|
12
|
+
#
|
13
|
+
#
|
14
|
+
require 'rubygems'
|
15
|
+
require 'yaml'
|
16
|
+
require 'tmpdir'
|
17
|
+
require 'nokogiri'
|
18
|
+
require "rubyXL"
|
19
|
+
require 'logger'
|
20
|
+
require 'wortsammler/latex_helper'
|
21
|
+
|
22
|
+
|
23
|
+
Encoding.default_external = Encoding::UTF_8
|
24
|
+
Encoding.default_internal = Encoding::UTF_8
|
25
|
+
|
26
|
+
# TODO: make these patterns part of the configuration
|
27
|
+
|
28
|
+
PANDOC_EXE ="pandoc_2.5 " # wat
|
29
|
+
LATEX_EXE = "xelatex "
|
30
|
+
|
31
|
+
ANY_ANCHOR_PATTERN = /<a\s+id=\"([^\"]+)\"\/>/
|
32
|
+
ANY_REF_PATTERN = /<a\s+href=\"#([^\"]+)\"\>([^<]*)<\/a>/
|
33
|
+
|
34
|
+
TRACE_ANCHOR_PATTERN = /\[(\w+_\w+_\w+)\](\s*\*\*)/
|
35
|
+
UPTRACE_REF_PATTERN = /\}\( ((\w+_\w+_\w+) (,\s*\w+_\w+_\w+)*)\)/x
|
36
|
+
TRACE_REF_PATTERN = /->\[(\w+_\w+_\w+)\]/
|
37
|
+
|
38
|
+
# filename
|
39
|
+
# heading
|
40
|
+
# level
|
41
|
+
# pages to include
|
42
|
+
# pageclearance
|
43
|
+
INCLUDE_PDF_PATTERN = /^\s+~~PDF\s+"(.+)" \s+ "(.+)" \s* (\d*) \s* (\d+-\d+)? \s* (clearpage|cleardoublepage)?~~/x
|
44
|
+
|
45
|
+
INCLUDE_MD_PATTERN = /(\s*)~~MD\s+\\?"(.+)\\?"~~/x
|
46
|
+
|
47
|
+
SNIPPET_PATTERN = /(\s*)~~SN \s+ (\w+)~~/x
|
48
|
+
|
49
|
+
EMBEDDED_IMAGE_PATTERN = /~~EMBED\s+ "(.+)" \s+ (r|l|i|o) \s+ (.+) \s+ (.+)~~/x
|
50
|
+
|
51
|
+
EXPECTED_RESULT_PATTERN = /(^\s*)[~`]{3,}\s*\{.expectedResult\s+label=\"([A-Za-z]+\\?_[A-Za-z]+\\?_[0-9]+)\"}\s([^~`]+)[~`]{3,}/x
|
52
|
+
|
53
|
+
PLANTUML_PATTERN = /[~`]{3,}\s+{\.plantuml}\s+@startuml\s+([^\n]+)(\s+title\s+([^\n]+))?[^~`]+ v/x
|
54
|
+
|
55
|
+
#
|
56
|
+
# This mixin convertes a file path to the os Path representation
|
57
|
+
# todo maybe replace this by a builtin ruby stuff such as "pathname"
|
58
|
+
#
|
59
|
+
class String
|
60
|
+
# convert the string to a path notation of the current operating system
|
61
|
+
def to_osPath
|
62
|
+
gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
|
63
|
+
end
|
64
|
+
|
65
|
+
# convert the string to a path notation of ruby.
|
66
|
+
def to_rubyPath
|
67
|
+
gsub(File::ALT_SEPARATOR || File::SEPARATOR, File::SEPARATOR)
|
68
|
+
end
|
69
|
+
|
70
|
+
# adding quotes around the string. Main purpose is to escape blanks
|
71
|
+
# in file paths.
|
72
|
+
def esc
|
73
|
+
"\"#{self}\""
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
#
|
79
|
+
# This class provides methods to tweak the reference according to the
|
80
|
+
# target document format
|
81
|
+
#
|
82
|
+
#
|
83
|
+
class ReferenceTweaker
|
84
|
+
|
85
|
+
#This attribute keeps the target format
|
86
|
+
attr_accessor :target, :log
|
87
|
+
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
# this prepares the reference in the target format
|
92
|
+
#
|
93
|
+
# :string: the Id of the referenced Traceable
|
94
|
+
def prepareTraceReferences(string)
|
95
|
+
result=string.gsub(/\s*/, "").split(",").map { |trace|
|
96
|
+
itrace = mkInternalTraceId(trace)
|
97
|
+
texTrace = mkTexTraceDisplay(trace)
|
98
|
+
if @target == "pdf" then
|
99
|
+
"\\hyperlink{#{itrace}}{#{texTrace}}"
|
100
|
+
else
|
101
|
+
"[#{trace}](\##{itrace})"
|
102
|
+
end
|
103
|
+
}
|
104
|
+
result.join(", ")
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
#
|
109
|
+
# [prepareExpectedResults description]
|
110
|
+
# @param label [type] [description]
|
111
|
+
# @param body [type] [description]
|
112
|
+
#
|
113
|
+
# @return [type] [description]
|
114
|
+
def prepareExpectedResults(indent="", original_label, body)
|
115
|
+
result_items=body.split("- ")[1..-1].map { |i| i.strip }
|
116
|
+
result = ["\\begin{Form}"]
|
117
|
+
|
118
|
+
label=original_label.gsub(/_/, "-")
|
119
|
+
j ="00"
|
120
|
+
result << result_items.map { |i|
|
121
|
+
j = j.next
|
122
|
+
"\\CheckBox[name=#{label}-#{j}]{} #{i}"
|
123
|
+
}
|
124
|
+
result << "\\vspace{1em}"
|
125
|
+
result << "\\ChoiceMenu[combo, name=#{label}-verdict, default=none]{Test verdict:}{none, ok-30, ok-60, ok, fail, pending}"
|
126
|
+
result << "\\vspace{1em}"
|
127
|
+
result << ["\\TextField[ name=#{label}-comment , width=40em, height=2cm, multiline=true, backgroundcolor={0.9 0.9 0.9}] {}"]
|
128
|
+
result << ["\\end{Form}"]
|
129
|
+
|
130
|
+
unless $1.nil? then
|
131
|
+
leading_whitespace=$1.split("\n", 100)
|
132
|
+
leading_lines =leading_whitespace[0..-1].join("\n")
|
133
|
+
leading_spaces =leading_whitespace.last || ""
|
134
|
+
replacetext =leading_lines+replacetext_raw.gsub("\n", "\n#{leading_spaces}")
|
135
|
+
end
|
136
|
+
|
137
|
+
result=result.compact.flatten.map { |i| "#{indent}#{i}" }
|
138
|
+
result.join("\n#{indent}\n")
|
139
|
+
end
|
140
|
+
|
141
|
+
# this tweaks the reference-Id to be comaptible as TeX label
|
142
|
+
# private methd
|
143
|
+
def mkInternalTraceId(string)
|
144
|
+
string.gsub("_", "-")
|
145
|
+
end
|
146
|
+
|
147
|
+
# this tweaks the reference-id to be displayed in TeX
|
148
|
+
# private method
|
149
|
+
def mkTexTraceDisplay(trace)
|
150
|
+
trace.gsub("_", "\\_")
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
#
|
155
|
+
# This replaces markdown inlays
|
156
|
+
# it is a subroutine which is called
|
157
|
+
# recursively
|
158
|
+
# todo: handle indentation
|
159
|
+
#
|
160
|
+
# @param text [String] text in which the markdown inlays shall be processed
|
161
|
+
# @return [String] The resulting text
|
162
|
+
def replace_md_inlay(text)
|
163
|
+
text.gsub!(INCLUDE_MD_PATTERN) { |m|
|
164
|
+
infile = $2.gsub("\\_", "_")
|
165
|
+
if File.exist?(infile) then
|
166
|
+
replacetext_raw = File.open(infile, :encoding => 'bom|utf-8').read
|
167
|
+
unless $1.nil? then
|
168
|
+
leading_whitespace = $1.split("\n", 100)
|
169
|
+
leading_lines = leading_whitespace[0 .. -1].join("\n")
|
170
|
+
leading_spaces = leading_whitespace.last || ""
|
171
|
+
replacetext = leading_lines + replacetext_raw.gsub("\n", "\n#{leading_spaces}")
|
172
|
+
else
|
173
|
+
replacetext = replacetext_raw
|
174
|
+
end
|
175
|
+
else
|
176
|
+
replacetext = ""
|
177
|
+
@log.warn("File not found: #{$2}")
|
178
|
+
end
|
179
|
+
result = replace_md_inlay(replacetext)
|
180
|
+
result
|
181
|
+
}
|
182
|
+
text
|
183
|
+
end
|
184
|
+
|
185
|
+
public
|
186
|
+
|
187
|
+
# constructor
|
188
|
+
# :target: the target format
|
189
|
+
# in which the referneces shall be represented
|
190
|
+
#todo: improve logger approach
|
191
|
+
def initialize(target, logger=nil)
|
192
|
+
@target=target
|
193
|
+
|
194
|
+
@log=logger || $logger || nil
|
195
|
+
|
196
|
+
if @log == nil
|
197
|
+
@log = Logger.new(STDOUT)
|
198
|
+
@log.level = Logger::INFO
|
199
|
+
@log.datetime_format = "%Y-%m-%d %H:%M:%S"
|
200
|
+
@log.formatter = proc do |severity, datetime, progname, msg|
|
201
|
+
"#{datetime}: #{msg}\n"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# this does the postprocessing
|
207
|
+
# of the file
|
208
|
+
# in particluar handle wortsammler's specific syntax.
|
209
|
+
def prepareFile(infile, outfile)
|
210
|
+
|
211
|
+
infileIo=File.new(infile)
|
212
|
+
text = infileIo.readlines.join
|
213
|
+
infileIo.close
|
214
|
+
|
215
|
+
#include pdf files
|
216
|
+
|
217
|
+
if @target == "pdf"
|
218
|
+
text.gsub!(INCLUDE_PDF_PATTERN) { |m|
|
219
|
+
|
220
|
+
if $4
|
221
|
+
pages="[pages=#{$4}]"
|
222
|
+
else
|
223
|
+
pages=""
|
224
|
+
end
|
225
|
+
|
226
|
+
if $5
|
227
|
+
clearpage=$5
|
228
|
+
else
|
229
|
+
clearpage="cleardoublepage"
|
230
|
+
end
|
231
|
+
|
232
|
+
if $3.length > 0
|
233
|
+
level=$3
|
234
|
+
else
|
235
|
+
level=9
|
236
|
+
end
|
237
|
+
|
238
|
+
"\n\n\\#{clearpage}\n\\bookmark[level=#{level},page=\\thepage]{#{$2}}\n\\includepdf#{pages}{#{$1}}"
|
239
|
+
}
|
240
|
+
else #if not pdf then it gets a regular external link
|
241
|
+
text.gsub!(INCLUDE_PDF_PATTERN) { |m|
|
242
|
+
"[#{$2}](#{$1})"
|
243
|
+
}
|
244
|
+
end
|
245
|
+
|
246
|
+
# include Markdown files
|
247
|
+
#
|
248
|
+
#
|
249
|
+
text = replace_md_inlay(text)
|
250
|
+
|
251
|
+
|
252
|
+
# embed images
|
253
|
+
#
|
254
|
+
if @target == "pdf"
|
255
|
+
text.gsub!(EMBEDDED_IMAGE_PATTERN) { |m|
|
256
|
+
"\\wsembedimage{#{$1}}{#{$2}}{#{$3}}{#{$4}}"
|
257
|
+
}
|
258
|
+
else #if not pdf then it gets a regular image
|
259
|
+
text.gsub!(EMBEDDED_IMAGE_PATTERN) { |m|
|
260
|
+
""
|
261
|
+
}
|
262
|
+
end
|
263
|
+
|
264
|
+
#inject the anchors for references to traces ->[traceid]
|
265
|
+
if @target == "pdf" then
|
266
|
+
text.gsub!(TRACE_ANCHOR_PATTERN) { |m| "[#{$1}]#{$2}\\hypertarget{#{mkInternalTraceId($1)}}{}" }
|
267
|
+
else
|
268
|
+
text.gsub!(TRACE_ANCHOR_PATTERN) { |m| "<a id=\"#{mkInternalTraceId($1)}\">[#{$1}]</a>#{$2}" }
|
269
|
+
end
|
270
|
+
|
271
|
+
#substitute arbitrary anchors for arbitrary targets <a id="">
|
272
|
+
if @target == "pdf" then
|
273
|
+
text.gsub!(ANY_ANCHOR_PATTERN) { |m| "\\hypertarget{#{mkInternalTraceId($1)}}{}" }
|
274
|
+
else
|
275
|
+
# it is already html
|
276
|
+
end
|
277
|
+
|
278
|
+
#substitute arbitrary document internal references <a href=""></a>
|
279
|
+
if @target == "pdf" then
|
280
|
+
text.gsub!(ANY_REF_PATTERN) { |m| "\\hyperlink{#{$1}}{#{mkTexTraceDisplay($2)}}" }
|
281
|
+
else
|
282
|
+
# it is already html
|
283
|
+
end
|
284
|
+
|
285
|
+
# substitute the uptrace references
|
286
|
+
text.gsub!(UPTRACE_REF_PATTERN) { |m| "}(#{prepareTraceReferences($1)})" }
|
287
|
+
|
288
|
+
# substitute the informal trace references
|
289
|
+
text.gsub!(TRACE_REF_PATTERN) { |m| "[#{prepareTraceReferences($1)}]" }
|
290
|
+
|
291
|
+
|
292
|
+
# substitute expected Results
|
293
|
+
#
|
294
|
+
#
|
295
|
+
if @target == "pdf" then
|
296
|
+
text.gsub!(EXPECTED_RESULT_PATTERN) { |m| "#{prepareExpectedResults($1, $2, $3)}" }
|
297
|
+
else
|
298
|
+
# it is already leave it as it is
|
299
|
+
end
|
300
|
+
|
301
|
+
# substitute plantuml
|
302
|
+
#
|
303
|
+
# note this is substituted in any case
|
304
|
+
#
|
305
|
+
#if @target == "pdf" then
|
306
|
+
text.gsub!(PLANTUML_PATTERN) { |m| "" }
|
307
|
+
|
308
|
+
#else
|
309
|
+
# it is already leave it as it is
|
310
|
+
#end
|
311
|
+
|
312
|
+
File.open(outfile, "w") { |f| f.puts(text) }
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
|
317
|
+
#
|
318
|
+
# This class handles the configuration of WortSammler framework
|
319
|
+
#
|
320
|
+
|
321
|
+
class ProoConfig
|
322
|
+
attr_reader :input, # An array with the input filenames
|
323
|
+
:outdir, # directory where to place the output files
|
324
|
+
:outname, # basis to determine the output files
|
325
|
+
:format, # array of output formats
|
326
|
+
:traceSortOrder, # Array of strings to determine the sort ord
|
327
|
+
:vars, # hash of variables for pandoc
|
328
|
+
:editions, # hash of editions for pandoc
|
329
|
+
:snippets, # Array of strings to determine snippet filenames
|
330
|
+
:upstream_tracefiles, # Array of strings to determine upstream tracefile names
|
331
|
+
:downstream_tracefile, # String to save downstram filename
|
332
|
+
:reqtracefile_base, # string to determine the requirements tracing results
|
333
|
+
:frontmatter, # Array of string to determine input filenames of frontmatter
|
334
|
+
:rootdir, # String directory of the configuration file
|
335
|
+
:stylefiles, # Hash of stylefiles path to pandoc latex style file
|
336
|
+
:mdreaderoptions, # string to be appended to -f markdown specifier in pandoc
|
337
|
+
:mdwriteroptions # string to be appendod to -t markdown in pandoc
|
338
|
+
|
339
|
+
|
340
|
+
# constructor
|
341
|
+
def initialize
|
342
|
+
@mdreaderoptions = %w{
|
343
|
+
+fenced_code_blocks
|
344
|
+
+compact_definition_lists
|
345
|
+
-space_in_atx_header
|
346
|
+
}.join()
|
347
|
+
|
348
|
+
@mdwriteroptions = %w{
|
349
|
+
-backtick_code_blocks
|
350
|
+
+fenced_code_blocks
|
351
|
+
+compact_definition_lists
|
352
|
+
+space_in_atx_header
|
353
|
+
+yaml_metadata_block
|
354
|
+
}.join()
|
355
|
+
end
|
356
|
+
|
357
|
+
# @param [String] configFileName name of the configfile (without .yaml)
|
358
|
+
# @param [Symbol] configSelect Default configuration. If not specified
|
359
|
+
# the very first entry in the config file
|
360
|
+
# will apply.
|
361
|
+
# TODO: not yet implemented.
|
362
|
+
# @return [ProoConfig] instance
|
363
|
+
def load_from_file(configFileName, configSelect=nil)
|
364
|
+
begin
|
365
|
+
config = YAML.load(File.new(configFileName))
|
366
|
+
rescue Exception => e
|
367
|
+
unless File.exist?(configFileName) then
|
368
|
+
$log.error "config file not found '#{configFileName}'"
|
369
|
+
else
|
370
|
+
$log.error "config file could not be loaded '#{configFileName}'"
|
371
|
+
if File.directory?(configFileName) then
|
372
|
+
# note that windows does not disinguish this.
|
373
|
+
$log.error "#{configFileName} is a directory"
|
374
|
+
end
|
375
|
+
$log.error "reason '#{e.message}'"
|
376
|
+
end
|
377
|
+
exit(false)
|
378
|
+
end
|
379
|
+
|
380
|
+
basePath = File.dirname(configFileName)
|
381
|
+
|
382
|
+
# this makes an absolute path based on the absolute path
|
383
|
+
# of the configuration file
|
384
|
+
expand_path =lambda do |lf|
|
385
|
+
File.expand_path("#{basePath}/#{lf}")
|
386
|
+
end
|
387
|
+
|
388
|
+
|
389
|
+
#activeConfigs=config.select{|x| [x[:name]] & ConfigSelet}
|
390
|
+
|
391
|
+
selectedConfig = config.first
|
392
|
+
#TODO: check the config file
|
393
|
+
#TODO: refactor the configuration processing
|
394
|
+
@input = selectedConfig[:input].map { |file| File.expand_path("#{basePath}/#{file}") }
|
395
|
+
@outdir = File.expand_path("#{basePath}/#{selectedConfig[:outdir]}")
|
396
|
+
@outname = selectedConfig[:outname]
|
397
|
+
@format = selectedConfig[:format]
|
398
|
+
@traceSortOrder = selectedConfig[:traceSortOrder]
|
399
|
+
@vars = selectedConfig[:vars] || {}
|
400
|
+
@editions = selectedConfig[:editions] || nil
|
401
|
+
|
402
|
+
@downstream_tracefile = selectedConfig[:downstream_tracefile] || nil
|
403
|
+
|
404
|
+
@reqtracefile_base = selectedConfig[:reqtracefile_base] #todo expand path
|
405
|
+
|
406
|
+
@upstream_tracefiles = selectedConfig[:upstream_tracefiles] || nil
|
407
|
+
@upstream_tracefiles = @upstream_tracefiles.map { |file| File.expand_path("#{basePath}/#{file}") } unless @upstream_tracefiles.nil?
|
408
|
+
@frontmatter = selectedConfig[:frontmatter] || nil
|
409
|
+
@frontmatter = selectedConfig[:frontmatter].map { |file| File.expand_path("#{basePath}/#{file}") } unless @frontmatter.nil?
|
410
|
+
@rootdir = basePath
|
411
|
+
|
412
|
+
@mdreaderoptions = selectedConfig[:mdreaderoptions].join() if selectedConfig[:mdreaderoptions]
|
413
|
+
@mdwriteroptions = selectedConfig[:mdwriteroptions].join() if selectedConfig[:mdwriteroptions]
|
414
|
+
|
415
|
+
|
416
|
+
stylefiles = selectedConfig[:stylefiles] || nil
|
417
|
+
if stylefiles.nil?
|
418
|
+
@stylefiles = {
|
419
|
+
:latex => expand_path.call("../ZSUPP_Styles/default.latex"),
|
420
|
+
:docx => expand_path.call("../ZSUPP_Styles/default.docx"),
|
421
|
+
:html => expand_path.call("../ZSUPP_Styles/default.css")
|
422
|
+
}
|
423
|
+
else
|
424
|
+
@stylefiles = stylefiles.map { |key, value| { key => expand_path.call(value) } }.reduce(:merge)
|
425
|
+
end
|
426
|
+
|
427
|
+
snippets = selectedConfig[:snippets]
|
428
|
+
if snippets.nil?
|
429
|
+
@snippets = nil
|
430
|
+
else
|
431
|
+
@snippets = snippets.map { |file| File.expand_path("#{basePath}/#{file}") }
|
432
|
+
end
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
|
437
|
+
#
|
438
|
+
# This class provides the major functionalites
|
439
|
+
#
|
440
|
+
# Note that it is called PandocBeautifier for historical reasons
|
441
|
+
#
|
442
|
+
# provides methods to Process a pandoc file
|
443
|
+
#
|
444
|
+
|
445
|
+
class PandocBeautifier
|
446
|
+
|
447
|
+
attr_accessor :log, :config
|
448
|
+
|
449
|
+
# the constructor
|
450
|
+
# @param [Logger] logger logger object to be applied.
|
451
|
+
# if none is specified, a default logger
|
452
|
+
# will be implemented
|
453
|
+
def initialize(logger = nil)
|
454
|
+
|
455
|
+
@markdown_output_switches = %w{
|
456
|
+
+backtick_code_blocks
|
457
|
+
-fenced_code_blocks
|
458
|
+
+compact_definition_lists
|
459
|
+
+space_in_atx_header
|
460
|
+
+yaml_metadata_block
|
461
|
+
}.join()
|
462
|
+
|
463
|
+
@markdown_input_switches = %w{
|
464
|
+
+smart
|
465
|
+
+backtick_code_blocks
|
466
|
+
+fenced_code_blocks
|
467
|
+
+compact_definition_lists
|
468
|
+
-space_in_atx_header
|
469
|
+
}.join()
|
470
|
+
|
471
|
+
|
472
|
+
@view_pattern = /~~ED((\s*(\w+))*)~~/
|
473
|
+
# @view_pattern = /<\?ED((\s*(\w+))*)\?>/
|
474
|
+
@tempdir = Dir.mktmpdir
|
475
|
+
|
476
|
+
@config = ProoConfig.new()
|
477
|
+
|
478
|
+
@log=logger || $logger || nil
|
479
|
+
|
480
|
+
if @log == nil
|
481
|
+
@log = Logger.new(STDOUT)
|
482
|
+
@log.level = Logger::INFO
|
483
|
+
@log.datetime_format = "%Y-%m-%d %H:%M:%S"
|
484
|
+
@log.formatter = proc do |severity, datetime, progname, msg|
|
485
|
+
"#{datetime}: #{msg}\n"
|
486
|
+
end
|
487
|
+
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
|
492
|
+
#
|
493
|
+
|
494
|
+
# This checks if an appropriate pandoc version can be
|
495
|
+
# started on the machine
|
496
|
+
|
497
|
+
#
|
498
|
+
|
499
|
+
# @return [boolean] true if an appropriate version is available
|
500
|
+
def check_pandoc_version
|
501
|
+
required_version_string="2.0.5"
|
502
|
+
begin
|
503
|
+
pandoc_version=`#{PANDOC_EXE} -v`.split("\n").first.split(" ")[1]
|
504
|
+
if pandoc_version < required_version_string then
|
505
|
+
@log.error "found pandoc #{pandoc_version} need #{required_version_string}"
|
506
|
+
result = false
|
507
|
+
else
|
508
|
+
result = true
|
509
|
+
end
|
510
|
+
rescue Exception => e
|
511
|
+
@log.error("could not run pandoc: #{e.message}")
|
512
|
+
result=false
|
513
|
+
end
|
514
|
+
result
|
515
|
+
end
|
516
|
+
|
517
|
+
# perform the beautify
|
518
|
+
# * process the file with pandoc
|
519
|
+
# * revoke some quotes introduced by pandoc
|
520
|
+
# @param [String] file the name of the file to be beautified
|
521
|
+
def beautify(file)
|
522
|
+
|
523
|
+
@log.debug(" Cleaning: \"#{file}\"")
|
524
|
+
|
525
|
+
docfile = File.new(file)
|
526
|
+
olddoc = docfile.readlines.join
|
527
|
+
docfile.close
|
528
|
+
|
529
|
+
# process the file in pandoc
|
530
|
+
cmd = "#{PANDOC_EXE} --standalone #{file.esc} -f markdown#{@markdown_input_switches} -t markdown#{@markdown_output_switches} --atx-headers --id-prefix=#{File.basename(file).esc}_ "
|
531
|
+
|
532
|
+
newdoc = `#{cmd}`
|
533
|
+
@log.debug "beautify #{file.esc}: #{$?}"
|
534
|
+
@log.debug(" finished: \"#{file}\"")
|
535
|
+
|
536
|
+
# tweak the quoting
|
537
|
+
if $?.success? then
|
538
|
+
# (RS_Mdc)
|
539
|
+
# TODO: fix Table width toggles sometimes
|
540
|
+
if (not olddoc == newdoc) then ##only touch the file if it is really changed
|
541
|
+
File.open(file, "w") { |f| f.puts(newdoc) }
|
542
|
+
File.open(file+".bak", "w") { |f| f.puts(olddoc) } # (RS_Mdc_) # remove this if needed
|
543
|
+
@log.debug(" cleaned: \"#{file}\"")
|
544
|
+
else
|
545
|
+
@log.debug("was clean: \"#{file}\"")
|
546
|
+
end
|
547
|
+
#TODO: error handling here
|
548
|
+
else
|
549
|
+
@log.error("error calling pandoc - please watch the screen output")
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
|
554
|
+
# this replaces the text snippets in files
|
555
|
+
def replace_snippets_in_file(infile, snippets)
|
556
|
+
input_data = File.open(infile) { |f| f.readlines.join }
|
557
|
+
output_data=input_data.clone
|
558
|
+
|
559
|
+
@log.debug("replacing snippets in #{infile}")
|
560
|
+
|
561
|
+
replace_snippets_in_text(output_data, snippets)
|
562
|
+
|
563
|
+
if (not input_data == output_data)
|
564
|
+
File.open(infile, "w") { |f| f.puts output_data }
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
# this replaces the snippets in a text
|
569
|
+
def replace_snippets_in_text(text, snippets)
|
570
|
+
changed=false
|
571
|
+
text.gsub!(SNIPPET_PATTERN) { |m|
|
572
|
+
replacetext_raw=snippets[$2.to_sym]
|
573
|
+
|
574
|
+
if replacetext_raw
|
575
|
+
changed=true
|
576
|
+
unless $1.nil? then
|
577
|
+
leading_whitespace=$1.split("\n", 100)
|
578
|
+
leading_lines =leading_whitespace[0..-1].join("\n")
|
579
|
+
leading_spaces =leading_whitespace.last || ""
|
580
|
+
replacetext =leading_lines+replacetext_raw.gsub("\n", "\n#{leading_spaces}")
|
581
|
+
end
|
582
|
+
@log.debug("replaced snippet #{$2} with #{replacetext}")
|
583
|
+
else
|
584
|
+
replacetext=m
|
585
|
+
@log.warn("Snippet not found: #{$2}")
|
586
|
+
end
|
587
|
+
replacetext
|
588
|
+
}
|
589
|
+
#recursively process nested snippets
|
590
|
+
#todo: this approach might rais undefined snippets twice if there are defined and undefined ones
|
591
|
+
replace_snippets_in_text(text, snippets) if changed==true
|
592
|
+
end
|
593
|
+
|
594
|
+
|
595
|
+
#
|
596
|
+
# Ths determines the view filter
|
597
|
+
#
|
598
|
+
# @param [String] line - the current input line
|
599
|
+
# @param [String] view - the currently selected view
|
600
|
+
#
|
601
|
+
# @return true/false if a view-command is found, else nil
|
602
|
+
def get_filter_command(line, view)
|
603
|
+
r = line.match(@view_pattern)
|
604
|
+
|
605
|
+
if not r.nil?
|
606
|
+
found = r[1].split(" ")
|
607
|
+
result = (found & [view, "all"].flatten).any?
|
608
|
+
else
|
609
|
+
result = nil
|
610
|
+
end
|
611
|
+
|
612
|
+
result
|
613
|
+
end
|
614
|
+
|
615
|
+
#
|
616
|
+
# This filters the document according to the target audience
|
617
|
+
#
|
618
|
+
# @param [String] inputfile name of inputfile
|
619
|
+
# @param [String] outputfile name of outputfile
|
620
|
+
# @param [String] view - name of intended view
|
621
|
+
|
622
|
+
def filter_document_variant(inputfile, outputfile, view)
|
623
|
+
|
624
|
+
input_data = File.open(inputfile) { |f| f.readlines }
|
625
|
+
|
626
|
+
output_data = Array.new
|
627
|
+
is_active = true
|
628
|
+
input_data.each { |l|
|
629
|
+
switch=self.get_filter_command(l, view)
|
630
|
+
l.gsub!(@view_pattern, "")
|
631
|
+
is_active = switch unless switch.nil?
|
632
|
+
@log.debug "select edtiion #{view}: #{is_active}: #{l.strip}"
|
633
|
+
|
634
|
+
output_data << l if is_active
|
635
|
+
}
|
636
|
+
|
637
|
+
File.open(outputfile, "w") { |f| f.puts output_data.join }
|
638
|
+
end
|
639
|
+
|
640
|
+
#
|
641
|
+
# This filters the document according to the target audience
|
642
|
+
#
|
643
|
+
# @param [String] inputfile name of inputfile
|
644
|
+
# @param [String] outputfile name of outputfile
|
645
|
+
# @param [String] view - name of intended view
|
646
|
+
|
647
|
+
def process_debug_info(inputfile, outputfile, view)
|
648
|
+
|
649
|
+
input_data = File.open(inputfile) { |f| f.readlines }
|
650
|
+
|
651
|
+
output_data = Array.new
|
652
|
+
|
653
|
+
input_data.each { |l|
|
654
|
+
l.gsub!(@view_pattern) { |p|
|
655
|
+
if $1.strip == "all" then
|
656
|
+
color="black"
|
657
|
+
else
|
658
|
+
color="red"
|
659
|
+
end
|
660
|
+
|
661
|
+
"\\color{#{color}}\\rule{2cm}{0.5mm}\\newline\\marginpar{#{$1.strip}}"
|
662
|
+
|
663
|
+
}
|
664
|
+
|
665
|
+
l.gsub!(/todo:|TODO:/) { |p| "#{p}\\marginpar{TODO}" }
|
666
|
+
|
667
|
+
output_data << l
|
668
|
+
}
|
669
|
+
|
670
|
+
File.open(outputfile, "w") { |f| f.puts output_data.join }
|
671
|
+
end
|
672
|
+
|
673
|
+
|
674
|
+
# This compiles the input documents to one single file
|
675
|
+
# it also beautifies the input files
|
676
|
+
#
|
677
|
+
# @param [Array of String] input - the input files to be processed in the given sequence
|
678
|
+
# @param [String] output - the the name of the output file
|
679
|
+
def collect_document(input, output)
|
680
|
+
inputs =input.map { |xx| xx.esc.to_osPath }.join(" ") # qoute cond combine the inputs
|
681
|
+
inputname=File.basename(input.first)
|
682
|
+
|
683
|
+
#now combine the input files
|
684
|
+
@log.debug("combining the input files #{inputname} et al")
|
685
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} --standalone -t markdown#{@markdown_output_switches} -o #{output} --ascii #{inputs}" # note that inputs is already quoted
|
686
|
+
system(cmd)
|
687
|
+
if $?.success? then
|
688
|
+
PandocBeautifier.new().beautify(output)
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
#
|
693
|
+
# This loads snipptes from xlsx file
|
694
|
+
# @param [String] file name of the xlsx file
|
695
|
+
# @return [Hash] a hash with the snippetes
|
696
|
+
#
|
697
|
+
def load_snippets_from_xlsx(file)
|
698
|
+
temp_filename = "#{@tempdir}/snippett.xlsx"
|
699
|
+
FileUtils::copy(file, temp_filename)
|
700
|
+
wb =RubyXL::Parser.parse(temp_filename)
|
701
|
+
result={}
|
702
|
+
wb.first.each { |row|
|
703
|
+
key, the_value = row
|
704
|
+
unless key.nil?
|
705
|
+
unless the_value.nil?
|
706
|
+
result[key.value.to_sym] = resolve_xml_entities(the_value.value) rescue ""
|
707
|
+
end
|
708
|
+
end
|
709
|
+
}
|
710
|
+
result
|
711
|
+
end
|
712
|
+
|
713
|
+
#
|
714
|
+
# this resolves xml entities in Text (lt, gt, amp)
|
715
|
+
# @param [String] text with entities
|
716
|
+
# @return [String] text with replaced entities
|
717
|
+
def resolve_xml_entities(text)
|
718
|
+
result=text
|
719
|
+
result.gsub!("<", "<")
|
720
|
+
result.gsub!(">", ">")
|
721
|
+
result.gsub!("&", "&")
|
722
|
+
result
|
723
|
+
end
|
724
|
+
|
725
|
+
#
|
726
|
+
# This generates the final document
|
727
|
+
#
|
728
|
+
# It actually does this in two steps:
|
729
|
+
#
|
730
|
+
# 1. process front matter to laTeX
|
731
|
+
# 2. process documents
|
732
|
+
#
|
733
|
+
# @param [Array of String] input the input files to be processed in the given sequence
|
734
|
+
# @param [String] outdir the output directory
|
735
|
+
# @param [String] outname the base name of the output file. It is a basename in case the
|
736
|
+
# output format requires multiple files
|
737
|
+
# @param [Array of String] format list of formats which shall be generated.
|
738
|
+
# supported formats: "pdf", "latex", "html", "docx", "rtf", txt
|
739
|
+
# @param [Hash] vars - the variables passed to pandoc
|
740
|
+
# @param [Hash] editions - the editions to process; default nil - no edition processing
|
741
|
+
# @param [Array of String] snippetfiles the list of files containing snippets
|
742
|
+
# @param [String] frontmatter file path to frontmatter the file to processed as frontmatter
|
743
|
+
# @param [ProoConfig] config - the configuration file to be used
|
744
|
+
def generateDocument(input, outdir, outname, format, vars, editions=nil, snippetfiles=nil, frontmatter=nil, config=nil)
|
745
|
+
|
746
|
+
# combine the input files
|
747
|
+
|
748
|
+
temp_filename = "#{@tempdir}/x.md".to_osPath
|
749
|
+
temp_frontmatter = "#{@tempdir}/xfrontmatter.md".to_osPath unless frontmatter.nil?
|
750
|
+
collect_document(input, temp_filename)
|
751
|
+
collect_document(frontmatter, temp_frontmatter) unless frontmatter.nil?
|
752
|
+
|
753
|
+
# process the snippets
|
754
|
+
|
755
|
+
if not snippetfiles.nil?
|
756
|
+
snippets={}
|
757
|
+
snippetfiles.each { |f|
|
758
|
+
if File.exists?(f)
|
759
|
+
type=File.extname(f)
|
760
|
+
case type
|
761
|
+
when ".yaml"
|
762
|
+
x=YAML.load(File.new(f))
|
763
|
+
when ".xlsx"
|
764
|
+
x=load_snippets_from_xlsx(f)
|
765
|
+
else
|
766
|
+
@log.error("Unsupported File format for snipptets: #{type}")
|
767
|
+
x={}
|
768
|
+
end
|
769
|
+
snippets.merge!(x)
|
770
|
+
else
|
771
|
+
@log.error("Snippet file not found: #{f}")
|
772
|
+
end
|
773
|
+
}
|
774
|
+
|
775
|
+
replace_snippets_in_file(temp_filename, snippets)
|
776
|
+
end
|
777
|
+
|
778
|
+
vars_frontmatter =vars.clone
|
779
|
+
vars_frontmatter[:usetoc] = "nousetoc"
|
780
|
+
|
781
|
+
|
782
|
+
if editions.nil?
|
783
|
+
# there are no editions
|
784
|
+
unless frontmatter.nil? then
|
785
|
+
render_document(temp_frontmatter, tempdir, temp_frontmatter, ["frontmatter"], vars_frontmatter)
|
786
|
+
vars[:frontmatter] = "#{tempdir}/#{temp_frontmatter}.latex"
|
787
|
+
end
|
788
|
+
render_document(temp_filename, outdir, outname, format, vars, config)
|
789
|
+
else
|
790
|
+
# process the editions
|
791
|
+
editions.each { |edition_name, properties|
|
792
|
+
edition_out_filename = "#{outname}_#{properties[:filepart]}"
|
793
|
+
edition_temp_frontmatter = "#{@tempdir}/#{edition_out_filename}_frontmatter.md" unless frontmatter.nil?
|
794
|
+
edition_temp_filename = "#{@tempdir}/#{edition_out_filename}.md"
|
795
|
+
vars[:title] = properties[:title]
|
796
|
+
|
797
|
+
editionformats = properties[:format] || format
|
798
|
+
|
799
|
+
if properties[:debug]
|
800
|
+
process_debug_info(temp_frontmatter, edition_temp_frontmatter, edition_name.to_s) unless frontmatter.nil?
|
801
|
+
process_debug_info(temp_filename, edition_temp_filename, edition_name.to_s)
|
802
|
+
lvars =vars.clone
|
803
|
+
lvars[:linenumbers] = "true"
|
804
|
+
unless frontmatter.nil? # frontmatter
|
805
|
+
lvars[:usetoc] = "nousetoc"
|
806
|
+
render_document(edition_temp_frontmatter, @tempdir, "xfrontmatter", ["frontmatter"], lvars)
|
807
|
+
lvars[:usetoc] = vars[:usetoc] || "usetoc"
|
808
|
+
lvars[:frontmatter] = "#{@tempdir}/xfrontmatter.latex"
|
809
|
+
end
|
810
|
+
render_document(edition_temp_filename, outdir, edition_out_filename, ["pdf", "latex"], lvars, config)
|
811
|
+
else
|
812
|
+
unless frontmatter.nil? # frontmatter
|
813
|
+
filter_document_variant(temp_frontmatter, edition_temp_frontmatter, edition_name.to_s)
|
814
|
+
render_document(edition_temp_frontmatter, @tempdir, "xfrontmatter", ["frontmatter"], vars_frontmatter)
|
815
|
+
vars[:frontmatter]="#{@tempdir}/xfrontmatter.latex"
|
816
|
+
end
|
817
|
+
|
818
|
+
filter_document_variant(temp_filename, edition_temp_filename, edition_name.to_s)
|
819
|
+
render_document(edition_temp_filename, outdir, edition_out_filename, editionformats, vars, config)
|
820
|
+
end
|
821
|
+
}
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
#
|
826
|
+
|
827
|
+
# render a single file
|
828
|
+
# @param input [String] path to the inputfile
|
829
|
+
# @param outdir [String] path to the output directory
|
830
|
+
# @param format [Array of String] formats
|
831
|
+
# @return [nil] no useful return value
|
832
|
+
def render_single_document(input, outdir, format)
|
833
|
+
outname=File.basename(input, ".*")
|
834
|
+
render_document(input, outdir, outname, format, { :geometry => "a4paper" })
|
835
|
+
end
|
836
|
+
|
837
|
+
#
|
838
|
+
# This renders the final document
|
839
|
+
# @param [String] input the input file
|
840
|
+
# @param [String] outdir the output directory
|
841
|
+
# @param [String] outname the base name of the output file. It is a basename in case the
|
842
|
+
# output format requires multiple files
|
843
|
+
# @param [Array of String] format list of formats which shall be generated.
|
844
|
+
# supported formats: "pdf", "latex", "html", "docx", "rtf", txt
|
845
|
+
# @param [Hash] vars - the variables passed to pandoc
|
846
|
+
|
847
|
+
# @param config [ProoConfig] the entire config object (for future extensions)
|
848
|
+
# @return nil
|
849
|
+
|
850
|
+
def render_document(input, outdir, outname, format, vars, config=nil)
|
851
|
+
|
852
|
+
#TODO: Clarify the following
|
853
|
+
# on Windows, Tempdir contains a drive letter. But drive letter
|
854
|
+
# seems not to work in pandoc -> pdf if the path separator ist forward
|
855
|
+
# slash. There are two options to overcome this
|
856
|
+
#
|
857
|
+
# 1. set tempdir such that it does not contain a drive letter
|
858
|
+
# 2. use Dir.mktempdir but ensure that all provided file names
|
859
|
+
# use the platform specific SEPARATOR
|
860
|
+
#
|
861
|
+
# for whatever Reason, I decided for 2.
|
862
|
+
|
863
|
+
tempfile = input
|
864
|
+
tempfilePdf = "#{@tempdir}/x.TeX.md".to_osPath
|
865
|
+
tempfileHtml = "#{@tempdir}/x.html.md".to_osPath
|
866
|
+
outfile = "#{outdir}/#{outname}".to_osPath
|
867
|
+
outfilePdf = "#{outfile}.pdf"
|
868
|
+
outfileDocx = "#{outfile}.docx"
|
869
|
+
outfileHtml = "#{outfile}.html"
|
870
|
+
outfileRtf = "#{outfile}.rtf"
|
871
|
+
outfileLatex = "#{outfile}.latex"
|
872
|
+
outfileText = "#{outfile}.txt"
|
873
|
+
outfileSlide = "#{outfile}.slide.html"
|
874
|
+
|
875
|
+
|
876
|
+
## format handle
|
877
|
+
|
878
|
+
# todo: use this information ...
|
879
|
+
|
880
|
+
format_config = {
|
881
|
+
'pdf' => {
|
882
|
+
tempfile: :pdf,
|
883
|
+
outfile: "#{outfile}.pdf"
|
884
|
+
},
|
885
|
+
'html' => {
|
886
|
+
tempfile: :html,
|
887
|
+
outfile: "#{outfile}.html"
|
888
|
+
},
|
889
|
+
'docx' => {
|
890
|
+
tempfile: :html,
|
891
|
+
outfile: "#{outfile}.docx"
|
892
|
+
},
|
893
|
+
'rtf' => {
|
894
|
+
tempfile: :html,
|
895
|
+
outfile: "#{outfile}.rtf"
|
896
|
+
},
|
897
|
+
'latex' => {
|
898
|
+
tempfile: :pdf,
|
899
|
+
outfile: "#{outfile}.latex"
|
900
|
+
},
|
901
|
+
'text' => {
|
902
|
+
tempfile: :html,
|
903
|
+
outfile: "#{outfile}.text"
|
904
|
+
},
|
905
|
+
'dzslides' => {
|
906
|
+
tempfile: :html,
|
907
|
+
outfile: "#{outfile}.slide.html"
|
908
|
+
},
|
909
|
+
|
910
|
+
:beamer => {
|
911
|
+
tempfile: :pdf,
|
912
|
+
outfile: "#{outfile}.beamer.pdf"
|
913
|
+
},
|
914
|
+
|
915
|
+
'markdown' => {
|
916
|
+
tempfile: :html,
|
917
|
+
outfile: "#{outfile}.slide.html"
|
918
|
+
}
|
919
|
+
}
|
920
|
+
|
921
|
+
tempfile_config = {
|
922
|
+
pdf: "#{@tempdir}/x.TeX.md".to_osPath,
|
923
|
+
html: "#{@tempdir}/x.html.md".to_osPath
|
924
|
+
}
|
925
|
+
|
926
|
+
|
927
|
+
if vars.has_key? :frontmatter
|
928
|
+
latexTitleInclude = "--include-before-body=#{vars[:frontmatter].esc}"
|
929
|
+
else
|
930
|
+
latexTitleInclude
|
931
|
+
end
|
932
|
+
|
933
|
+
#todo: make config required, so it can be reduced to the else part
|
934
|
+
if config.nil? then
|
935
|
+
latexStyleFile = File.dirname(File.expand_path(__FILE__))+"/../../resources/default.wortsammler.latex"
|
936
|
+
latexStyleFile = File.expand_path(latexStyleFile).to_osPath
|
937
|
+
css_style_file = File.dirname(File.expand_path(__FILE__))+"/../../resources/default.wortsammler.css"
|
938
|
+
css_style_file = File.expand_path(css_style_file).to_osPath
|
939
|
+
else
|
940
|
+
latexStyleFile = config.stylefiles[:latex]
|
941
|
+
css_style_file = config.stylefiles[:css]
|
942
|
+
end
|
943
|
+
|
944
|
+
|
945
|
+
toc = "--toc"
|
946
|
+
toc = "" if vars[:usetoc]=="nousetoc"
|
947
|
+
|
948
|
+
if vars[:documentclass]=="book"
|
949
|
+
option_chapters = "--chapters"
|
950
|
+
else
|
951
|
+
option_chapter = ""
|
952
|
+
end
|
953
|
+
|
954
|
+
begin
|
955
|
+
vars_string=vars.map.map { |key, value| "-V #{key}=#{value.esc}" }.join(" ")
|
956
|
+
rescue
|
957
|
+
#todo require 'pry'; binding.pry
|
958
|
+
end
|
959
|
+
|
960
|
+
@log.info("rendering #{outname} as [#{format.join(', ')}]")
|
961
|
+
|
962
|
+
supported_formats=["pdf", "latex", "frontmatter", "docx", "html", "txt", "rtf", "slidy", "md", "beamer"]
|
963
|
+
wrong_format =format - supported_formats
|
964
|
+
wrong_format.each { |f| @log.error("format not supported: #{f}") }
|
965
|
+
|
966
|
+
begin
|
967
|
+
|
968
|
+
if format.include?("frontmatter") then
|
969
|
+
|
970
|
+
ReferenceTweaker.new("pdf").prepareFile(tempfile, tempfilePdf)
|
971
|
+
|
972
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfilePdf.esc} --pdf-engine xelatex #{vars_string} --ascii -t latex+smart -o #{outfileLatex.esc}"
|
973
|
+
`#{cmd}`
|
974
|
+
end
|
975
|
+
|
976
|
+
|
977
|
+
if (format.include?("pdf") | format.include?("latex")) then
|
978
|
+
@log.debug("creating #{outfileLatex}")
|
979
|
+
ReferenceTweaker.new("pdf").prepareFile(tempfile, tempfilePdf)
|
980
|
+
|
981
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfilePdf.esc} #{toc} --standalone #{option_chapters} --pdf-engine xelatex --number-sections #{vars_string}" +
|
982
|
+
" --template #{latexStyleFile.esc} --ascii -t latex+smart -o #{outfileLatex.esc} #{latexTitleInclude}"
|
983
|
+
`#{cmd}`
|
984
|
+
|
985
|
+
end
|
986
|
+
|
987
|
+
|
988
|
+
|
989
|
+
if format.include?("pdf") then
|
990
|
+
@log.debug("creating #{outfilePdf}")
|
991
|
+
ReferenceTweaker.new("pdf").prepareFile(tempfile, tempfilePdf)
|
992
|
+
#cmd="#{PANDOC_EXE} -S #{tempfilePdf.esc} #{toc} --standalone #{option_chapters} --latex-engine xelatex --number-sections #{vars_string}" +
|
993
|
+
# " --template #{latexStyleFile.esc} --ascii -o #{outfilePdf.esc} #{latexTitleInclude}"
|
994
|
+
cmd ="#{LATEX_EXE} -halt-on-error -interaction nonstopmode -output-directory=#{outdir.esc} #{outfileLatex.esc}"
|
995
|
+
#cmdmkindex = "makeindex \"#{outfile.esc}.idx\""
|
996
|
+
|
997
|
+
latex=LatexHelper.new.set_latex_command(cmd).setlogger(@log)
|
998
|
+
latex.run(outfileLatex)
|
999
|
+
|
1000
|
+
messages=latex.log_analyze("#{outdir}/#{outname}.log")
|
1001
|
+
|
1002
|
+
removeables = ["toc", "aux", "bak", "idx", "ilg", "ind"]
|
1003
|
+
removeables << "log" unless messages > 0
|
1004
|
+
|
1005
|
+
|
1006
|
+
removeables << "latex" unless format.include?("latex")
|
1007
|
+
removeables = removeables.map { |e| "#{outdir}/#{outname}.#{e}" }.select { |f| File.exists?(f) }
|
1008
|
+
removeables.each { |e|
|
1009
|
+
@log.debug "removing file: #{e}"
|
1010
|
+
FileUtils.rm e
|
1011
|
+
}
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
if format.include?("html") then
|
1015
|
+
#todo: handle css
|
1016
|
+
@log.debug("creating #{outfileHtml}")
|
1017
|
+
|
1018
|
+
ReferenceTweaker.new("html").prepareFile(tempfile, tempfileHtml)
|
1019
|
+
|
1020
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfileHtml.esc} --toc --standalone --self-contained --ascii --number-sections #{vars_string}" +
|
1021
|
+
" -t html+smart -o #{outfileHtml.esc}"
|
1022
|
+
|
1023
|
+
`#{cmd}`
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
if format.include?("docx") then
|
1027
|
+
#todo: handle style file
|
1028
|
+
@log.debug("creating #{outfileDocx}")
|
1029
|
+
|
1030
|
+
ReferenceTweaker.new("html").prepareFile(tempfile, tempfileHtml)
|
1031
|
+
|
1032
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfileHtml.esc} #{toc} --standalone --self-contained --ascii --number-sections #{vars_string}" +
|
1033
|
+
" -f docx+smart -o #{outfileDocx.esc}"
|
1034
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfileHtml.esc} --toc --standalone --self-contained --ascii --number-sections #{vars_string}" +
|
1035
|
+
" -t docx+smart -o #{outfileDocx.esc}"
|
1036
|
+
`#{cmd}`
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
if format.include?("rtf") then
|
1040
|
+
@log.debug("creating #{outfileRtf}")
|
1041
|
+
ReferenceTweaker.new("html").prepareFile(tempfile, tempfileHtml)
|
1042
|
+
|
1043
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfileHtml.esc} --toc --standalone --self-contained --ascii --number-sections #{vars_string}" +
|
1044
|
+
" -t rtf+smart -o #{outfileRtf.esc}"
|
1045
|
+
`#{cmd}`
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
if format.include?("txt") then
|
1049
|
+
@log.debug("creating #{outfileText}")
|
1050
|
+
|
1051
|
+
ReferenceTweaker.new("pdf").prepareFile(tempfile, tempfileHtml)
|
1052
|
+
|
1053
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfileHtml.esc} --toc --standalone --self-contained --ascii --number-sections #{vars_string}" +
|
1054
|
+
" -t plain+smart -o #{outfileText.esc}"
|
1055
|
+
`#{cmd}`
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
if format.include?("slidy") then
|
1059
|
+
@log.debug("creating #{outfileSlide}")
|
1060
|
+
|
1061
|
+
ReferenceTweaker.new("html").prepareFile(tempfile, tempfileHtml)
|
1062
|
+
#todo: handle stylefile
|
1063
|
+
cmd="#{PANDOC_EXE} -f markdown#{@markdown_input_switches} #{tempfileHtml.esc} --toc --standalone --self-contained #{vars_string}" +
|
1064
|
+
" --ascii -t s5+smart --slide-level 1 -o #{outfileSlide.esc}"
|
1065
|
+
`#{cmd}`
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
if format.include?("beamer") then
|
1069
|
+
outfile = format_config[:beamer][:outfile]
|
1070
|
+
tempformat = format_config[:beamer][:tempfile]
|
1071
|
+
tempfile_out = tempfile_config[tempformat]
|
1072
|
+
@log.debug("creating #{outfile}")
|
1073
|
+
ReferenceTweaker.new(tempformat).prepareFile(tempfile, tempfile_out)
|
1074
|
+
|
1075
|
+
cmd = %Q{#{PANDOC_EXE} -t beamer #{tempfile_out.esc} -V theme:Warsaw -o #{outfile.esc}}
|
1076
|
+
`#{cmd}`
|
1077
|
+
|
1078
|
+
#messages=latex.log_analyze("#{outdir}/#{outname}.log")
|
1079
|
+
messages = 0
|
1080
|
+
|
1081
|
+
removeables = ["toc", "aux", "bak", "idx", "ilg", "ind"]
|
1082
|
+
removeables << "log" unless messages > 0
|
1083
|
+
|
1084
|
+
|
1085
|
+
removeables << "latex" unless format.include?("latex")
|
1086
|
+
removeables = removeables.map { |e| "#{outdir}/#{outname}.#{e}" }.select { |f| File.exists?(f) }
|
1087
|
+
removeables.each { |e|
|
1088
|
+
@log.debug "removing file: #{e}"
|
1089
|
+
FileUtils.rm e
|
1090
|
+
}
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
|
1094
|
+
rescue Exception => e
|
1095
|
+
@log.error "failed to perform #{cmd}, \n#{e.message}"
|
1096
|
+
@log.error e.backtrace.join("\n")
|
1097
|
+
#TODO make a try catch block kere
|
1098
|
+
end
|
1099
|
+
nil
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
end
|