asciidoctor-autoterm 1.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9aa205a2201907e6e79efdf5e15b67116c0fe00c074927580f305487a930e817
4
+ data.tar.gz: 73962f910b8e86becb9233012a7507d914e50508413567edd3896f59d1c95028
5
+ SHA512:
6
+ metadata.gz: 1c708dde292c21e8149e81029ac501ebb53ea9da26c0aa159de5c4271360b01fefa00a1ca307b0588bd64c702e84135bd3e002ee7b3a6666bd79c2e24f22c000
7
+ data.tar.gz: 8453acb552ee6b80382c0f95b48645eb1347b45203612efd766b60fcf138588ab32dca730b7d831a5832b0ff662ea147bde3e9e5d8b8473453baa04c0d7e5b29
@@ -0,0 +1,19 @@
1
+ Asciidoctor::Extensions.register do
2
+ tree_processor do
3
+ process do |doc|
4
+ if doc.attributes['include-terminology'] == 'true'
5
+ if (last_section = doc.sections.last)
6
+ terminology_section = create_section last_section.parent, 'Terminology', { 'style' => 'index', 'type' => 'terminology' }
7
+ terminology_section.parent << terminology_section
8
+ end
9
+ end
10
+ if doc.attributes['include-index'] == 'true'
11
+ if (last_section = doc.sections.last)
12
+ index_section = create_section last_section.parent, 'Index', { 'style' => 'index' }
13
+ index_section.parent << index_section
14
+ end
15
+ end
16
+ doc
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,141 @@
1
+ require 'asciidoctor'
2
+ require 'asciidoctor/extensions'
3
+
4
+ class TermIndex < Asciidoctor::Converter.for('pdf')
5
+ register_for 'pdf'
6
+
7
+ def convert_index_section(node)
8
+ if node.attributes['type'] == 'terminology'
9
+ use_custom_definitions = node.document.attr('terminology-use-definitions', 'false').to_s.downcase != 'false'
10
+ terminology = use_custom_definitions ? parse_terminology_from_ast(node.document) : {}
11
+ terms_by_full_name_with_abbr_and_definition = collect_terms(terminology)
12
+
13
+ convert_terminology_entries(terms_by_full_name_with_abbr_and_definition) unless terms_by_full_name_with_abbr_and_definition.empty?
14
+ nil
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def convert_terminology_entries(terms_by_full_name_with_abbr_and_definition)
21
+ sorted_terms = terms_by_full_name_with_abbr_and_definition.sort_by do |full_term, details|
22
+ abbr = details[:abbr]
23
+ (abbr.nil_or_empty? ? full_term : abbr).downcase
24
+ end
25
+
26
+ grouped_terms = sorted_terms.group_by { |full_term, _details| full_term[0].upcase }
27
+ sorted_letters = grouped_terms.keys.sort
28
+
29
+ line_metrics = calc_line_metrics @base_line_height
30
+ space_needed_for_letter = @theme.description_list_term_spacing + (2 * (height_of_typeset_text 'A'))
31
+
32
+ sorted_letters.each do |letter|
33
+ bounds.move_past_bottom if space_needed_for_letter > cursor
34
+
35
+ ink_prose letter,
36
+ align: :left,
37
+ inline_format: false,
38
+ margin_bottom: @theme.description_list_term_spacing,
39
+ style: :bold
40
+
41
+ grouped_terms[letter].each do |full_term, details|
42
+ abbreviation = details[:abbr]
43
+ definition = details[:definition]
44
+
45
+ if abbreviation
46
+ term_text = abbreviation
47
+ desc_text = full_term
48
+ desc_text += " – #{definition}" unless definition.nil_or_empty?
49
+ else
50
+ term_text = full_term
51
+ desc_text = definition || ''
52
+ end
53
+
54
+ entry_height = height_of_typeset_text term_text
55
+ bounds.move_past_bottom if entry_height > cursor
56
+
57
+ term_width = bounds.width * 0.15
58
+ start_cursor = cursor
59
+
60
+ float do
61
+ indent 0 do
62
+ typeset_formatted_text [{ text: term_text, color: @font_color }], line_metrics, align: :left
63
+ end
64
+ end
65
+
66
+ indent term_width do
67
+ typeset_formatted_text [{ text: desc_text, color: @font_color }], line_metrics, align: :left
68
+ end
69
+
70
+ move_down 4.24
71
+ end
72
+
73
+ @theme.prose_margin_bottom > cursor ? bounds.move_past_bottom : (move_down @theme.prose_margin_bottom)
74
+ end
75
+
76
+ start_new_page unless at_page_top?
77
+ end
78
+
79
+ def parse_terminology_from_ast(document)
80
+ terminology = {}
81
+
82
+ terminology_tables = document.find_by do |block|
83
+ block.context == :table && block.has_role?('terminology')
84
+ end
85
+
86
+ if terminology_tables.any?
87
+ first_table = terminology_tables.first
88
+ if first_table.rows && first_table.rows.body
89
+ first_table.rows.body.each do |row|
90
+ full_term = row[0].text.strip
91
+ definition = row[2].text.strip
92
+
93
+ if full_term && definition
94
+ terminology[full_term] = { definition: definition }
95
+ else
96
+ log :warn, %(Skipping invalid row with missing data: #{row.inspect})
97
+ end
98
+ end
99
+ else
100
+ log :warn, %(No rows found in the table with .terminology role.)
101
+ end
102
+ else
103
+ log :info, %(No tables with .terminology role found in the document.)
104
+ end
105
+
106
+ terminology
107
+ end
108
+
109
+ def collect_terms(terminology)
110
+ terms_by_full_name_with_abbr_and_definition = {}
111
+ terminology_present = !terminology.empty?
112
+
113
+ @index.categories.each do |category|
114
+ category.terms.each do |term_obj|
115
+ term_name = term_obj.name
116
+
117
+ if term_name =~ /(.*?)\s+\((.*?)\)/
118
+ full_name = $1.strip
119
+ abbr = $2.strip
120
+ else
121
+ full_name = term_name
122
+ abbr = nil
123
+ end
124
+
125
+ definition_entry = terminology[full_name]
126
+ definition = definition_entry ? definition_entry[:definition] : nil
127
+
128
+ if abbr.nil? && (!terminology_present || definition.nil_or_empty?)
129
+ next
130
+ end
131
+
132
+ terms_by_full_name_with_abbr_and_definition[full_name] = {
133
+ abbr: abbr,
134
+ definition: definition
135
+ }
136
+ end
137
+ end
138
+
139
+ terms_by_full_name_with_abbr_and_definition
140
+ end
141
+ end
@@ -0,0 +1,21 @@
1
+ # https://docs.asciidoctor.org/pdf-converter/latest/extend/use-cases/#theme-table-using-roles
2
+
3
+ class PDFConverterTableRole < (Asciidoctor::Converter.for 'pdf')
4
+ register_for 'pdf'
5
+
6
+ def convert_table node
7
+ if node.role?
8
+ key_prefix = %(role_<table>_#{node.roles[0]}_)
9
+ unless (role_entries = theme.each_pair.select {|name, val| name.to_s.start_with? key_prefix }).empty?
10
+ save_theme do
11
+ role_entries.each do |name, val|
12
+ theme[%(table_#{name.to_s.delete_prefix key_prefix})] = val
13
+ end
14
+ super
15
+ end
16
+ return
17
+ end
18
+ end
19
+ super
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Asciidoctor
2
+ module Autoterm
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ require_relative 'asciidoctor/autoterm/version'
2
+ require_relative 'asciidoctor/autoterm/table_roles'
3
+ require_relative 'asciidoctor/autoterm/converter'
4
+ require_relative 'asciidoctor/autoterm/antora_processor'
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asciidoctor-autoterm
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - baiyibai
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: asciidoctor
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: asciidoctor-pdf
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.3'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.3'
40
+ description: Generates a Terminology section from AsciiDoc index term markup for Asciidoctor
41
+ PDF documents, with support for abbreviations and optional external definitions.
42
+ email:
43
+ - claude@baiyibai.cyou
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/asciidoctor-autoterm.rb
49
+ - lib/asciidoctor/autoterm/antora_processor.rb
50
+ - lib/asciidoctor/autoterm/converter.rb
51
+ - lib/asciidoctor/autoterm/table_roles.rb
52
+ - lib/asciidoctor/autoterm/version.rb
53
+ homepage: https://gitlab.com/baiyibai-asciidoc/antora-asciidoc-autoterm
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '3.0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubygems_version: 3.6.9
72
+ specification_version: 4
73
+ summary: Automatic terminology generator for Asciidoctor PDF
74
+ test_files: []