summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/cstypo/cstypo.lua
blob: 4ad6f651fb7edf3147c0edaba070219e8758b53d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
175
176
--[[--
(c) 2016 Václav Haisman

This program can be redistributed and/or modified under the terms of the MIT
license. See LICENSE file.
--]]--

local GLYPH = node.id("glyph")
--print('GLYPH value: ', GLYPH)

local GLUE = node.id("glue")
--print('GLUE value: ', GLUE)

local CZECH_ID = cstypo_czech_language_id
--print('CZECH_ID value: ', CZECH_ID)

local function prevent_single_letter (head)
  while head do
    -- glyph
    if (head.id == GLYPH
        -- and in Czech or unspecified (???)
          and (head.lang == nil
               or head.lang == CZECH_ID)) then
      -- only if we are at one letter word
      if unicode.utf8.match(unicode.utf8.char(head.char), "[zZsSuUkKoOvViI]") then
        -- and left of it is either a space
        if ((head.prev.id == GLUE
             -- or one of '{[('
               or (head.prev.id == GLYPH
                     and unicode.utf8.match(unicode.utf8.char(head.prev.char),
                                            "[%[%]()%{%}]")))
          -- and right of the one letter word is also a space
          and head.next.id == GLUE) then
          -- then avoid line break between the single letter word and the
          -- word following it
          local p = node.new("penalty")
          p.penalty = 10000
          node.insert_after(head, head, p)
          --print('inserting penalty at ', head)
        end
      end
    end
    head = head.next
  end
  return true
end

function cstypo_single_letter_enable ()
  print('cstypo: Enabling single letter hook.')
  luatexbase.add_to_callback("pre_linebreak_filter", prevent_single_letter,
                             "cstyposingleletter")
end

function cstypo_single_letter_disable ()
  print('cstypo: Disabling single letter hook.')
  luatexbase.remove_from_callback("pre_linebreak_filter", "cstyposingleletter")
end


local function prevent_a_letter (head)
  while head do
    -- glyph
    if (head.id == GLYPH
        -- and in Czech or unspecified (???)
          and (head.lang == nil
               or head.lang == CZECH_ID)) then
      -- only if we are at one letter word
      if unicode.utf8.match(unicode.utf8.char(head.char), "[aA]") then
        -- and previous is space
        if ((head.prev.id == GLUE
             -- or previous is one of '{[('
               or (head.prev.id == GLYPH
                     and unicode.utf8.match(unicode.utf8.char(head.prev.char),
                                            "[%[%]()%{%}]")))
          -- and right of the one letter word is also a space
          and head.next.id == GLUE) then
          -- then avoid line break between the single letter word and the
          -- word following it
          local p = node.new("penalty")
          p.penalty = 10000
          node.insert_after(head, head, p)
        end
      end
    end
    head = head.next
  end
  return true
end

function cstypo_a_letter_enable ()
  print('cstypo: Enabling \'a\' letter hook.')
  luatexbase.add_to_callback("pre_linebreak_filter", prevent_a_letter,
                             "cstypoaletter")
end

function cstypo_a_letter_disable ()
  print('cstypo: Disabling \'a\' letter hook.')
  luatexbase.remove_from_callback("pre_linebreak_filter", "cstypoaletter")
end


local function prevent_percents (head)
  while head do
    -- glyph
    if (head.id == GLYPH
        -- and in Czech or unspecified (???)
          and (head.lang == nil
               or head.lang == CZECH_ID)) then
      -- only if we are at percentage sign
      if unicode.utf8.match(unicode.utf8.char(head.char), "[%%‰°℃℉]") then
        -- and left of it is a space
        if (head.prev.id == GLUE
            -- and left of the space is a digit.
              and head.prev.prev.id == GLYPH
              and unicode.utf8.match(unicode.utf8.char(head.prev.prev.char),
                                     "[0-9]")) then
          local p = node.new("penalty")
          p.penalty = 10000
          node.insert_after(head.prev.prev, head.prev.prev, p)
        end
      end
    end
    head = head.next
  end
  return true
end

function cstypo_percents_enable()
  print('cstypo: Enabling percents hook.')
  luatexbase.add_to_callback("pre_linebreak_filter", prevent_percents,
                             "cstypopercents")
end

function cstypo_percents_disable()
  print('cstypo: Disabling percents hook.')
  luatexbase.remove_from_callback("pre_linebreak_filter", "cstypopercents")
end


local function prevent_paragraph (head)
  while head do
    -- glyph
    if (head.id == GLYPH
        -- and in Czech or unspecified (???)
          and (head.lang == nil
               or head.lang == CZECH_ID)) then
      -- only if we are at paragraph symbol
      if unicode.utf8.match(unicode.utf8.char(head.char), "[§]") then
        -- and right of it is a space
        if (head.next.id == GLUE
              and (head.next.next.id == GLYPH
                     and unicode.utf8.match(unicode.utf8.char(head.next.next.char),
                                            "[0-9]"))) then
          -- then avoid line break between the paragraph and the number
          -- following it
          local p = node.new("penalty")
          p.penalty = 10000
          node.insert_after(head, head, p)
        end
      end
    end
    head = head.next
  end
  return true
end

function cstypo_paragraph_enable()
  print('cstypo: Enabling paragraph hook.')
  luatexbase.add_to_callback("pre_linebreak_filter", prevent_paragraph,
                             "cstypoparagraph")
end

function cstypo_paragraph_disable()
  print('cstypo: Disabling paragraph hook.')
  luatexbase.remove_from_callback("pre_linebreak_filter", "cstypoparagraph")
end