Skip to content

Commit

Permalink
Merge pull request #873 from yast/rtl-pathnames
Browse files Browse the repository at this point in the history
Display pathnames correctly in a Right-to-Left context (bsc#1128091)
  • Loading branch information
mvidner committed May 12, 2021
2 parents 6595d26 + 4015fbd commit 825398b
Show file tree
Hide file tree
Showing 14 changed files with 323 additions and 14 deletions.
7 changes: 6 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
require "yast/rake"

Yast::Tasks.configuration do |conf|
conf.skip_license_check << /.*/
conf.skip_license_check << /\.pdf$/ # binary
conf.skip_license_check << /\.desktop$/
conf.skip_license_check << /\.scr$/
# conf file template, you don't want licenses in your config files
conf.skip_license_check << /\/fillup\//

conf.documentation_minimal = 91
end
7 changes: 7 additions & 0 deletions package/yast2-storage-ng.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Thu May 6 08:00:23 UTC 2021 - Martin Vidner <mvidner@suse.com>

- Display pathnames correctly in a Right-to-Left context
(bsc#1128091).
- 4.4.1

-------------------------------------------------------------------
Tue Apr 20 13:51:55 UTC 2021 - Ladislav Slezák <lslezak@suse.cz>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-storage-ng.spec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#

Name: yast2-storage-ng
Version: 4.4.0
Version: 4.4.1
Release: 0
Summary: YaST2 - Storage Configuration
License: GPL-2.0-only OR GPL-3.0-only
Expand Down
19 changes: 18 additions & 1 deletion src/bin/mask-systemd-units
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
#!/bin/bash

# Copyright (c) [2018-2020] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

# This script can mask or unmask systemd mount and swap units since systemd
# and YaST mounting the same file system leads to race conditions (see bsc
Expand Down
157 changes: 157 additions & 0 deletions src/lib/bidi_markup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Copyright (c) [2020-2021] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

# Bidirectional Text: Left-to-right (Latin) and right-to-left (Arabic).
#
# See https://en.wikipedia.org/wiki/Bidirectional_text
#
# If you feel lost, try wrapping a piece of text that belongs together with
# {.first_strong_isolate First Strong Isolate}.
#
# Quoting from the standard, Unicode TR 9, Section 6.3 Formatting,
# where UPPER CASE simulates a RTL script:
#
# > The most common problematic case is that of neutrals on the
# > boundary of an embedded language. This can be addressed by
# > setting the level of the embedded text correctly. For example,
# > with all the text at level 0 the following occurs:
# >
# > Memory: he said "I NEED WATER!", and expired.
# > Display: he said "RETAW DEEN I!", and expired.
# >
# > If the exclamation mark is to be part of the Arabic quotation,
# > then the user can select the text I NEED WATER! and explicitly
# > mark it as embedded Arabic, which produces the following result:
# >
# > Memory: he said "(RLI)I NEED WATER!(PDI)", and expired.
# > Display: he said "!RETAW DEEN I", and expired.
module BidiMarkup
LRE = "\u{202A}".freeze
RLE = "\u{202B}".freeze
PDF = "\u{202C}".freeze
LRO = "\u{202D}".freeze
RLO = "\u{202E}".freeze
LRI = "\u{2066}".freeze
RLI = "\u{2067}".freeze
FSI = "\u{2068}".freeze
PDI = "\u{2069}".freeze

LEFT_TO_RIGHT_EMBEDDING = LRE
RIGHT_TO_LEFT_EMBEDDING = RLE
POP_DIRECTIONAL_FORMATTING = PDF
LEFT_TO_RIGHT_OVERRIDE = LRO
RIGHT_TO_LEFT_OVERRIDE = RLO
LEFT_TO_RIGHT_ISOLATE = LRI
RIGHT_TO_LEFT_ISOLATE = RLI
FIRST_STRONG_ISOLATE = FSI
POP_DIRECTIONAL_ISOLATE = PDI

module_function

# Wrap *str* in a pair of characters: Left-to-Right Embedding.
#
# @deprecated Use {.ltr_isolate}.
# Embedding is an older method that may have side effect on
# the *surrounding* text so since Unicode 6.3 (2013) it is discouraged
# in favor of Isolates.
def ltr_embed(str)
LRE + str + PDF
end

# Wrap *str* in a pair of characters: Right-to-Left Embedding.
#
# @deprecated Use {.rtl_isolate}.
# Embedding is an older method that may have side effect on
# the *surrounding* text so since Unicode 6.3 (2013) it is discouraged
# in favor of Isolates.
def rtl_embed(str)
RLE + str + PDF
end

# Wrap *str* in a pair of characters: Left-to-Right Override.
#
# Force text direction regardless of the characters it contains.
# "Can be used to force a part number made of mixed English, digits
# and Hebrew letters to be written from right to left."
def ltr_override(str)
LRO + str + PDF
end

# Wrap *str* in a pair of characters: Right-to-Left Override.
#
# Force text direction regardless of the characters it contains.
# "Can be used to force a part number made of mixed English, digits
# and Hebrew letters to be written from right to left."
def rtl_override(str)
RLO + str + PDF
end

# Wrap *str* in a pair of characters: Left-to-Right Isolate.
def ltr_isolate(str)
LRI + str + PDI
end

# Wrap *str* in a pair of characters: Right-to-Left Isolate.
def rtl_isolate(str)
RLI + str + PDI
end

# Wrap *str* in a pair of characters: First Strong Isolate.
#
# This is like LTR Isolate or RTL Isolate but the direction is decided by
# the first character that is directionally strong (usually a letter, not
# punctuation).
def first_strong_isolate(str)
FSI + str + PDI
end

BIDI_CONTROLS = LRE + RLE + PDF + LRO + RLO + LRI + RLI + FSI + PDI

LRM = "\u{200E}".freeze
RLM = "\u{200F}".freeze
ALM = "\u{061C}".freeze

LEFT_TO_RIGHT_MARK = LRM
RIGHT_TO_LEFT_MARK = RLM
ARABIC_LETTER_MARK = ALM

# Add bidi formatting characters to *pname*
# otherwise /dev/sda will be presented as dev/sda/ in RTL context
# @param pname [Pathname]
def pathname_bidi_to_s(pname)
return ltr_isolate(File::SEPARATOR) if pname.root?

isolated_components = pname.each_filename.map { |fn| first_strong_isolate(fn) }

isolated_components.unshift("") if pname.absolute?
joined = isolated_components.join(File::SEPARATOR) # "/" pedantry

ltr_isolate(joined)
end

# Return a copy of *str* where bidirectional formatting chars are removed.
#
# LRM, RLM, ALM are kept because they are not added by the methods
# of this module, a human has probably added them instead.
# @param str [String]
# @return [String]
def bidi_strip(str)
str.tr(BIDI_CONTROLS, "")
end
end
18 changes: 18 additions & 0 deletions src/lib/y2partitioner/widgets/columns/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

require "yast"
require "abstract_method"
require "bidi_markup"
require "y2partitioner/device_graphs"

module Y2Partitioner
Expand Down Expand Up @@ -111,6 +112,23 @@ def id

private

def left_to_right(path_string)
return path_string unless bidi_supported?

pn = Pathname.new(path_string)
BidiMarkup.pathname_bidi_to_s(pn)
end

# In ncurses the bidi characters would mess up columns,
# making things worse; return false there.
def bidi_supported?
return @bidi_supported unless @bidi_supported.nil?

di = Yast::UI.GetDisplayInfo() || {}
text_mode = di.fetch("TextMode", true)
@bidi_supported = !text_mode
end

# Helper method to create a `cell` term
#
# @param args [Array] content of the cell
Expand Down
7 changes: 4 additions & 3 deletions src/lib/y2partitioner/widgets/columns/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ def value_for(device, entry: nil)

# The device name
#
# @param entry [DeviceTableEntry]
# @return [String]
def device_name(device, entry)
return fstab_device_name(device, entry) if fstab_entry?(device)
return device.path if device.is?(:btrfs_subvolume)
return blk_device_name(device, entry) unless device.is?(:blk_filesystem)
return left_to_right(fstab_device_name(device, entry)) if fstab_entry?(device)
return left_to_right(device.path) if device.is?(:btrfs_subvolume)
return left_to_right(blk_device_name(device, entry)) unless device.is?(:blk_filesystem)

device.name
end
Expand Down
4 changes: 2 additions & 2 deletions src/lib/y2partitioner/widgets/columns/mount_point.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ def title

# @see Columns::Base#value_for
def value_for(device)
return device.mount_point if fstab_entry?(device)
return left_to_right(device.mount_point) if fstab_entry?(device)

mount_point = mount_point_for(device)

return "" unless mount_point

path = mount_point.path
path = left_to_right(mount_point.path)
path += " *" unless mount_point.active?

path
Expand Down
19 changes: 19 additions & 0 deletions src/lib/y2partitioner/widgets/tabs.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# Copyright (c) [2017-2020] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "yast"
require "cwm/tabs"
require "y2partitioner/ui_state"
Expand Down
19 changes: 19 additions & 0 deletions src/lib/y2partitioner/yard_links.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# Copyright (c) [2017] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

# The documentatin tool YARD has no mechanism
# for linking to separately generated YARD documentation.
# So we use this file to help YARD.
Expand Down
29 changes: 29 additions & 0 deletions test/data/devicegraphs/bidi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
- disk:
name: /dev/sda
size: 1 TiB
file_system: ext4
label: root
mount_point: "/"

- disk:
name: /dev/sdb
size: 1 GiB
partition_table: msdos
partitions:

- partition:
size: 500 MiB
name: /dev/sdb1
file_system: ext4
# /fidiu/qdima (/video/old)
mount_point: "/\u0641\u064A\u062F\u064A\u0648/\u0642\u062F\u064A\u0645\u0629"

- partition:
size: 500 MiB
name: /dev/sdb2
file_system: ext4
# /fidiu/jdida (/video/new)
mount_point: "/\u0641\u064A\u062F\u064A\u0648/\u062C\u062F\u064A\u062F\u0629"


3 changes: 2 additions & 1 deletion test/y2partitioner/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# find current contact information at www.suse.com

require_relative "../spec_helper"
require "bidi_markup"

# Removes the :sortKey term from a :cell term, possibly returning only
# the single param of the term.
Expand All @@ -31,7 +32,7 @@ def remove_sort_key(term)
term.params.delete_if { |param| param.is_a?(Yast::Term) && param.value == :sortKey }
return term if term.params.size > 1

term.params[0]
BidiMarkup.bidi_strip(term.params[0])
end

# Removes the :sortKey term from :cell terms somewhere inside (to the
Expand Down
9 changes: 9 additions & 0 deletions test/y2partitioner/widgets/columns/device_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@
it "uses the sort key provided by libstorage-ng" do
expect(sort_key).to eq(device.name_sort_key)
end

it "wraps the value with bidi control characters" do
allow(subject).to receive(:bidi_supported?).and_return(true)

expect(subject.value_for(device)).to satisfy do |term|
term.value == :cell &&
term.params[0] == "\u2066/\u2068dev\u2069/\u2068sdb1\u2069\u2069"
end
end
end

shared_examples "filesystem" do
Expand Down
Loading

0 comments on commit 825398b

Please sign in to comment.