wp/wp-includes/pomo/po.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
    51 		}
    51 		}
    52 
    52 
    53 		/**
    53 		/**
    54 		 * Exports all entries to PO format
    54 		 * Exports all entries to PO format
    55 		 *
    55 		 *
    56 		 * @return string sequence of mgsgid/msgstr PO strings, doesn't containt newline at the end
    56 		 * @return string sequence of msgid/msgstr PO strings, doesn't contain a newline at the end
    57 		 */
    57 		 */
    58 		public function export_entries() {
    58 		public function export_entries() {
    59 			// TODO: Sorting.
    59 			// TODO: Sorting.
    60 			return implode( "\n\n", array_map( array( 'PO', 'export_entry' ), $this->entries ) );
    60 			return implode( "\n\n", array_map( array( 'PO', 'export_entry' ), $this->entries ) );
    61 		}
    61 		}
    62 
    62 
    63 		/**
    63 		/**
    64 		 * Exports the whole PO file as a string
    64 		 * Exports the whole PO file as a string
    65 		 *
    65 		 *
    66 		 * @param bool $include_headers whether to include the headers in the export
    66 		 * @param bool $include_headers whether to include the headers in the export
    67 		 * @return string ready for inclusion in PO file string for headers and all the enrtries
    67 		 * @return string ready for inclusion in PO file string for headers and all the entries
    68 		 */
    68 		 */
    69 		public function export( $include_headers = true ) {
    69 		public function export( $include_headers = true ) {
    70 			$res = '';
    70 			$res = '';
    71 			if ( $include_headers ) {
    71 			if ( $include_headers ) {
    72 				$res .= $this->export_headers();
    72 				$res .= $this->export_headers();
   108 		}
   108 		}
   109 
   109 
   110 		/**
   110 		/**
   111 		 * Formats a string in PO-style
   111 		 * Formats a string in PO-style
   112 		 *
   112 		 *
   113 		 * @param string $string the string to format
   113 		 * @param string $input_string the string to format
   114 		 * @return string the poified string
   114 		 * @return string the poified string
   115 		 */
   115 		 */
   116 		public static function poify( $string ) {
   116 		public static function poify( $input_string ) {
   117 			$quote   = '"';
   117 			$quote   = '"';
   118 			$slash   = '\\';
   118 			$slash   = '\\';
   119 			$newline = "\n";
   119 			$newline = "\n";
   120 
   120 
   121 			$replaces = array(
   121 			$replaces = array(
   122 				"$slash" => "$slash$slash",
   122 				"$slash" => "$slash$slash",
   123 				"$quote" => "$slash$quote",
   123 				"$quote" => "$slash$quote",
   124 				"\t"     => '\t',
   124 				"\t"     => '\t',
   125 			);
   125 			);
   126 
   126 
   127 			$string = str_replace( array_keys( $replaces ), array_values( $replaces ), $string );
   127 			$input_string = str_replace( array_keys( $replaces ), array_values( $replaces ), $input_string );
   128 
   128 
   129 			$po = $quote . implode( "${slash}n$quote$newline$quote", explode( $newline, $string ) ) . $quote;
   129 			$po = $quote . implode( "{$slash}n{$quote}{$newline}{$quote}", explode( $newline, $input_string ) ) . $quote;
   130 			// Add empty string on first line for readbility.
   130 			// Add empty string on first line for readability.
   131 			if ( false !== strpos( $string, $newline ) &&
   131 			if ( str_contains( $input_string, $newline ) &&
   132 				( substr_count( $string, $newline ) > 1 || substr( $string, -strlen( $newline ) ) !== $newline ) ) {
   132 				( substr_count( $input_string, $newline ) > 1 || substr( $input_string, -strlen( $newline ) ) !== $newline ) ) {
   133 				$po = "$quote$quote$newline$po";
   133 				$po = "$quote$quote$newline$po";
   134 			}
   134 			}
   135 			// Remove empty strings.
   135 			// Remove empty strings.
   136 			$po = str_replace( "$newline$quote$quote", '', $po );
   136 			$po = str_replace( "$newline$quote$quote", '', $po );
   137 			return $po;
   137 			return $po;
   138 		}
   138 		}
   139 
   139 
   140 		/**
   140 		/**
   141 		 * Gives back the original string from a PO-formatted string
   141 		 * Gives back the original string from a PO-formatted string
   142 		 *
   142 		 *
   143 		 * @param string $string PO-formatted string
   143 		 * @param string $input_string PO-formatted string
   144 		 * @return string enascaped string
   144 		 * @return string unescaped string
   145 		 */
   145 		 */
   146 		public static function unpoify( $string ) {
   146 		public static function unpoify( $input_string ) {
   147 			$escapes               = array(
   147 			$escapes               = array(
   148 				't'  => "\t",
   148 				't'  => "\t",
   149 				'n'  => "\n",
   149 				'n'  => "\n",
   150 				'r'  => "\r",
   150 				'r'  => "\r",
   151 				'\\' => '\\',
   151 				'\\' => '\\',
   152 			);
   152 			);
   153 			$lines                 = array_map( 'trim', explode( "\n", $string ) );
   153 			$lines                 = array_map( 'trim', explode( "\n", $input_string ) );
   154 			$lines                 = array_map( array( 'PO', 'trim_quotes' ), $lines );
   154 			$lines                 = array_map( array( 'PO', 'trim_quotes' ), $lines );
   155 			$unpoified             = '';
   155 			$unpoified             = '';
   156 			$previous_is_backslash = false;
   156 			$previous_is_backslash = false;
   157 			foreach ( $lines as $line ) {
   157 			foreach ( $lines as $line ) {
   158 				preg_match_all( '/./u', $line, $chars );
   158 				preg_match_all( '/./u', $line, $chars );
   176 
   176 
   177 			return $unpoified;
   177 			return $unpoified;
   178 		}
   178 		}
   179 
   179 
   180 		/**
   180 		/**
   181 		 * Inserts $with in the beginning of every new line of $string and
   181 		 * Inserts $with in the beginning of every new line of $input_string and
   182 		 * returns the modified string
   182 		 * returns the modified string
   183 		 *
   183 		 *
   184 		 * @param string $string prepend lines in this string
   184 		 * @param string $input_string prepend lines in this string
   185 		 * @param string $with prepend lines with this string
   185 		 * @param string $with         prepend lines with this string
   186 		 */
   186 		 */
   187 		public static function prepend_each_line( $string, $with ) {
   187 		public static function prepend_each_line( $input_string, $with ) {
   188 			$lines  = explode( "\n", $string );
   188 			$lines  = explode( "\n", $input_string );
   189 			$append = '';
   189 			$append = '';
   190 			if ( "\n" === substr( $string, -1 ) && '' === end( $lines ) ) {
   190 			if ( "\n" === substr( $input_string, -1 ) && '' === end( $lines ) ) {
   191 				/*
   191 				/*
   192 				 * Last line might be empty because $string was terminated
   192 				 * Last line might be empty because $input_string was terminated
   193 				 * with a newline, remove it from the $lines array,
   193 				 * with a newline, remove it from the $lines array,
   194 				 * we'll restore state by re-terminating the string at the end.
   194 				 * we'll restore state by re-terminating the string at the end.
   195 				 */
   195 				 */
   196 				array_pop( $lines );
   196 				array_pop( $lines );
   197 				$append = "\n";
   197 				$append = "\n";
   340 			// Where were we in the last step.
   340 			// Where were we in the last step.
   341 			// Can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural.
   341 			// Can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural.
   342 			$context      = '';
   342 			$context      = '';
   343 			$msgstr_index = 0;
   343 			$msgstr_index = 0;
   344 			while ( true ) {
   344 			while ( true ) {
   345 				$lineno++;
   345 				++$lineno;
   346 				$line = PO::read_line( $f );
   346 				$line = PO::read_line( $f );
   347 				if ( ! $line ) {
   347 				if ( ! $line ) {
   348 					if ( feof( $f ) ) {
   348 					if ( feof( $f ) ) {
   349 						if ( self::is_final( $context ) ) {
   349 						if ( self::is_final( $context ) ) {
   350 							break;
   350 							break;
   363 				$line = trim( $line );
   363 				$line = trim( $line );
   364 				if ( preg_match( '/^#/', $line, $m ) ) {
   364 				if ( preg_match( '/^#/', $line, $m ) ) {
   365 					// The comment is the start of a new entry.
   365 					// The comment is the start of a new entry.
   366 					if ( self::is_final( $context ) ) {
   366 					if ( self::is_final( $context ) ) {
   367 						PO::read_line( $f, 'put-back' );
   367 						PO::read_line( $f, 'put-back' );
   368 						$lineno--;
   368 						--$lineno;
   369 						break;
   369 						break;
   370 					}
   370 					}
   371 					// Comments have to be at the beginning.
   371 					// Comments have to be at the beginning.
   372 					if ( $context && 'comment' !== $context ) {
   372 					if ( $context && 'comment' !== $context ) {
   373 						return false;
   373 						return false;
   375 					// Add comment.
   375 					// Add comment.
   376 					$this->add_comment_to_entry( $entry, $line );
   376 					$this->add_comment_to_entry( $entry, $line );
   377 				} elseif ( preg_match( '/^msgctxt\s+(".*")/', $line, $m ) ) {
   377 				} elseif ( preg_match( '/^msgctxt\s+(".*")/', $line, $m ) ) {
   378 					if ( self::is_final( $context ) ) {
   378 					if ( self::is_final( $context ) ) {
   379 						PO::read_line( $f, 'put-back' );
   379 						PO::read_line( $f, 'put-back' );
   380 						$lineno--;
   380 						--$lineno;
   381 						break;
   381 						break;
   382 					}
   382 					}
   383 					if ( $context && 'comment' !== $context ) {
   383 					if ( $context && 'comment' !== $context ) {
   384 						return false;
   384 						return false;
   385 					}
   385 					}
   386 					$context         = 'msgctxt';
   386 					$context         = 'msgctxt';
   387 					$entry->context .= PO::unpoify( $m[1] );
   387 					$entry->context .= PO::unpoify( $m[1] );
   388 				} elseif ( preg_match( '/^msgid\s+(".*")/', $line, $m ) ) {
   388 				} elseif ( preg_match( '/^msgid\s+(".*")/', $line, $m ) ) {
   389 					if ( self::is_final( $context ) ) {
   389 					if ( self::is_final( $context ) ) {
   390 						PO::read_line( $f, 'put-back' );
   390 						PO::read_line( $f, 'put-back' );
   391 						$lineno--;
   391 						--$lineno;
   392 						break;
   392 						break;
   393 					}
   393 					}
   394 					if ( $context && 'msgctxt' !== $context && 'comment' !== $context ) {
   394 					if ( $context && 'msgctxt' !== $context && 'comment' !== $context ) {
   395 						return false;
   395 						return false;
   396 					}
   396 					}
   503 		/**
   503 		/**
   504 		 * @param string $s
   504 		 * @param string $s
   505 		 * @return string
   505 		 * @return string
   506 		 */
   506 		 */
   507 		public static function trim_quotes( $s ) {
   507 		public static function trim_quotes( $s ) {
   508 			if ( '"' === substr( $s, 0, 1 ) ) {
   508 			if ( str_starts_with( $s, '"' ) ) {
   509 				$s = substr( $s, 1 );
   509 				$s = substr( $s, 1 );
   510 			}
   510 			}
   511 			if ( '"' === substr( $s, -1, 1 ) ) {
   511 			if ( str_ends_with( $s, '"' ) ) {
   512 				$s = substr( $s, 0, -1 );
   512 				$s = substr( $s, 0, -1 );
   513 			}
   513 			}
   514 			return $s;
   514 			return $s;
   515 		}
   515 		}
   516 	}
   516 	}