PluginProbe
Zalomení / 2.0.1
Zalomení v2.0.1
2.0.1 trunk 1.0 1.1 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.3 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 2.0.0
zalomeni / zalomeni.php
zalomeni.php
439 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Zalomení
4 * Plugin URI: https://wordpress.org/plugins/zalomeni/
5 * Description: Puts non-breakable space after one-letter Czech prepositions like 'k', 's', 'v' or 'z'.
6 * Version: 2.0.1
7 * Author: Karolína Vyskočilová
8 * Author URI: https://kybernaut.cz
9 * Text Domain: zalomeni
10 * License: GPL-2.0-or-later
11 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
12 * Requires at least: 6.0
13 * Requires PHP: 7.0
14 */
15
16 defined( 'ABSPATH' ) || exit;
17
18 class Zalomeni {
19 const version = '2.0.1';
20
21 public function __construct() {
22 register_activation_hook(__FILE__, array(__CLASS__, 'activate'));
23 if (is_admin()) {
24 add_action('admin_init', array($this, 'admin_init'));
25 } else {
26 add_action('init', array($this, 'add_filters'));
27 }
28 }
29
30 public function add_filters() {
31 $zalomeni_matches = get_option('zalomeni_matches');
32 if (!empty($zalomeni_matches)) {
33 $filters = array('comment_author', 'term_name', 'link_name', 'link_description', 'link_notes', 'bloginfo', 'wp_title', 'widget_title', 'term_description', 'the_title', 'the_content', 'the_excerpt', 'comment_text', 'single_post_title', 'list_cats');
34 $filters = array_combine($filters, $filters);
35 $filters = apply_filters('zalomeni_filtry', $filters);
36 foreach ($filters as $filter) {
37 add_filter($filter, array(__CLASS__, 'texturize'));
38 }
39 }
40 }
41
42 public static function activate() {
43 $required_php_version = '7.0';
44 if ( version_compare( phpversion(), $required_php_version, '<' ) ) {
45 wp_die(
46 esc_html( str_replace(
47 array( '%1', '%2' ),
48 array( $required_php_version, phpversion() ),
49 __( 'Plugin Zalomení vyžaduje PHP verze %1 nebo vyšší. Na tomto webu je nainstalováno PHP verze %2', 'zalomeni' )
50 ) )
51 );
52 }
53 self::add_options();
54 }
55
56 const default_prepositions = 'on';
57 const default_prepositions_list = 'k, s, v, z';
58 const default_conjunctions = '';
59 const default_conjunctions_list = 'a, i, o, u';
60 const default_abbreviations = '';
61 const default_abbreviations_list = 'cca., č., čís., čj., čp., fa, fě, fy, kupř., mj., např., p., pí, popř., př., přib., přibl., sl., str., sv., tj., tzn., tzv., zvl.';
62 const default_between_number_and_unit = 'on';
63 const default_between_number_and_unit_list = 'm, m², l, kg, h, °C, Kč, lidí, dní, %';
64 const default_spaces_in_scales = 'on';
65 const default_space_between_numbers = 'on';
66 const default_space_after_ordered_number = 'on';
67 const default_custom_terms = "Formule 1\nWindows \d\niPhone \d\niPhone S\d\niPad \d\nWii U\nPlayStation \d\nXBox 360";
68
69 private static function get_default($key) {
70 static $defaults = null;
71 if ($defaults === null) {
72 $defaults = array(
73 'prepositions' => self::default_prepositions,
74 'prepositions_list' => self::default_prepositions_list,
75 'conjunctions' => self::default_conjunctions,
76 'conjunctions_list' => self::default_conjunctions_list,
77 'abbreviations' => self::default_abbreviations,
78 'abbreviations_list' => self::default_abbreviations_list,
79 'between_number_and_unit' => self::default_between_number_and_unit,
80 'between_number_and_unit_list' => self::default_between_number_and_unit_list,
81 'spaces_in_scales' => self::default_spaces_in_scales,
82 'space_between_numbers' => self::default_space_between_numbers,
83 'space_after_ordered_number' => self::default_space_after_ordered_number,
84 'custom_terms' => self::default_custom_terms,
85 );
86 }
87 return isset($defaults[$key]) ? $defaults[$key] : '';
88 }
89
90 private static function add_options() {
91 add_option('zalomeni_version', self::version);
92
93 add_option('zalomeni_prepositions', self::default_prepositions);
94 add_option('zalomeni_prepositions_list', self::default_prepositions_list);
95 add_option('zalomeni_conjunctions', self::default_conjunctions);
96 add_option('zalomeni_conjunctions_list', self::default_conjunctions_list);
97 add_option('zalomeni_abbreviations', self::default_abbreviations);
98 add_option('zalomeni_abbreviations_list', self::default_abbreviations_list);
99 add_option('zalomeni_between_number_and_unit', self::default_between_number_and_unit);
100 add_option('zalomeni_between_number_and_unit_list', self::default_between_number_and_unit_list);
101 add_option('zalomeni_spaces_in_scales', self::default_spaces_in_scales);
102 add_option('zalomeni_space_between_numbers', self::default_space_between_numbers);
103 add_option('zalomeni_space_after_ordered_number', self::default_space_after_ordered_number);
104 add_option('zalomeni_custom_terms', self::default_custom_terms);
105
106 self::update_matches_and_replacements();
107 }
108
109 private function update_plugin_version() {
110 $registered_version = get_option('zalomeni_version', '0');
111 if ($registered_version === '0') return;
112
113 if (version_compare($registered_version, self::version, '<')) {
114 if (version_compare($registered_version, '1.3', '<')) {
115 $old_options = get_option('zalomeni_options');
116 if (is_array($old_options)) {
117 update_option('zalomeni_prepositions', $old_options['zalomeni_prepositions']);
118 update_option('zalomeni_prepositions_list', $old_options['zalomeni_prepositions_list']);
119 update_option('zalomeni_conjunctions', $old_options['zalomeni_conjunctions']);
120 update_option('zalomeni_conjunctions_list', $old_options['zalomeni_conjunctions_list']);
121 if (!version_compare($registered_version, '1.1', '<')) {
122 // these options were introduced in version 1.1
123 update_option('zalomeni_abbreviations', $old_options['zalomeni_abbreviations']);
124 update_option('zalomeni_abbreviations_list', $old_options['zalomeni_abbreviations_list']);
125 update_option('zalomeni_space_between_numbers', $old_options['zalomeni_numbers']);
126 }
127 delete_option('zalomeni_options');
128 }
129 }
130
131 self::add_options();
132 update_option('zalomeni_version', self::version);
133 }
134 }
135
136 private static $this_plugin;
137 public function add_settings_to_plugin_actions($links, $file) {
138 if (!self::$this_plugin) {
139 include_once(ABSPATH . 'wp-admin/includes/plugin.php');
140 self::$this_plugin = plugin_basename(__FILE__);
141 }
142 if ($file === self::$this_plugin) {
143 $settings_link = '<a href="options-reading.php#zalomeni_options_desc">' . __('Settings', 'zalomeni') . '</a>';
144 array_unshift( $links, $settings_link ); // before other links
145 }
146 return $links;
147 }
148
149 public function admin_init() {
150 $this->update_plugin_version();
151 add_filter('plugin_action_links', array($this, 'add_settings_to_plugin_actions'), 10, 2);
152
153 register_setting('reading', 'zalomeni_prepositions', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
154 register_setting('reading', 'zalomeni_prepositions_list', array('sanitize_callback' => array(__CLASS__, 'sanitize_text_list')));
155 register_setting('reading', 'zalomeni_conjunctions', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
156 register_setting('reading', 'zalomeni_conjunctions_list', array('sanitize_callback' => array(__CLASS__, 'sanitize_text_list')));
157 register_setting('reading', 'zalomeni_abbreviations', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
158 register_setting('reading', 'zalomeni_abbreviations_list', array('sanitize_callback' => array(__CLASS__, 'sanitize_text_list')));
159 register_setting('reading', 'zalomeni_between_number_and_unit', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
160 register_setting('reading', 'zalomeni_between_number_and_unit_list', array('sanitize_callback' => array(__CLASS__, 'sanitize_text_list')));
161 register_setting('reading', 'zalomeni_space_between_numbers', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
162 register_setting('reading', 'zalomeni_space_after_ordered_number', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
163 register_setting('reading', 'zalomeni_spaces_in_scales', array('sanitize_callback' => array(__CLASS__, 'sanitize_checkbox')));
164 register_setting('reading', 'zalomeni_custom_terms', array('sanitize_callback' => array(__CLASS__, 'sanitize_custom_terms')));
165
166 add_settings_section('zalomeni_section', self::texturize(__('Nevhodná slova a zalomení na konci řádku', 'zalomeni')), array( __CLASS__, 'settings_section_description' ), 'reading');
167
168 add_settings_field('zalomeni_prepositions', __('Předložky', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'prepositions', 'description'=>__('Vkládat pevnou mezeru za následující předložky.', 'zalomeni'), 'toggle_list_read_only'=>true));
169 add_settings_field('zalomeni_prepositions_list', '', array( __CLASS__, 'settings_field_textlist' ), 'reading', 'zalomeni_section', array('option'=>'prepositions', 'description'=>__('(oddělte jednotlivé předložky čárkou)', 'zalomeni')));
170 add_settings_field('zalomeni_conjunctions', __('Spojky', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'conjunctions', 'description'=>__('Vkládat pevnou mezeru za následující spojky.', 'zalomeni'), 'toggle_list_read_only'=>true));
171 add_settings_field('zalomeni_conjunctions_list', '', array( __CLASS__, 'settings_field_textlist' ), 'reading', 'zalomeni_section', array('option'=>'conjunctions', 'description'=>__('(oddělte jednotlivé spojky čárkou)', 'zalomeni')));
172 add_settings_field('zalomeni_abbreviations', __('Zkratky', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'abbreviations', 'description'=>__('Vkládat pevnou mezeru za následující zkratky.', 'zalomeni'), 'toggle_list_read_only'=>true));
173 add_settings_field('zalomeni_abbreviations_list', '', array( __CLASS__, 'settings_field_textlist' ), 'reading', 'zalomeni_section', array('option'=>'abbreviations', 'description'=>__('(oddělte jednotlivé zkratky čárkou)', 'zalomeni')));
174 add_settings_field('zalomeni_between_number_and_unit', __('Jednotky a míry', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'between_number_and_unit', 'description'=>__('Vkládat pevnou mezeru mezi číslovku a jednotku míry (měrné jednotky, měna apod., např. <em>5 m</em> nebo <em>10 kg</em>).', 'zalomeni'), 'toggle_list_read_only'=>true));
175 add_settings_field('zalomeni_between_number_and_unit_list', '', array( __CLASS__, 'settings_field_textlist' ), 'reading', 'zalomeni_section', array('option'=>'between_number_and_unit', 'description'=>__('(oddělte jednotlivé míry čárkou)', 'zalomeni')));
176 add_settings_field('zalomeni_space_between_numbers', __('Mezery uprostřed čísel', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'space_between_numbers', 'description'=>__('Pokud jsou dvě čísla oddělena mezerou, předpokládat, že se jedná o formátování čísla pomocí mezery (např. telefonní číslo <em>800 123 456</em>) a nahrazovat mezeru pevnou mezerou, aby nedošlo k zalomení řádku uprostřed čísla.', 'zalomeni')));
177 add_settings_field('zalomeni_space_after_ordered_number', __('Řadové číslovky', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'space_after_ordered_number', 'description'=>__('Zabránit zalomení řádku za řadovou číslovkou; díky tomu nedojde k zalomení řádku uprostřed data (např. <em>1. ledna</em>) a v podobných případech (<em>19. ročník</em>, <em>3. svazek</em>, <em>5. kapitola</em> apod.)', 'zalomeni')));
178 add_settings_field('zalomeni_spaces_in_scales', __('Měřítka a poměry', 'zalomeni'), array( __CLASS__, 'settings_field_checkbox' ), 'reading', 'zalomeni_section', array('option'=>'spaces_in_scales', 'description'=>__('Pevné mezery v měřítkách a poměrech (např. <em>1 : 50 000</em>)', 'zalomeni')));
179 add_settings_field('zalomeni_custom_terms', __('Vlastní výrazy', 'zalomeni'), array( __CLASS__, 'settings_field_custom_terms' ), 'reading', 'zalomeni_section');
180
181 if ( empty( get_option('zalomeni_matches') ) ) {
182 self::update_matches_and_replacements();
183 }
184
185 $this->add_update_option_hooks();
186 }
187
188 public static function settings_field_checkbox(array $args) {
189 $option = sanitize_key( $args['option'] );
190 echo(
191 '<input type="checkbox" name="zalomeni_' . esc_attr( $option ) . '" id="zalomeni_' . esc_attr( $option ) . '" value="on" '
192 . checked('on', get_option("zalomeni_" . $option, self::get_default($args['option'])), false)
193 . (array_key_exists('toggle_list_read_only', $args) ? ' onchange="document.getElementById(\'zalomeni_' . esc_js( $option ) . '_list\').readOnly = this.checked?\'\':\'1\';"' : '')
194 . ' /> '
195 . wp_kses_post( self::texturize($args['description']) )
196 );
197 }
198
199 public static function settings_field_textlist(array $args) {
200 $option = sanitize_key( $args['option'] );
201 echo(
202 '<input type="text" name="zalomeni_' . esc_attr( $option ) . '_list" id="zalomeni_' . esc_attr( $option ) . '_list" class="regular-text" value="' . esc_attr( get_option('zalomeni_' . $option . '_list', self::get_default($args['option'] . '_list')) ) . '"'
203 . ((get_option("zalomeni_" . $option, self::get_default($args['option'])) !== 'on') ? ' readonly="1"' : '')
204 . ' /> '
205 . wp_kses_post( self::texturize($args['description']) )
206 );
207 }
208
209 public static function settings_field_custom_terms() {
210 echo(
211 wp_kses_post( self::texturize(__('Zde můžete uvést vlastní termíny, v nichž mají být mezery nahrazeny pevnými mezerami tak, aby nedošlo k zalomení uvnitř těchto výrazů. Uveďte vždy každý výraz na samostatný řádek; pokud je výraz složen z více jak dvou slov, tedy je v něm více jak jedna mezera, pak všechny mezery budou nahrazeny za pevné mezery. Lze použít výrazu \\d pro libovolnou číslici (pro pokročilé administrátory: algoritmus používá <a href="https://www.php.net/manual/en/reference.pcre.pattern.syntax.php" target="_blank">Perl Compatible Regular Expressions</a>, lze využít syntaxe této specifikace).', 'zalomeni')) )
212 . '<p><textarea name="zalomeni_custom_terms" id="zalomeni_custom_terms" rows="10" cols="50" class="regular-text">'
213 . esc_textarea( get_option('zalomeni_custom_terms', self::default_custom_terms) )
214 . '</textarea></p>'
215 );
216 }
217
218 public static function sanitize_checkbox($value) {
219 return $value === 'on' ? 'on' : '';
220 }
221
222 public static function sanitize_text_list($value) {
223 return sanitize_text_field($value);
224 }
225
226 public static function sanitize_custom_terms($value) {
227 return sanitize_textarea_field($value);
228 }
229
230 private function add_update_option_hooks() {
231 foreach (array('update_option_zalomeni_prepositions',
232 'update_option_zalomeni_prepositions_list',
233 'update_option_zalomeni_conjunctions',
234 'update_option_zalomeni_conjunctions_list',
235 'update_option_zalomeni_abbreviations',
236 'update_option_zalomeni_abbreviations_list',
237 'update_option_zalomeni_between_number_and_unit',
238 'update_option_zalomeni_between_number_and_unit_list',
239 'update_option_zalomeni_space_between_numbers',
240 'update_option_zalomeni_space_after_ordered_number',
241 'update_option_zalomeni_spaces_in_scales',
242 'update_option_zalomeni_custom_terms') as $i) {
243 add_action($i, array(__CLASS__, 'update_matches_and_replacements'));
244 }
245 }
246
247 public static function update_matches_and_replacements() {
248 update_option('zalomeni_matches', self::prepare_matches());
249 update_option('zalomeni_replacements', self::prepare_replacements());
250 }
251
252 private static function prepare_matches() {
253 $return_array = array();
254
255 $word_matches = '';
256 foreach (array('prepositions', 'conjunctions', 'abbreviations') as $i) {
257 if (get_option('zalomeni_'.$i, self::get_default($i)) === 'on') {
258 $temp_array = explode(',', get_option('zalomeni_'.$i.'_list', self::get_default($i.'_list')));
259 foreach ($temp_array as $j) {
260 $j = preg_quote(mb_strtolower(trim($j), 'UTF-8'), '@');
261 if ($j === '') continue;
262 $word_matches .= ($word_matches === '' ? '' : '|') . $j;
263 }
264 }
265 }
266 if ($word_matches !== '') {
267 // A semicolon counts as a leading boundary so prepositions glued to an HTML entity
268 // still get a non-breaking space -- typically the Czech opening quote, `&#8222;V lese`.
269 // Apostrophe entities are excluded: wptexturize turns "America's" into
270 // "America&#8217;s", and without this the trailing "s" would be mistaken for a
271 // standalone preposition. Each lookbehind must stay a fixed-length literal (PCRE).
272 $no_apostrophe = '(?<!&#8217;)(?<!&#39;)(?<!&#039;)(?<!&rsquo;)(?<!&apos;)(?<!&#x2019;)(?<!&#x27;)';
273 $return_array['words'] = '@(^|;| |&nbsp;|\(|\n)'.$no_apostrophe.'('.$word_matches.') @i';
274 }
275
276 $word_matches = '';
277 if (get_option('zalomeni_between_number_and_unit', self::default_between_number_and_unit) === 'on') {
278 $temp_array = explode(',', get_option('zalomeni_between_number_and_unit_list', self::default_between_number_and_unit_list));
279 foreach ($temp_array as $j) {
280 $j = preg_quote(mb_strtolower(trim($j), 'UTF-8'), '@');
281 if ($j === '') continue;
282 $word_matches .= ($word_matches === '' ? '' : '|') . $j;
283 }
284 }
285 if ($word_matches !== '') {
286 $return_array['units'] = '@(\d) ('.$word_matches.')(^|[;\.!:]| |&nbsp;|\?|\n|\)|<|\010|\013|$)@i';
287 }
288
289 if (get_option('zalomeni_space_between_numbers', self::default_space_between_numbers) === 'on') {
290 $return_array['numbers'] = '@(\d) (\d)@i';
291 }
292
293 if (get_option('zalomeni_spaces_in_scales', self::default_spaces_in_scales) === 'on') {
294 $return_array['scales'] = '@(\d) : (\d)@i';
295 }
296
297 if (get_option('zalomeni_space_after_ordered_number', self::default_space_after_ordered_number) === 'on') {
298 $return_array['orders'] = '@(\d\.) ([0-9a-záčďéěíňóřšťúýž])@';
299 }
300
301 if (get_option('zalomeni_custom_terms', self::default_custom_terms) !== '') {
302 $term_counter = 1;
303 $custom_terms = explode(chr(10), str_replace(chr(13), '', get_option('zalomeni_custom_terms', self::default_custom_terms)));
304 foreach ($custom_terms as $i) {
305 if (strpos($i, ' ') !== false) {
306 $term = '';
307 $words_split = explode(' ', $i);
308 foreach ($words_split as $j) {
309 $escaped = preg_quote($j, '/');
310 // Restore supported backslash sequences (\d, \w, \s, etc.)
311 $escaped = preg_replace('/\\\\\\\\([dDwWsS])/', '\\\\$1', $escaped);
312 $term .= ($term === '' ? '(' : ' (') . $escaped . ')';
313 }
314 $term = '/' . $term . '/i';
315 $return_array['customterm' . $term_counter++] = $term;
316 }
317 }
318 }
319
320 return $return_array;
321 }
322
323 private static function prepare_replacements() {
324 $return_array = array();
325
326 foreach (array('prepositions', 'conjunctions', 'abbreviations') as $i) {
327 if (get_option('zalomeni_'.$i, self::get_default($i)) === 'on') {
328 $return_array['words'] = '$1$2&nbsp;';
329 break;
330 }
331 }
332
333 if (get_option('zalomeni_between_number_and_unit', self::default_between_number_and_unit) === 'on') {
334 $return_array['units'] = '$1&nbsp;$2$3';
335 }
336
337 if (get_option('zalomeni_space_between_numbers', self::default_space_between_numbers) === 'on') {
338 $return_array['numbers'] = '$1&nbsp;$2';
339 }
340
341 if (get_option('zalomeni_spaces_in_scales', self::default_spaces_in_scales) === 'on') {
342 $return_array['scales'] = '$1&nbsp;:&nbsp;$2';
343 }
344
345 if (get_option('zalomeni_space_after_ordered_number', self::default_space_after_ordered_number) === 'on') {
346 $return_array['orders'] = '$1&nbsp;$2';
347 }
348
349 if (get_option('zalomeni_custom_terms', self::default_custom_terms) !== '') {
350 $term_counter = 1;
351 $custom_terms = explode(chr(10), str_replace(chr(13), '', get_option('zalomeni_custom_terms', self::default_custom_terms)));
352 foreach ($custom_terms as $i) {
353 if (strpos($i, ' ') !== false) {
354 $term = '';
355 $words_split = explode(' ', $i);
356 $word_counter = 1;
357 foreach ($words_split as $j) {
358 $term .= ($term === '' ? '' : '&nbsp;') . '$' . $word_counter++;
359 }
360 $return_array['customterm' . $term_counter++] = $term;
361 }
362 }
363 }
364
365 return $return_array;
366 }
367
368 public static function settings_section_description() {
369 echo(
370 '<div id="zalomeni_options_desc" style="margin:0 0 15px 10px;-webkit-border-radius:3px;border-radius:3px;border-width:1px;border-color:#e6db55;border-style:solid;float:right;background:#FFFBCC;text-align:center;width:200px">'
371 . '<p style="line-height:1.5em;">Plugin <strong>Zalomení</strong><br />' . esc_html__('Maintainer:', 'zalomeni') . ' <a href="https://kybernaut.cz" class="external" target="_blank">Karolína Vyskočilová</a><br /><small>' . esc_html__('Originally by', 'zalomeni') . ' Honza Skýpala</small></p>'
372 . '</div>'
373 . '<p>' . wp_kses_post( self::texturize(__('Upravujeme-li písemný dokument, radí nám <strong>Pravidla českého pravopisu</strong> nepsat neslabičné předložky <em>v, s, z, k</em> na konec řádku, ale psát je na stejný řádek se slovem, které nese přízvuk (např. ve spojení <em>k mostu</em>, <em>s bratrem</em>, <em>v Plzni</em>, <em>z nádraží</em>). Typografické normy jsou ještě přísnější: podle některých je nepatřičné ponechat na konci řádku jakékoli jednopísmenné slovo, tedy také předložky a spojky <em>a, i, o, u</em>;. Někteří pisatelé dokonce nechtějí z estetických důvodů ponechávat na konci řádků jakékoli jednoslabičné výrazy (např. <em>ve, ke, ku, že, na, do, od, pod</em>).', 'zalomeni')) ) . '</p>'
374 . '<p>' . wp_kses_post( self::texturize(__('<a href="https://prirucka.ujc.cas.cz/?id=880" class="external" target="_blank">Více informací</a> na webu Ústavu pro jazyk český, Akademie věd ČR.', 'zalomeni')) ) . '</p>'
375 . '<p>' . wp_kses_post( self::texturize(__('Tento plugin řeší některé z uvedených příkladů: v textu nahrazuje běžné mezery za pevné tak, aby nedošlo k zalomení řádku v nevhodném místě.', 'zalomeni')) ) . '</p>'
376 );
377 }
378
379 private static function pushpop_element($text, &$stack, $disabled_elements, $opening, $closing) {
380 $tag = trim( str_replace( $closing, '', str_replace( $opening, '', $text ) ) );
381 $tag = explode( ' ', $tag )[0];
382 if ( in_array( $tag, $disabled_elements, true ) ) {
383 $stack[] = $tag;
384 } elseif ( strpos( $tag, '/' ) === 0 ) {
385 $tag = ltrim( $tag, '/' );
386 if ( ( $key = array_search( $tag, $stack, true ) ) !== false ) {
387 unset( $stack[ $key ] );
388 $stack = array_values( $stack );
389 }
390 }
391 }
392
393 public static function texturize($text) {
394 $matches = get_option('zalomeni_matches');
395 if (empty($matches)) return $text;
396 $replacements = get_option('zalomeni_replacements');
397
398 $output = '';
399 $curl = '';
400 $textarr = preg_split('/(<.*>|\[.*\])/Us', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
401 $stop = count($textarr);
402
403 $no_texturize_tags = apply_filters('no_texturize_tags', array('pre', 'code', 'kbd', 'style', 'script', 'tt'));
404 $no_texturize_shortcodes = apply_filters('no_texturize_shortcodes', array('code'));
405 $no_texturize_tags_stack = array();
406 $no_texturize_shortcodes_stack = array();
407
408 for ($i = 0; $i < $stop; $i++) {
409 $curl = $textarr[$i];
410
411 if (!empty($curl)) {
412 if ('<' !== $curl[0] && '[' !== $curl[0]
413 && empty($no_texturize_shortcodes_stack) && empty($no_texturize_tags_stack)) {
414 $result = @preg_replace($matches, $replacements, $curl);
415 if ($result !== null) {
416 $result = @preg_replace($matches, $replacements, $result);
417 }
418 $curl = ($result !== null) ? $result : $curl;
419 } else {
420 self::pushpop_element($curl, $no_texturize_tags_stack, $no_texturize_tags, '<', '>');
421 self::pushpop_element($curl, $no_texturize_shortcodes_stack, $no_texturize_shortcodes, '[', ']');
422 }
423 }
424
425 $output .= $curl;
426 }
427
428 return $output;
429 }
430 }
431
432 function zalomeni_init() {
433 static $instance = null;
434 if ( $instance === null ) {
435 $instance = new Zalomeni();
436 }
437 return $instance;
438 }
439 zalomeni_init();